mirror of https://git.ffmpeg.org/ffmpeg.git
Allow the combined TrueHD/AC3 tracks on Blu-Ray discs to be demuxed as two separate streams.
Patch by Ian Caulfield, ian D caulfield A gmail Originally committed as revision 20168 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
55c0e1e6d2
commit
63380b5e54
|
@ -148,11 +148,13 @@ struct PESContext {
|
|||
MpegTSContext *ts;
|
||||
AVFormatContext *stream;
|
||||
AVStream *st;
|
||||
AVStream *sub_st; /**< stream for the embedded AC3 stream in HDMV TrueHD */
|
||||
enum MpegTSState state;
|
||||
/* used to get the format */
|
||||
int data_index;
|
||||
int total_size;
|
||||
int pes_header_size;
|
||||
int extended_stream_id;
|
||||
int64_t pts, dts;
|
||||
int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */
|
||||
uint8_t header[MAX_PES_HEADER_SIZE];
|
||||
|
@ -509,6 +511,7 @@ static const StreamType HDMV_types[] = {
|
|||
{ 0x80, CODEC_TYPE_AUDIO, CODEC_ID_PCM_BLURAY },
|
||||
{ 0x81, CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
|
||||
{ 0x82, CODEC_TYPE_AUDIO, CODEC_ID_DTS },
|
||||
{ 0x83, CODEC_TYPE_AUDIO, CODEC_ID_TRUEHD },
|
||||
{ 0x90, CODEC_TYPE_SUBTITLE, CODEC_ID_HDMV_PGS_SUBTITLE },
|
||||
{ 0 },
|
||||
};
|
||||
|
@ -568,8 +571,32 @@ static AVStream *new_pes_av_stream(PESContext *pes, uint32_t prog_reg_desc, uint
|
|||
|
||||
mpegts_find_stream_type(st, pes->stream_type, ISO_types);
|
||||
if (prog_reg_desc == AV_RL32("HDMV") &&
|
||||
st->codec->codec_id == CODEC_ID_NONE)
|
||||
st->codec->codec_id == CODEC_ID_NONE) {
|
||||
mpegts_find_stream_type(st, pes->stream_type, HDMV_types);
|
||||
if (pes->stream_type == 0x83) {
|
||||
// HDMV TrueHD streams also contain an AC3 coded version of the
|
||||
// audio track - add a second stream for this
|
||||
AVStream *sub_st;
|
||||
// priv_data cannot be shared between streams
|
||||
PESContext *sub_pes = av_malloc(sizeof(*sub_pes));
|
||||
if (!sub_pes)
|
||||
return NULL;
|
||||
memcpy(sub_pes, pes, sizeof(*sub_pes));
|
||||
|
||||
sub_st = av_new_stream(pes->stream, pes->pid);
|
||||
if (!sub_st) {
|
||||
av_free(sub_pes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
av_set_pts_info(sub_st, 33, 1, 90000);
|
||||
sub_st->priv_data = sub_pes;
|
||||
sub_st->codec->codec_type = CODEC_TYPE_AUDIO;
|
||||
sub_st->codec->codec_id = CODEC_ID_AC3;
|
||||
sub_st->need_parsing = AVSTREAM_PARSE_FULL;
|
||||
sub_pes->sub_st = pes->sub_st = sub_st;
|
||||
}
|
||||
}
|
||||
if (st->codec->codec_id == CODEC_ID_NONE)
|
||||
mpegts_find_stream_type(st, pes->stream_type, MISC_types);
|
||||
|
||||
|
@ -730,6 +757,11 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
|
|||
break;
|
||||
}
|
||||
p = desc_end;
|
||||
|
||||
if (prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) {
|
||||
av_program_add_stream_index(ts->stream, h->id, pes->sub_st->index);
|
||||
pes->sub_st->codec->codec_tag = st->codec->codec_tag;
|
||||
}
|
||||
}
|
||||
p = desc_list_end;
|
||||
}
|
||||
|
@ -873,7 +905,11 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
|
|||
pkt->size = pes->data_index;
|
||||
memset(pkt->data+pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
pkt->stream_index = pes->st->index;
|
||||
// Separate out the AC3 substream from an HDMV combined TrueHD/AC3 PID
|
||||
if (pes->sub_st && pes->stream_type == 0x83 && pes->extended_stream_id == 0x76)
|
||||
pkt->stream_index = pes->sub_st->index;
|
||||
else
|
||||
pkt->stream_index = pes->st->index;
|
||||
pkt->pts = pes->pts;
|
||||
pkt->dts = pes->dts;
|
||||
/* store position of first TS packet of this PES packet */
|
||||
|
@ -1005,7 +1041,7 @@ static int mpegts_push_data(MpegTSFilter *filter,
|
|||
buf_size -= len;
|
||||
if (pes->data_index == pes->pes_header_size) {
|
||||
const uint8_t *r;
|
||||
unsigned int flags;
|
||||
unsigned int flags, pes_ext, skip;
|
||||
|
||||
flags = pes->header[7];
|
||||
r = pes->header + 9;
|
||||
|
@ -1020,6 +1056,20 @@ static int mpegts_push_data(MpegTSFilter *filter,
|
|||
pes->dts = get_pts(r);
|
||||
r += 5;
|
||||
}
|
||||
pes->extended_stream_id = -1;
|
||||
if (flags & 0x01) { /* PES extension */
|
||||
pes_ext = *r++;
|
||||
/* Skip PES private data, program packet sequence counter and P-STD buffer */
|
||||
skip = (pes_ext >> 4) & 0xb;
|
||||
skip += skip & 0x9;
|
||||
r += skip;
|
||||
if ((pes_ext & 0x41) == 0x01 &&
|
||||
(r + 2) <= (pes->header + pes->pes_header_size)) {
|
||||
/* PES extension 2 */
|
||||
if ((r[0] & 0x7f) > 0 && (r[1] & 0x80) == 0)
|
||||
pes->extended_stream_id = r[1];
|
||||
}
|
||||
}
|
||||
|
||||
/* we got the full header. We parse it and get the payload */
|
||||
pes->state = MPEGTS_PAYLOAD;
|
||||
|
|
Loading…
Reference in New Issue