mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-23 19:31:44 +00:00
Pad MPEG packets up to 2048 bytes for VobSub extraction because some programs depend on it. Patch by Mike Matsnev <mike () po !cs ! msu ! su>
This commit is contained in:
parent
596d11ae2f
commit
0a3f88b6d7
@ -1,3 +1,9 @@
|
||||
2005-05-17 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvextract: bug fix: The MPEG packets are now padded to 2048
|
||||
byte boundaries as some programs require them to be. Patch by
|
||||
Mike Matsnev (see AUTHORS).
|
||||
|
||||
2005-05-07 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvinfo: bug fix: Removed the restriction of max. ten levels of
|
||||
|
@ -124,6 +124,8 @@ xtr_vobsub_c::handle_block(KaxBlock &block,
|
||||
int64_t duration,
|
||||
int64_t bref,
|
||||
int64_t fref) {
|
||||
static unsigned char padding_data[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff};
|
||||
mpeg_es_header_t es;
|
||||
mpeg_ps_header_t ps;
|
||||
uint64_t c;
|
||||
@ -138,7 +140,7 @@ xtr_vobsub_c::handle_block(KaxBlock &block,
|
||||
for (i = 0; i < block.NumberFrames(); i++) {
|
||||
autofree_ptr<unsigned char> af_data;
|
||||
unsigned char *data;
|
||||
uint32_t size;
|
||||
uint32_t size, padding, first;
|
||||
DataBuffer &data_buffer = block.GetBuffer(i);
|
||||
|
||||
size = data_buffer.Size();
|
||||
@ -146,6 +148,15 @@ xtr_vobsub_c::handle_block(KaxBlock &block,
|
||||
if (content_decoder.reverse(data, size, CONTENT_ENCODING_SCOPE_BLOCK))
|
||||
af_data.set(data);
|
||||
|
||||
positions.push_back(vmaster->out->getFilePointer());
|
||||
timecodes.push_back(timecode);
|
||||
|
||||
padding = (2048 - (size + sizeof(mpeg_ps_header_t) +
|
||||
sizeof(mpeg_es_header_t))) & 2047;
|
||||
first = size + sizeof(mpeg_ps_header_t) +
|
||||
sizeof(mpeg_es_header_t) > 2048 ?
|
||||
2048 - sizeof(mpeg_ps_header_t) - sizeof(mpeg_es_header_t) : size;
|
||||
|
||||
memset(&ps, 0, sizeof(mpeg_ps_header_t));
|
||||
|
||||
ps.pfx[2] = 0x01;
|
||||
@ -155,25 +166,27 @@ xtr_vobsub_c::handle_block(KaxBlock &block,
|
||||
ps.scr[0] = 0x40 | ((uint8_t)(c >> 27) & 0x38) | 0x04 |
|
||||
((uint8_t)(c >> 28) & 0x03);
|
||||
ps.scr[1] = (uint8_t)(c >> 20);
|
||||
ps.scr[2] = ((uint8_t)(c >> 12) & 0xf8) | 0x40 |
|
||||
((uint8_t)(c >> 13) & 0x07);
|
||||
ps.scr[2] = ((uint8_t)(c >> 12) & 0xf8) | 0x04 |
|
||||
((uint8_t)(c >> 13) & 0x03);
|
||||
ps.scr[3] = (uint8_t)(c >> 5);
|
||||
ps.scr[4] = ((uint8_t)(c << 3) & 0xf8) | 0x40;
|
||||
ps.scr[4] = ((uint8_t)(c << 3) & 0xf8) | 0x04;
|
||||
ps.scr[5] = 1;
|
||||
ps.muxr[0] = 1;
|
||||
ps.muxr[1] = 0x89;
|
||||
ps.muxr[2] = 0xc3; // just some value
|
||||
ps.stlen = 0xf8;
|
||||
if ((padding < 8) && (first == size))
|
||||
ps.stlen |= (uint8_t)padding;
|
||||
|
||||
memset(&es, 0, sizeof(mpeg_es_header_t));
|
||||
es.pfx[2] = 1;
|
||||
es.stream_id = 0xbd;
|
||||
es.len[0] = ((size + 9) >> 8) & 0xff;
|
||||
es.len[1] = (size + 9) & 0xff;
|
||||
es.len[0] = (uint8_t)((first + 9) >> 8);
|
||||
es.len[1] = (uint8_t)(first + 9);
|
||||
es.flags[0] = 0x81;
|
||||
es.flags[1] = 0x80;
|
||||
es.hlen = 5;
|
||||
es.pts[0] = 0x20 | ((uint8_t)(c >> 29) & 0xe0) | 0x01;
|
||||
es.pts[0] = 0x20 | ((uint8_t)(c >> 29) & 0x0e) | 0x01;
|
||||
es.pts[1] = (uint8_t)(c >> 22);
|
||||
es.pts[2] = ((uint8_t)(c >> 14) & 0xfe) | 0x01;
|
||||
es.pts[3] = (uint8_t)(c >> 7);
|
||||
@ -183,11 +196,45 @@ xtr_vobsub_c::handle_block(KaxBlock &block,
|
||||
else
|
||||
es.lidx = stream_id;
|
||||
|
||||
positions.push_back(vmaster->out->getFilePointer());
|
||||
timecodes.push_back(timecode);
|
||||
vmaster->out->write(&ps, sizeof(mpeg_ps_header_t));
|
||||
if ((padding > 0) && (padding < 8) && (first == size))
|
||||
vmaster->out->write(padding_data, padding);
|
||||
vmaster->out->write(&es, sizeof(mpeg_es_header_t));
|
||||
vmaster->out->write(data, size);
|
||||
vmaster->out->write(data, first);
|
||||
while (first < size) {
|
||||
size -= first;
|
||||
data += first;
|
||||
|
||||
padding = (2048 - (size + 10 + sizeof(mpeg_ps_header_t))) & 2047;
|
||||
first = size + 10 + sizeof(mpeg_ps_header_t) > 2048 ?
|
||||
2048 - 10 - sizeof(mpeg_ps_header_t) : size;
|
||||
|
||||
if ((padding < 8) && (first == size))
|
||||
ps.stlen |= (uint8_t)padding;
|
||||
|
||||
es.len[0] = (uint8_t)((first + 4) >> 8);
|
||||
es.len[1] = (uint8_t)(first + 4);
|
||||
es.flags[1] = 0;
|
||||
es.hlen = 0;
|
||||
es.pts[0] = es.lidx;
|
||||
vmaster->out->write(&ps, sizeof(mpeg_ps_header_t));
|
||||
if ((padding > 0) && (padding < 8) && (first == size))
|
||||
vmaster->out->write(padding_data, padding);
|
||||
vmaster->out->write(&es, 10);
|
||||
vmaster->out->write(data, first);
|
||||
}
|
||||
if (8 <= padding) {
|
||||
padding -= 6;
|
||||
es.stream_id = 0xbe;
|
||||
es.len[0] = (uint8_t)(padding >> 8);
|
||||
es.len[1] = (uint8_t)padding;
|
||||
vmaster->out->write(&es, 6); // XXX
|
||||
while (0 < padding) {
|
||||
uint32_t todo = padding > 8 ? 8 : padding;
|
||||
vmaster->out->write(padding_data, todo);
|
||||
padding -= todo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user