blob: 32f7e62fe49c7ed5b82b2f081e1c3d98c7fddaac [file] [log] [blame]
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is MPEG4IP.
*
* The Initial Developer of the Original Code is Cisco Systems Inc.
* Portions created by Cisco Systems Inc. are
* Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved.
*
* See ETSI TS 102 366 V1.2.1 Annex F for how to put Ac3 in MP4.
*
* Contributor(s):
* Edward Groenendaal egroenen@cisco.com
*/
#include "src/impl.h"
namespace mp4v2 {
namespace impl {
///////////////////////////////////////////////////////////////////////////////
MP4DAc3Atom::MP4DAc3Atom(MP4File &file)
: MP4Atom(file, "dac3")
{
AddProperty( new MP4BitfieldProperty(*this, "fscod", 2)); /* 0 */
AddProperty( new MP4BitfieldProperty(*this, "bsid", 5)); /* 1 */
AddProperty( new MP4BitfieldProperty(*this, "bsmod", 3)); /* 2 */
AddProperty( new MP4BitfieldProperty(*this, "acmod", 3)); /* 3 */
AddProperty( new MP4BitfieldProperty(*this, "lfeon", 1)); /* 4 */
AddProperty( new MP4BitfieldProperty(*this, "bit_rate_code", 5)); /* 5 */
AddProperty( new MP4BitfieldProperty(*this, "reserved", 5)); /* 6 */
m_pProperties[6]->SetReadOnly(true);
}
void MP4DAc3Atom::Generate()
{
MP4Atom::Generate();
}
/*
* Normalling the Dump of the atom looks like the following, we want to spruce
* this up a bit to give more information.
*
* type = dac3
* fscod = 0 (0x0) <2 bits>
* bsid = 8 (0x08) <5 bits>
* bsmod = 0 (0x0) <3 bits>
* acmod = 7 (0x7) <3 bits>
* lfeon = 1 (0x1) <1 bits>
* bit_rate_code = 15 (0x0f) <5 bits>
* reserved = 0 (0x00) <5 bits>
*
* into:
* type = dac3
* fscod = 0 (0x0) <2 bits> [48 kHz]
* bsid = 8 (0x08) <5 bits>
* bsmod = 0 (0x0) <3 bits> [Main audio service: complete main (CM)]
* acmod = 7 (0x7) <3 bits> [3/2 (L, C, R, SL, SR)]
* lfeon = 1 (0x1) <1 bits> [ENABLED]
* bit_rate_code = 15 (0x0f) <5 bits> [448 kbit/s]
* reserved = 0 (0x00) <5 bits>
*
*/
void MP4DAc3Atom::Dump(uint8_t indent, bool dumpImplicits)
{
MP4BitfieldProperty* fscodProp = ((MP4BitfieldProperty*)m_pProperties[0]);
MP4BitfieldProperty* bsidProp = ((MP4BitfieldProperty*)m_pProperties[1]);
MP4BitfieldProperty* bsmodProp = ((MP4BitfieldProperty*)m_pProperties[2]);
MP4BitfieldProperty* acmodProp = ((MP4BitfieldProperty*)m_pProperties[3]);
MP4BitfieldProperty* lfeonProp = ((MP4BitfieldProperty*)m_pProperties[4]);
MP4BitfieldProperty* brcProp = ((MP4BitfieldProperty*)m_pProperties[5]);
MP4BitfieldProperty* resProp = ((MP4BitfieldProperty*)m_pProperties[6]);
log.dump(indent++, MP4_LOG_VERBOSE2, "\"%s\": type = dac3",
GetFile().GetFilename().c_str() );
if (fscodProp) {
uint64_t fscod = 0xFF;
const char* fscodString;
const char* fscods[] = {
"48", "44.1", "32", "Reserved",
};
fscod = fscodProp->GetValue();
if (fscod < (sizeof(fscods) / sizeof(fscods[0]))) {
fscodString = fscods[fscod];
} else {
fscodString = "Invalid value";
}
uint8_t hexWidth = fscodProp->GetNumBits() / 4;
if (hexWidth == 0 || (fscodProp->GetNumBits() % 4)) {
hexWidth++;
}
log.dump(indent, MP4_LOG_VERBOSE2, "\"%s\": fscod = %" PRIu64 " (0x%0*" PRIx64 ") <%u bits> [%s kHz]",
GetFile().GetFilename().c_str(),
fscod, (int)hexWidth, fscod, fscodProp->GetNumBits(), fscodString);
}
if (bsidProp) bsidProp->Dump(indent, dumpImplicits);
if (bsmodProp) {
uint64_t bsmod = 0xFF;
const char* bsmodString;
const char* bsmods[] = {
"Main audio service: complete main (CM)",
"Main audio srrvice: music and effects (ME)",
"Associated service: visually impaired (VI)",
"Associated service: hearing impaired (HI)",
"Associated service: dialogue (D)",
"Associated service: commentary (C)",
"Associated service: emergency (E)",
"Associated service: voice over (VO) or Main audio service: karaoke",
};
bsmod = bsmodProp->GetValue();
if (bsmod < (sizeof(bsmods) / sizeof(bsmods[0]))) {
bsmodString = bsmods[bsmod];
} else {
bsmodString = "Invalid value";
}
uint8_t hexWidth = bsmodProp->GetNumBits() / 4;
if (hexWidth == 0 || (bsmodProp->GetNumBits() % 4)) {
hexWidth++;
}
log.dump(indent, MP4_LOG_VERBOSE2,
"\"%s\": bsmod = %" PRIu64 " (0x%0*" PRIx64 ") <%u bits> [%s]",
GetFile().GetFilename().c_str(),
bsmod, (int)hexWidth, bsmod, bsmodProp->GetNumBits(), bsmodString);
}
if (acmodProp) {
uint64_t acmod = 0xFF;
const char* acmodString;
const char* acmods[] = {
"1 + 1 (Ch1, Ch2)",
"1/0 (C)",
"2/0 (L, R)",
"3/0 (L, C, R)",
"2/1 (L, R, S)",
"3/1 (L, C, R, S)",
"2/2 (L, R, SL, SR)",
"3/2 (L, C, R, SL, SR)",
};
acmod = acmodProp->GetValue();
if (acmod < (sizeof(acmods) / sizeof(acmods[0]))) {
acmodString = acmods[acmod];
} else {
acmodString = "Invalid value";
}
uint8_t hexWidth = acmodProp->GetNumBits() / 4;
if (hexWidth == 0 || (acmodProp->GetNumBits() % 4)) {
hexWidth++;
}
log.dump(indent, MP4_LOG_VERBOSE2,
"\"%s\": acmod = %" PRIu64 " (0x%0*" PRIx64 ") <%u bits> [%s]",
GetFile().GetFilename().c_str(),
acmod, (int)hexWidth, acmod, acmodProp->GetNumBits(), acmodString);
}
if (lfeonProp) {
uint64_t lfeon = lfeonProp->GetValue();
uint8_t hexWidth = lfeonProp->GetNumBits() / 4;
if (hexWidth == 0 || (lfeonProp->GetNumBits() % 4)) {
hexWidth++;
}
log.dump(indent, MP4_LOG_VERBOSE2,
"\"%s\": lfeon = %" PRIu64 " (0x%0*" PRIx64 ") <%u bits> [%s]",
GetFile().GetFilename().c_str(), lfeon, (int)hexWidth, lfeon,
lfeonProp->GetNumBits(), lfeon ? "ENABLED" : "DISABLED");
}
if (brcProp) {
uint32_t bit_rate_codes[] = {
32,
40,
48,
56,
64,
80,
96,
112,
128,
160,
192,
224,
256,
320,
384,
448,
512,
576,
640,
};
uint64_t bit_rate_code = brcProp->GetValue();
uint32_t bit_rate;
if (bit_rate_code < (sizeof(bit_rate_codes) / sizeof(bit_rate_codes[0]))) {
bit_rate = bit_rate_codes[bit_rate_code];
} else {
bit_rate = 0;
}
uint8_t hexWidth = brcProp->GetNumBits() / 4;
if (hexWidth == 0 || (brcProp->GetNumBits() % 4)) {
hexWidth++;
}
log.dump(indent, MP4_LOG_VERBOSE2,
"\"%s\": bit_rate_code = %" PRIu64 " (0x%0*" PRIx64 ") <%u bits> [%" PRIu32 " kbit/s]",
GetFile().GetFilename().c_str(),
bit_rate_code, (int)hexWidth, bit_rate_code,
brcProp->GetNumBits(), bit_rate);
}
if (resProp) resProp->Dump(indent, dumpImplicits);
}
///////////////////////////////////////////////////////////////////////////////
}
} // namespace mp4v2::impl