| /* |
| * 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 |