void EbmlComposer::WriteSimpleBlock(EncodedFrame* aFrame) { EbmlGlobal ebml; ebml.offset = 0; if (aFrame->GetFrameType() == EncodedFrame::FrameType::VP8_I_FRAME) { FinishCluster(); } auto block = mClusterBuffs.AppendElement(); block->SetLength(aFrame->GetFrameData().Length() + DEFAULT_HEADER_SIZE); ebml.buf = block->Elements(); if (aFrame->GetFrameType() == EncodedFrame::FrameType::VP8_I_FRAME) { EbmlLoc ebmlLoc; Ebml_StartSubElement(&ebml, &ebmlLoc, Cluster); MOZ_ASSERT(mClusterBuffs.Length() > 0); // current cluster header array index mClusterHeaderIndex = mClusterBuffs.Length() - 1; mClusterLengthLoc = ebmlLoc.offset; mClusterTimecode = aFrame->GetTimeStamp() / PR_USEC_PER_MSEC; Ebml_SerializeUnsigned(&ebml, Timecode, mClusterTimecode); mFlushState |= FLUSH_CLUSTER; } if (aFrame->GetFrameType() != EncodedFrame::FrameType::VORBIS_AUDIO_FRAME) { short timeCode = aFrame->GetTimeStamp() / PR_USEC_PER_MSEC - mClusterTimecode; writeSimpleBlock(&ebml, 0x1, timeCode, aFrame->GetFrameType() == EncodedFrame::FrameType::VP8_I_FRAME, 0, 0, (unsigned char*)aFrame->GetFrameData().Elements(), aFrame->GetFrameData().Length()); } else { writeSimpleBlock(&ebml, 0x2, 0, false, 0, 0, (unsigned char*)aFrame->GetFrameData().Elements(), aFrame->GetFrameData().Length()); } MOZ_ASSERT(ebml.offset <= DEFAULT_HEADER_SIZE + aFrame->GetFrameData().Length(), "write more data > EBML_BUFFER_SIZE"); block->SetLength(ebml.offset); }
int main(int argc, char *argv[]) { // init the datatype we're using for ebml output unsigned char data[8192]; EbmlGlobal ebml; ebml.buf = data; ebml.offset = 0; ebml.length = 8192; writeHeader(&ebml); { EbmlLoc startSegment; Ebml_StartSubElement(&ebml, &startSegment, Segment); // segment { // segment info EbmlLoc startInfo; Ebml_StartSubElement(&ebml, &startInfo, Info); Ebml_SerializeString(&ebml, 0x4D80, "muxingAppLibMkv"); Ebml_SerializeString(&ebml, 0x5741, "writingAppLibMkv"); Ebml_EndSubElement(&ebml, &startInfo); } { EbmlLoc trackStart; Ebml_StartSubElement(&ebml, &trackStart, Tracks); writeVideoTrack(&ebml, 1, 1, "V_MS/VFW/FOURCC", 320, 240, 29.97); // writeAudioTrack(&ebml,2,1, "A_VORBIS", 32000, 1, NULL, 0); Ebml_EndSubElement(&ebml, &trackStart); } { EbmlLoc clusterStart; Ebml_StartSubElement(&ebml, &clusterStart, Cluster); // cluster Ebml_SerializeUnsigned(&ebml, Timecode, 0); unsigned char someData[4] = {1, 2, 3, 4}; writeSimpleBlock(&ebml, 1, 0, 1, 0, 0, someData, 4); Ebml_EndSubElement(&ebml, &clusterStart); } // end cluster Ebml_EndSubElement(&ebml, &startSegment); } // dump ebml stuff to the file FILE *file_out = fopen("test.mkv", "wb"); size_t bytesWritten = fwrite(data, 1, ebml.offset, file_out); fclose(file_out); return 0; }