Skip to content

Commit

Permalink
Matroska capture misc fixes
Browse files Browse the repository at this point in the history
wrong size of a void element, timestamp rounding issues, cues missing CRC
  • Loading branch information
JeromeMartinez committed Dec 6, 2023
1 parent d59c7dc commit 2cfe084
Showing 1 changed file with 20 additions and 21 deletions.
41 changes: 20 additions & 21 deletions Source/Common/Output_Mkv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

using namespace std;

static const unsigned char matroska_writer_header[] = { 0x1A, 0x45, 0xDF, 0xA3, 0xA3, 0x42, 0x86, 0x81, 0x01, 0x42, 0xF7, 0x81, 0x01, 0x42, 0xF2, 0x81, 0x04, 0x42, 0xF3, 0x81, 0x08, 0x42, 0x82, 0x88, 0x6D, 0x61, 0x74, 0x72, 0x6F, 0x73, 0x6B, 0x61, 0x42, 0x87, 0x81, 0x04, 0x42, 0x85, 0x81, 0x02, 0x18, 0x53, 0x80, 0x67, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x11, 0x4D, 0x9B, 0x74, 0xC6, 0xEC, 0x84, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xBB, 0x8B, 0x53, 0xAB, 0x84, 0x15, 0x49, 0xA9, 0x66, 0x53, 0xAC, 0x81, 0xA1, 0x4D, 0xBB, 0x8B, 0x53, 0xAB, 0x84, 0x16, 0x54, 0xAE, 0x6B, 0x53, 0xAC, 0x81, 0xF3, 0xEC, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49, 0xA9, 0x66, 0xCD, 0xEC, 0x84, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xD7, 0xB1, 0x83, 0x0F, 0x42, 0x40, 0x4D, 0x80, 0x8E, 0x44, 0x56, 0x52, 0x65, 0x73, 0x63, 0x75, 0x65, 0x20, 0x30, 0x30, 0x2E, 0x30, 0x30, 0x57, 0x41, 0x8E, 0x44, 0x56, 0x52, 0x65, 0x73, 0x63, 0x75, 0x65, 0x20, 0x30, 0x30, 0x2E, 0x30, 0x30, 0xEC, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x54, 0xAE, 0x6B, 0x41, 0x14, 0xEC, 0x84, 0x00, 0x00, 0x00, 0x00, 0xAE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0xD7, 0x81, 0x01, 0x73, 0xC5, 0x81, 0x01, 0xEC, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x81, 0x00, 0x22, 0xB5, 0x9C, 0x83, 0x75, 0x6E, 0x64, 0x83, 0x81, 0x01, 0x23, 0xE3, 0x83, 0x84, 0x01, 0xFD, 0x22, 0x8A, 0x86, 0x8F, 0x56, 0x5F, 0x4D, 0x53, 0x2F, 0x56, 0x46, 0x57, 0x2F, 0x46, 0x4F, 0x55, 0x52, 0x43, 0x43, 0xE0, 0xA6, 0xB0, 0x82, 0x00, 0x00, 0xBA, 0x82, 0x00, 0x00, 0x9A, 0x81, 0x01, 0x9D, 0x81, 0x06, 0x54, 0xB0, 0x81, 0x04, 0x54, 0xBA, 0x81, 0x03, 0x54, 0xB2, 0x81, 0x03, 0xEC, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0xA2, 0xA8, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x76, 0x32, 0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xD7, 0x81, 0x02, 0x73, 0xC5, 0x81, 0x02, 0xEC, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x81, 0x00, 0x22, 0xB5, 0x9C, 0x83, 0x75, 0x6E, 0x64, 0x86, 0x8D, 0x41, 0x5F, 0x50, 0x43, 0x4D, 0x2F, 0x49, 0x4E, 0x54, 0x2F, 0x4C, 0x49, 0x54, 0x83, 0x81, 0x02, 0xE1, 0x91, 0x9F, 0x81, 0x02, 0xB5, 0x88, 0x40, 0xE7, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x64, 0x81, 0x20, 0xEC, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static const unsigned char matroska_writer_header[] = { 0x1A, 0x45, 0xDF, 0xA3, 0xA3, 0x42, 0x86, 0x81, 0x01, 0x42, 0xF7, 0x81, 0x01, 0x42, 0xF2, 0x81, 0x04, 0x42, 0xF3, 0x81, 0x08, 0x42, 0x82, 0x88, 0x6D, 0x61, 0x74, 0x72, 0x6F, 0x73, 0x6B, 0x61, 0x42, 0x87, 0x81, 0x04, 0x42, 0x85, 0x81, 0x02, 0x18, 0x53, 0x80, 0x67, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x11, 0x4D, 0x9B, 0x74, 0xC6, 0xEC, 0x84, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xBB, 0x8B, 0x53, 0xAB, 0x84, 0x15, 0x49, 0xA9, 0x66, 0x53, 0xAC, 0x81, 0xA1, 0x4D, 0xBB, 0x8B, 0x53, 0xAB, 0x84, 0x16, 0x54, 0xAE, 0x6B, 0x53, 0xAC, 0x81, 0xF3, 0xEC, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49, 0xA9, 0x66, 0xCD, 0xEC, 0x84, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xD7, 0xB1, 0x83, 0x0F, 0x42, 0x40, 0x4D, 0x80, 0x8E, 0x44, 0x56, 0x52, 0x65, 0x73, 0x63, 0x75, 0x65, 0x20, 0x30, 0x30, 0x2E, 0x30, 0x30, 0x57, 0x41, 0x8E, 0x44, 0x56, 0x52, 0x65, 0x73, 0x63, 0x75, 0x65, 0x20, 0x30, 0x30, 0x2E, 0x30, 0x30, 0xEC, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x54, 0xAE, 0x6B, 0x41, 0x14, 0xEC, 0x84, 0x00, 0x00, 0x00, 0x00, 0xAE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0xD7, 0x81, 0x01, 0x73, 0xC5, 0x81, 0x01, 0xEC, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x81, 0x00, 0x22, 0xB5, 0x9C, 0x83, 0x75, 0x6E, 0x64, 0x83, 0x81, 0x01, 0x23, 0xE3, 0x83, 0x84, 0x01, 0xFD, 0x22, 0x8A, 0x86, 0x8F, 0x56, 0x5F, 0x4D, 0x53, 0x2F, 0x56, 0x46, 0x57, 0x2F, 0x46, 0x4F, 0x55, 0x52, 0x43, 0x43, 0xE0, 0xA6, 0xB0, 0x82, 0x00, 0x00, 0xBA, 0x82, 0x00, 0x00, 0x9A, 0x81, 0x01, 0x9D, 0x81, 0x06, 0x54, 0xB0, 0x81, 0x04, 0x54, 0xBA, 0x81, 0x03, 0x54, 0xB2, 0x81, 0x03, 0xEC, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0xA2, 0xA8, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x76, 0x32, 0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xD7, 0x81, 0x02, 0x73, 0xC5, 0x81, 0x02, 0xEC, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x81, 0x00, 0x22, 0xB5, 0x9C, 0x83, 0x75, 0x6E, 0x64, 0x86, 0x8D, 0x41, 0x5F, 0x50, 0x43, 0x4D, 0x2F, 0x49, 0x4E, 0x54, 0x2F, 0x4C, 0x49, 0x54, 0x83, 0x81, 0x02, 0xE1, 0x91, 0x9F, 0x81, 0x02, 0xB5, 0x88, 0x40, 0xE7, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x64, 0x81, 0x20, 0xEC, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static const unsigned char matroska_writer_header_seek[] = { 0x4D, 0xBB, 0x92, 0x53, 0xAB, 0x84, 0x1C, 0x53, 0xBB, 0x6B, 0x53, 0xAC, 0x88 };
static const unsigned char matroska_writer_header_timecode[] = { 0x41, 0xE4, 0x8A, 0x41, 0xE7, 0x83, 0x31, 0x32, 0x31, 0x41, 0xF0, 0x81, 0x79 };
static const unsigned char matroska_writer_header_texttrack[] = { 0xAE, 0xA1, 0xD7, 0x81, 0x03, 0x73, 0xC5, 0x81, 0x03, 0xEC, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x81, 0x11, 0x86, 0x8B, 0x53, 0x5F, 0x54, 0x45, 0x58, 0x54, 0x2F, 0x55, 0x54, 0x46, 0x38, 0x9C, 0x81, 0x00 };
Expand Down Expand Up @@ -290,7 +290,7 @@ void matroska_writer::write_header()
void matroska_writer::write_frame(const char* video_buffer, int video_size, const char* audio_buffer, int audio_size, timecode_struct timecode)
{
// Cues
double timecode_ms = (double)frame_number * 1000 * framerate_den / framerate_num + 0.5;
auto timecode_ms = (frame_number * 1000 * framerate_den + framerate_num / 2 - 1) / framerate_num;
auto timecode_s = timecode_ms / 1000;
if (timecode_s >= cues.size())
cues.push_back({ (unsigned long long)timecode_ms, output_size });
Expand Down Expand Up @@ -346,6 +346,8 @@ void matroska_writer::write_frame(const char* video_buffer, int video_size, cons
store_b2(cur, 0x75A1); // BlockMore
store_b8(cur, 0x8FA68DEE8179A588LL); // BlockMore size + BlockAddID + BlockAdditional
store_b8(cur, timecode_value);
if (!has_timecode)
has_timecode=true; // timecode track header will be written when header is written again with cues
}

// Audio
Expand Down Expand Up @@ -387,15 +389,21 @@ void matroska_writer::write_frame(const char* video_buffer, int video_size, cons

void matroska_writer::close(std::ofstream* output)
{
char buffer[sizeof(matroska_writer_header)];
char* cur;
auto cues_size = 6 + 27 * cues.size();
if (buffer_size < cues_size)
{
buffer_size = cues_size;
delete[] buffer;
buffer = new char[buffer_size];
}
auto cur = buffer;

// Cues
int cues_size = 6 + 27 * (int)cues.size();
cur = buffer;
// Header
store_b4(cur, 0x1C53BB6B); // Cues
store_e4(cur, cues_size);
cur += 6; // CRC-32

// Cues
for (const auto& cue : cues)
{
store_b4(cur, 0xBB99B388); // CuePoint + CueTime
Expand All @@ -404,22 +412,13 @@ void matroska_writer::close(std::ofstream* output)
store_b1(cur, 1);
store_b2(cur, 0xF188); // CueClusterPosition
store_b8(cur, cue.offset);
auto size = cur - buffer;
if (sizeof(matroska_writer_header) - size < 27)
{
output->write(buffer, size);
output_size += size;
cur = buffer;
}
}
if (cur > buffer)
{
auto size = cur - buffer;
matroska_crc32_store(buffer + 8, cues_size);
output->write(buffer, size);
output_size += size;
}

auto size = cur - buffer;
matroska_crc32_store(buffer + 8, cues_size);
output->write(buffer, size);
output_size += size;

output->seekp(0);
if (output)
write_header();
Expand Down

0 comments on commit 2cfe084

Please sign in to comment.