void xtr_fullraw_c::create_file(xtr_base_c *master, KaxTrackEntry &track) { xtr_base_c::create_file(master, track); KaxCodecPrivate *priv = FindChild<KaxCodecPrivate>(&track); if (priv && (0 != priv->GetSize())) { memory_cptr mem(new memory_c(priv->GetBuffer(), priv->GetSize(), false)); m_content_decoder.reverse(mem, CONTENT_ENCODING_SCOPE_CODECPRIVATE); m_out->write(mem); } }
// xiph-qt expects these this sound extension to have been created in this way // from the packets which are stored in the CodecPrivate element in Matroska ComponentResult DescExt_XiphFLAC(KaxTrackEntry *tr_entry, Handle *cookie, DescExtDirection dir) { if (!tr_entry || !cookie) return paramErr; if (dir == kToSampleDescription) { Handle sndDescExt; UInt32 uid = 0; KaxCodecPrivate *codecPrivate = FindChild<KaxCodecPrivate>(*tr_entry); if (codecPrivate == NULL) return invalidAtomErr; KaxTrackUID *trackUID = FindChild<KaxTrackUID>(*tr_entry); if (trackUID != NULL) uid = uint32(*trackUID); size_t privateSize = codecPrivate->GetSize(); UInt8 *privateBuf = (unsigned char *) codecPrivate->GetBuffer(), *privateEnd = privateBuf + privateSize; unsigned long serialnoatom[3] = { EndianU32_NtoB(sizeof(serialnoatom)), EndianU32_NtoB(kCookieTypeOggSerialNo), EndianU32_NtoB(uid) }; PtrToHand(serialnoatom, (Handle*)&sndDescExt, sizeof(serialnoatom)); privateBuf += 4; // skip 'fLaC' while ((privateEnd - privateBuf) > 4) { uint32_t packetHeader = EndianU32_BtoN(*(uint32_t*)privateBuf); int lastPacket = packetHeader >> 31, blockType = (packetHeader >> 24) & 0x7F; uint32_t packetSize = (packetHeader & 0xFFFFFF) + 4; uint32_t xiphHeader[2] = {EndianU32_NtoB(packetSize + sizeof(xiphHeader)), EndianU32_NtoB(blockType ? kCookieTypeFLACMetadata : kCookieTypeFLACStreaminfo)}; if ((privateEnd - privateBuf) < packetSize) break; PtrAndHand(xiphHeader, sndDescExt, sizeof(xiphHeader)); PtrAndHand(privateBuf, sndDescExt, packetSize); privateBuf += packetSize; if (lastPacket) break; } *cookie = sndDescExt; }
ComponentResult DescExt_H264(KaxTrackEntry *tr_entry, SampleDescriptionHandle desc, DescExtDirection dir) { if (!tr_entry || !desc) return paramErr; ImageDescriptionHandle imgDesc = (ImageDescriptionHandle) desc; if (dir == kToSampleDescription) { KaxCodecPrivate *codecPrivate = FindChild<KaxCodecPrivate>(*tr_entry); if (codecPrivate == NULL) { // technically invalid file, assume that the h.264 is in VfW format (no pts, etc). (*desc)->dataFormat = 'H264'; return noErr; } Handle imgDescExt; PtrToHand(codecPrivate->GetBuffer(), &imgDescExt, codecPrivate->GetSize()); AddImageDescriptionExtension(imgDesc, imgDescExt, 'avcC'); DisposeHandle(imgDescExt); } return noErr; }
// xiph-qt expects these this sound extension to have been created from first 3 packets // which are stored in CodecPrivate in Matroska ComponentResult DescExt_XiphVorbis(KaxTrackEntry *tr_entry, Handle *cookie, DescExtDirection dir) { if (!tr_entry || !cookie) return paramErr; if (dir == kToSampleDescription) { Handle sndDescExt; unsigned char *privateBuf; size_t privateSize; uint8_t numPackets; int offset = 1, i; UInt32 uid = 0; KaxCodecPrivate *codecPrivate = FindChild<KaxCodecPrivate>(*tr_entry); if (codecPrivate == NULL) return invalidAtomErr; KaxTrackUID *trackUID = FindChild<KaxTrackUID>(*tr_entry); if (trackUID != NULL) uid = uint32(*trackUID); privateSize = codecPrivate->GetSize(); privateBuf = (unsigned char *) codecPrivate->GetBuffer(); numPackets = privateBuf[0] + 1; int packetSizes[numPackets]; memset(packetSizes, 0, sizeof(packetSizes)); // get the sizes of the packets packetSizes[numPackets - 1] = privateSize - 1; int packetNum = 0; for (i = 1; packetNum < numPackets - 1; i++) { packetSizes[packetNum] += privateBuf[i]; if (privateBuf[i] < 255) { packetSizes[numPackets - 1] -= packetSizes[packetNum]; packetNum++; } offset++; } packetSizes[numPackets - 1] -= offset - 1; if (offset+packetSizes[0]+packetSizes[1]+packetSizes[2] > privateSize) { return invalidAtomErr; } // first packet uint32_t serial_header_atoms[3+2] = { EndianU32_NtoB(3*4), EndianU32_NtoB(kCookieTypeOggSerialNo), EndianU32_NtoB(uid), EndianU32_NtoB(packetSizes[0] + 2*4), EndianU32_NtoB(kCookieTypeVorbisHeader) }; PtrToHand(serial_header_atoms, &sndDescExt, sizeof(serial_header_atoms)); PtrAndHand(&privateBuf[offset], sndDescExt, packetSizes[0]); // second packet uint32_t atomhead2[2] = { EndianU32_NtoB(packetSizes[1] + sizeof(atomhead2)), EndianU32_NtoB(kCookieTypeVorbisComments) }; PtrAndHand(atomhead2, sndDescExt, sizeof(atomhead2)); PtrAndHand(&privateBuf[offset + packetSizes[0]], sndDescExt, packetSizes[1]); // third packet uint32_t atomhead3[2] = { EndianU32_NtoB(packetSizes[2] + sizeof(atomhead3)), EndianU32_NtoB(kCookieTypeVorbisCodebooks) }; PtrAndHand(atomhead3, sndDescExt, sizeof(atomhead3)); PtrAndHand(&privateBuf[offset + packetSizes[1] + packetSizes[0]], sndDescExt, packetSizes[2]); *cookie = sndDescExt; } return noErr; }