Signed-off-by: Martin Storsjö <martin@martin.st>tags/n3.3
| @@ -443,12 +443,13 @@ void ff_format_io_close(AVFormatContext *s, AVIOContext **pb); | |||||
| /** | /** | ||||
| * Find the next packet in the interleaving queue for the given stream. | * Find the next packet in the interleaving queue for the given stream. | ||||
| * The packet is not removed from the interleaving queue, but only | |||||
| * a pointer to it is returned. | |||||
| * The pkt parameter is filled in with the queued packet, including | |||||
| * references to the data (which the caller is not allowed to keep or | |||||
| * modify). | |||||
| * | * | ||||
| * @return a pointer to the next packet, or NULL if no packet is queued | |||||
| * for this stream. | |||||
| * @return 0 if a packet was found, a negative value if no packet was found | |||||
| */ | */ | ||||
| const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream); | |||||
| int ff_interleaved_peek(AVFormatContext *s, int stream, | |||||
| AVPacket *pkt, int add_offset); | |||||
| #endif /* AVFORMAT_INTERNAL_H */ | #endif /* AVFORMAT_INTERNAL_H */ | ||||
| @@ -3262,13 +3262,13 @@ static int mov_flush_fragment(AVFormatContext *s, int force) | |||||
| for (i = 0; i < s->nb_streams; i++) { | for (i = 0; i < s->nb_streams; i++) { | ||||
| MOVTrack *track = &mov->tracks[i]; | MOVTrack *track = &mov->tracks[i]; | ||||
| if (!track->end_reliable) { | if (!track->end_reliable) { | ||||
| const AVPacket *next = ff_interleaved_peek(s, i); | |||||
| if (next) { | |||||
| track->track_duration = next->dts - track->start_dts; | |||||
| if (next->pts != AV_NOPTS_VALUE) | |||||
| track->end_pts = next->pts; | |||||
| AVPacket pkt; | |||||
| if (!ff_interleaved_peek(s, i, &pkt, 1)) { | |||||
| track->track_duration = pkt.dts - track->start_dts; | |||||
| if (pkt.pts != AV_NOPTS_VALUE) | |||||
| track->end_pts = pkt.pts; | |||||
| else | else | ||||
| track->end_pts = next->dts; | |||||
| track->end_pts = pkt.dts; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -357,6 +357,8 @@ FF_ENABLE_DEPRECATION_WARNINGS | |||||
| static int write_packet(AVFormatContext *s, AVPacket *pkt) | static int write_packet(AVFormatContext *s, AVPacket *pkt) | ||||
| { | { | ||||
| int ret; | int ret; | ||||
| // If the timestamp offsetting below is adjusted, adjust | |||||
| // ff_interleaved_peek similarly. | |||||
| if (s->avoid_negative_ts > 0) { | if (s->avoid_negative_ts > 0) { | ||||
| AVRational time_base = s->streams[pkt->stream_index]->time_base; | AVRational time_base = s->streams[pkt->stream_index]->time_base; | ||||
| int64_t offset = 0; | int64_t offset = 0; | ||||
| @@ -614,15 +616,27 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, | |||||
| } | } | ||||
| } | } | ||||
| const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream) | |||||
| int ff_interleaved_peek(AVFormatContext *s, int stream, | |||||
| AVPacket *pkt, int add_offset) | |||||
| { | { | ||||
| AVPacketList *pktl = s->internal->packet_buffer; | AVPacketList *pktl = s->internal->packet_buffer; | ||||
| while (pktl) { | while (pktl) { | ||||
| if (pktl->pkt.stream_index == stream) | |||||
| return &pktl->pkt; | |||||
| if (pktl->pkt.stream_index == stream) { | |||||
| *pkt = pktl->pkt; | |||||
| if (add_offset && s->internal->offset != AV_NOPTS_VALUE) { | |||||
| int64_t offset = av_rescale_q(s->internal->offset, | |||||
| s->internal->offset_timebase, | |||||
| s->streams[stream]->time_base); | |||||
| if (pkt->dts != AV_NOPTS_VALUE) | |||||
| pkt->dts += offset; | |||||
| if (pkt->pts != AV_NOPTS_VALUE) | |||||
| pkt->pts += offset; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| pktl = pktl->next; | pktl = pktl->next; | ||||
| } | } | ||||
| return NULL; | |||||
| return AVERROR(ENOENT); | |||||
| } | } | ||||
| /** | /** | ||||