From: Derek Buitenhuis Date: Wed, 18 Nov 2015 16:40:16 +0000 (+0000) Subject: Merge commit 'bef3b1f59f036aba4a5fe599b2480f6bd9e6b280' X-Git-Tag: n3.1-dev~1514 X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff_plain/3e0daf0716888d166329cffa554893846d6ec3be Merge commit 'bef3b1f59f036aba4a5fe599b2480f6bd9e6b280' * commit 'bef3b1f59f036aba4a5fe599b2480f6bd9e6b280': movenc: Allow setting start_dts/start_cts before writing actual packets Merged-by: Derek Buitenhuis --- 3e0daf0716888d166329cffa554893846d6ec3be diff --cc libavformat/movenc.c index 363501b,9f7cca9..372c41f --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@@ -4574,7 -3592,19 +4571,19 @@@ static int mov_write_single_packet(AVFo mov->flags &= ~FF_MOV_FLAG_FRAG_DISCONT; } + if (!pkt->size) { + if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) { + trk->start_dts = pkt->dts; + if (pkt->pts != AV_NOPTS_VALUE) + trk->start_cts = pkt->pts - pkt->dts; + else + trk->start_cts = 0; + } + + return 0; /* Discard 0 sized packets */ + } + - if (trk->entry) + if (trk->entry && pkt->stream_index < s->nb_streams) frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts, s->streams[pkt->stream_index]->time_base, AV_TIME_BASE_Q); @@@ -4596,73 -3626,6 +4605,74 @@@ } return ff_mov_write_packet(s, pkt); +} + +static int mov_write_subtitle_end_packet(AVFormatContext *s, + int stream_index, + int64_t dts) { + AVPacket end; + uint8_t data[2] = {0}; + int ret; + + av_init_packet(&end); + end.size = sizeof(data); + end.data = data; + end.pts = dts; + end.dts = dts; + end.duration = 0; + end.stream_index = stream_index; + + ret = mov_write_single_packet(s, &end); + av_packet_unref(&end); + + return ret; +} + +static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + if (!pkt) { + mov_flush_fragment(s, 1); + return 1; + } else { + int i; + MOVMuxContext *mov = s->priv_data; + - if (!pkt->size) return 0; /* Discard 0 sized packets */ ++ if (!pkt->size) ++ return mov_write_single_packet(s, pkt); /* Passthrough. */ + + /* + * Subtitles require special handling. + * + * 1) For full complaince, every track must have a sample at + * dts == 0, which is rarely true for subtitles. So, as soon + * as we see any packet with dts > 0, write an empty subtitle + * at dts == 0 for any subtitle track with no samples in it. + * + * 2) For each subtitle track, check if the current packet's + * dts is past the duration of the last subtitle sample. If + * so, we now need to write an end sample for that subtitle. + * + * This must be done conditionally to allow for subtitles that + * immediately replace each other, in which case an end sample + * is not needed, and is, in fact, actively harmful. + * + * 3) See mov_write_trailer for how the final end sample is + * handled. + */ + for (i = 0; i < mov->nb_streams; i++) { + MOVTrack *trk = &mov->tracks[i]; + int ret; + + if (trk->enc->codec_id == AV_CODEC_ID_MOV_TEXT && + trk->track_duration < pkt->dts && + (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) { + ret = mov_write_subtitle_end_packet(s, i, trk->track_duration); + if (ret < 0) return ret; + trk->last_sample_is_subtitle_end = 1; + } + } + + return mov_write_single_packet(s, pkt); } }