This way, the element will be present in any scenario when the write_prft option is used.
Signed-off-by: James Almer <jamr...@gmail.com> --- libavformat/dashenc.c | 46 +++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 5c1d24d3e2..b910cc22d0 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -129,6 +129,7 @@ typedef struct OutputStream { char temp_path[1024]; double availability_time_offset; int64_t producer_reference_time; + int producer_reference_time_flags; char producer_reference_time_str[100]; int total_pkt_size; int64_t total_pkt_duration; @@ -864,8 +865,8 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind s->streams[i]->codecpar->channels); } if (!final && c->write_prft && os->producer_reference_time_str[0]) { - avio_printf(out, "\t\t\t\t<ProducerReferenceTime id=\"%d\" inband=\"true\" type=\"encoder\" wallclockTime=\"%s\" presentationTime=\"%"PRId64"\">\n", - i, os->producer_reference_time_str, c->presentation_time_offset); + avio_printf(out, "\t\t\t\t<ProducerReferenceTime id=\"%d\" inband=\"true\" type=\"%s\" wallclockTime=\"%s\" presentationTime=\"%"PRId64"\">\n", + i, os->producer_reference_time_flags ? "captured" : "encoder", os->producer_reference_time_str, c->presentation_time_offset); avio_printf(out, "\t\t\t\t\t<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:http-xsdate:2014\" value=\"%s\"/>\n", c->utc_timing_url); avio_printf(out, "\t\t\t\t</ProducerReferenceTime>\n"); } @@ -2002,6 +2003,35 @@ static int dash_flush(AVFormatContext *s, int final, int stream) return ret; } +static int dash_parse_prft(DASHContext *c, AVPacket *pkt) +{ + OutputStream *os = &c->streams[pkt->stream_index]; + int side_data_size; + AVProducerReferenceTime *prft; + + if (!c->write_prft) + return 0; + + prft = (AVProducerReferenceTime *)av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, &side_data_size); + if (!prft || side_data_size != sizeof(AVProducerReferenceTime) || prft->flags) { + // No encoder generated AVProducerReferenceTime side data. Instead of letting the mov muxer + // generate a capture-time one for the first packet, do it here so we can also use it for the + // manifest. + prft = (AVProducerReferenceTime *)av_packet_new_side_data(pkt, AV_PKT_DATA_PRFT, + sizeof(AVProducerReferenceTime)); + if (!prft) + return AVERROR(ENOMEM); + prft->wallclock = av_gettime(); + prft->flags = 24; + } + os->producer_reference_time = prft->wallclock; + os->producer_reference_time_flags = prft->flags; + if (c->target_latency_refid < 0) + c->target_latency_refid = pkt->stream_index; + + return 0; +} + static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) { DASHContext *c = s->priv_data; @@ -2034,15 +2064,11 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) } if (os->first_pts == AV_NOPTS_VALUE) { - int side_data_size; - AVProducerReferenceTime *prft = (AVProducerReferenceTime *)av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, - &side_data_size); - if (prft && side_data_size == sizeof(AVProducerReferenceTime) && !prft->flags) { - os->producer_reference_time = prft->wallclock; - if (c->target_latency_refid < 0) - c->target_latency_refid = pkt->stream_index; - } os->first_pts = pkt->pts; + + ret = dash_parse_prft(c, pkt); + if (ret > 0) + return ret; } os->last_pts = pkt->pts; -- 2.25.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".