X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmpegtsenc.c;h=51677eaaf4336ea5b06998b3cd57b3839ddb0d71;hb=38a6242b271fad4917a1c6201ff61e10160c965b;hp=765672067a3c43f9e2665aa3f3cf0d027d9f5f7a;hpb=4e3185d208666f151e442ba0e9509f1e97ad865e;p=ffmpeg diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 765672067a3..51677eaaf43 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -56,6 +56,7 @@ typedef struct MpegTSService { int pcr_pid; int pcr_packet_count; int pcr_packet_period; + AVProgram *program; } MpegTSService; // service_type values as defined in ETSI 300 468 @@ -275,15 +276,12 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); if (s->nb_programs) { - int j, k, found = 0; - - for (j = 0; j < s->nb_programs; j++) - if (s->programs[j]->id == service->sid) { - for (k = 0; k < s->programs[j]->nb_stream_indexes; k++) - if (s->programs[j]->stream_index[k] == i) { - found = 1; - break; - } + int k, found = 0; + AVProgram *program = service->program; + + for (k = 0; k < program->nb_stream_indexes; k++) + if (program->stream_index[k] == i) { + found = 1; break; } @@ -784,6 +782,7 @@ static int mpegts_init(AVFormatContext *s) service->pmt.write_packet = section_write_packet; service->pmt.opaque = s; service->pmt.cc = 15; + service->program = program; } } @@ -807,6 +806,7 @@ static int mpegts_init(AVFormatContext *s) /* assign pids to each stream */ for (i = 0; i < s->nb_streams; i++) { + AVProgram *program; st = s->streams[i]; ts_st = av_mallocz(sizeof(MpegTSWriteStream)); @@ -824,6 +824,17 @@ static int mpegts_init(AVFormatContext *s) ret = AVERROR(ENOMEM); goto fail; } + + program = av_find_program_from_stream(s, NULL, i); + if (program) { + for (j = 0; j < ts->nb_services; j++) { + if (ts->services[j]->program == program) { + service = ts->services[j]; + break; + } + } + } + ts_st->service = service; /* MPEG pid values < 16 are reserved. Applications which set st->id in * this range are assigned a calculated pid. */ @@ -1111,7 +1122,7 @@ static uint8_t *get_ts_payload_start(uint8_t *pkt) * NOTE: 'payload' contains a complete PES payload. */ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, const uint8_t *payload, int payload_size, - int64_t pts, int64_t dts, int key) + int64_t pts, int64_t dts, int key, int stream_id) { MpegTSWriteStream *ts_st = st->priv_data; MpegTSWrite *ts = s->priv_data; @@ -1208,6 +1219,11 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, st->codec->codec_id == AV_CODEC_ID_AC3 && ts->m2ts_mode) { *q++ = 0xfd; + } else if (st->codec->codec_type == AVMEDIA_TYPE_DATA) { + *q++ = stream_id != -1 ? stream_id : 0xfc; + + if (stream_id == 0xbd) /* asynchronous KLV */ + pts = dts = AV_NOPTS_VALUE; } else { *q++ = 0xbd; if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { @@ -1451,6 +1467,15 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2; int64_t dts = pkt->dts, pts = pkt->pts; int opus_samples = 0; + int side_data_size; + char *side_data = NULL; + int stream_id = -1; + + side_data = av_packet_get_side_data(pkt, + AV_PKT_DATA_MPEGTS_STREAM_ID, + &side_data_size); + if (side_data) + stream_id = side_data[0]; if (ts->reemit_pat_pmt) { av_log(s, AV_LOG_WARNING, @@ -1629,8 +1654,8 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) if ( ts_st2->payload_size && (ts_st2->payload_dts == AV_NOPTS_VALUE || dts - ts_st2->payload_dts > delay/2)) { mpegts_write_pes(s, st2, ts_st2->payload, ts_st2->payload_size, - ts_st2->payload_pts, ts_st2->payload_dts, - ts_st2->payload_flags & AV_PKT_FLAG_KEY); + ts_st2->payload_pts, ts_st2->payload_dts, + ts_st2->payload_flags & AV_PKT_FLAG_KEY, stream_id); ts_st2->payload_size = 0; } } @@ -1643,7 +1668,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) ts_st->opus_queued_samples + opus_samples >= 5760 /* 120ms */)) { mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size, ts_st->payload_pts, ts_st->payload_dts, - ts_st->payload_flags & AV_PKT_FLAG_KEY); + ts_st->payload_flags & AV_PKT_FLAG_KEY, stream_id); ts_st->payload_size = 0; ts_st->opus_queued_samples = 0; } @@ -1652,7 +1677,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) av_assert0(!ts_st->payload_size); // for video and subtitle, write a single pes packet mpegts_write_pes(s, st, buf, size, pts, dts, - pkt->flags & AV_PKT_FLAG_KEY); + pkt->flags & AV_PKT_FLAG_KEY, stream_id); ts_st->opus_queued_samples = 0; av_free(data); return 0; @@ -1684,7 +1709,7 @@ static void mpegts_write_flush(AVFormatContext *s) if (ts_st->payload_size > 0) { mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size, ts_st->payload_pts, ts_st->payload_dts, - ts_st->payload_flags & AV_PKT_FLAG_KEY); + ts_st->payload_flags & AV_PKT_FLAG_KEY, -1); ts_st->payload_size = 0; ts_st->opus_queued_samples = 0; }