mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2025-02-26 08:22:31 +00:00
Read the PES extension and get the substream ID from it. This is needed for VC1 video tracks.
This commit is contained in:
parent
4ebd5d60ad
commit
c743eea7fa
@ -231,10 +231,23 @@ mpeg_ps_reader_c::calculate_global_timecode_offset() {
|
||||
bool
|
||||
mpeg_ps_reader_c::read_timestamp(int c,
|
||||
int64_t ×tamp) {
|
||||
int d, e;
|
||||
int d = io->read_uint16_be();
|
||||
int e = io->read_uint16_be();
|
||||
|
||||
d = io->read_uint16_be();
|
||||
e = io->read_uint16_be();
|
||||
if (((c & 1) != 1) || ((d & 1) != 1) || ((e & 1) != 1))
|
||||
return false;
|
||||
|
||||
timestamp = (int64_t)((((c >> 1) & 7) << 30) | ((d >> 1) << 15) | (e >> 1)) * 100000ll / 9;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
mpeg_ps_reader_c::read_timestamp(bit_cursor_c &bc,
|
||||
int64_t ×tamp) {
|
||||
int c = bc.get_bits(8);
|
||||
int d = bc.get_bits(16);
|
||||
int e = bc.get_bits(16);
|
||||
|
||||
if (((c & 1) != 1) || ((d & 1) != 1) || ((e & 1) != 1))
|
||||
return false;
|
||||
@ -368,35 +381,70 @@ mpeg_ps_reader_c::parse_packet(mpeg_ps_id_t &id,
|
||||
if ((c & 0x30) != 0x00)
|
||||
mxerror(FMT_FN "Reading encrypted VOBs is not supported.\n", ti.fname.c_str());
|
||||
|
||||
int pts_flags = io->read_uint8() >> 6;
|
||||
int hdrlen = io->read_uint8();
|
||||
length -= 2;
|
||||
int flags = io->read_uint8();
|
||||
int hdrlen = io->read_uint8();
|
||||
length -= 2;
|
||||
|
||||
if (hdrlen > length)
|
||||
return false;
|
||||
|
||||
if (2 == (pts_flags & 0x02)) {
|
||||
if (hdrlen < 5)
|
||||
return false;
|
||||
c = io->read_uint8();
|
||||
if (!read_timestamp(c, timestamp))
|
||||
return false;
|
||||
length -= 5;
|
||||
hdrlen -= 5;
|
||||
length -= hdrlen;
|
||||
|
||||
memory_c af_header(safemalloc(hdrlen), hdrlen, true);
|
||||
if (io->read(af_header.get(), hdrlen) != hdrlen)
|
||||
return false;
|
||||
|
||||
bit_cursor_c bc(af_header.get(), hdrlen);
|
||||
|
||||
try {
|
||||
if (0x80 == (flags & 0x80)) {
|
||||
// PTS
|
||||
if (!read_timestamp(bc, timestamp))
|
||||
return false;
|
||||
|
||||
// DTS
|
||||
if (0x40 == (flags & 0x40))
|
||||
bc.skip_bits(5 * 8);
|
||||
}
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// DTS
|
||||
if (1 == (pts_flags & 0x01)) {
|
||||
if (hdrlen < 5)
|
||||
return false;
|
||||
io->skip(5);
|
||||
length -= 5;
|
||||
hdrlen -= 5;
|
||||
}
|
||||
try {
|
||||
// PES extension?
|
||||
if (0x01 == (flags & 0x01)) {
|
||||
int pes_ext_flags = bc.get_bits(8);
|
||||
|
||||
if (0 < hdrlen) {
|
||||
length -= hdrlen;
|
||||
io->skip(hdrlen);
|
||||
if (0x80 == (pes_ext_flags & 0x80)) {
|
||||
// PES private data
|
||||
bc.skip_bits(128);
|
||||
}
|
||||
|
||||
if (0x40 == (pes_ext_flags & 0x40)) {
|
||||
// pack header field
|
||||
int pack_header_field_len = bc.get_bits(8);
|
||||
bc.skip_bits(8 * pack_header_field_len);
|
||||
}
|
||||
|
||||
if (0x20 == (pes_ext_flags & 0x20)) {
|
||||
// program packet sequence counter
|
||||
bc.skip_bits(16);
|
||||
}
|
||||
|
||||
if (0x10 == (pes_ext_flags & 0x10)) {
|
||||
// P-STD buffer
|
||||
bc.skip_bits(16);
|
||||
}
|
||||
|
||||
if (0x01 == (pes_ext_flags & 0x01)) {
|
||||
bc.skip_bits(1);
|
||||
int pes_ext2_len = bc.get_bits(7);
|
||||
|
||||
if (0 < pes_ext2_len)
|
||||
id.sub_id = bc.get_bits(8);
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
if (0xbd == id.id) { // DVD audio substream
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "bit_cursor.h"
|
||||
#include "dts_common.h"
|
||||
#include "mpeg4_common.h"
|
||||
#include "pr_generic.h"
|
||||
@ -140,6 +141,7 @@ public:
|
||||
|
||||
virtual void found_new_stream(mpeg_ps_id_t id);
|
||||
|
||||
virtual bool read_timestamp(bit_cursor_c &bc, int64_t ×tamp);
|
||||
virtual bool read_timestamp(int c, int64_t ×tamp);
|
||||
virtual bool parse_packet(mpeg_ps_id_t &id, int64_t ×tamp, int &length, int &full_length);
|
||||
virtual bool find_next_packet(mpeg_ps_id_t &id, int64_t max_file_pos = -1);
|
||||
|
Loading…
Reference in New Issue
Block a user