diff options
author | James Almer <jamrial@gmail.com> | 2020-02-18 12:49:15 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2020-02-22 23:19:07 -0300 |
commit | dbd02443ae08126a498ddfaf9e7f044471e1ac1c (patch) | |
tree | 0c940a767971287e42c1e42e41bac4e5be8bac18 /libavformat/dashenc.c | |
parent | 7098989e708396c542a5d10176e96c56e8b704b6 (diff) | |
download | ffmpeg-dbd02443ae08126a498ddfaf9e7f044471e1ac1c.tar.gz |
avformat/dashenc: write a capture time Producer Reference Time element when none is provided by the encoder
This way, the element will be present in any scenario when the write_prft option is used.
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavformat/dashenc.c')
-rw-r--r-- | libavformat/dashenc.c | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 5c1d24d3e2..ee5ab701ef 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -128,7 +128,7 @@ typedef struct OutputStream { char full_path[1024]; char temp_path[1024]; double availability_time_offset; - int64_t producer_reference_time; + AVProducerReferenceTime producer_reference_time; char producer_reference_time_str[100]; int total_pkt_size; int64_t total_pkt_duration; @@ -864,8 +864,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 +2002,32 @@ 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]; + AVProducerReferenceTime *prft; + int side_data_size; + + prft = (AVProducerReferenceTime *)av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, &side_data_size); + if (!prft || side_data_size != sizeof(AVProducerReferenceTime) || (prft->flags && prft->flags != 24)) { + // No encoder generated or user provided capture time AVProducerReferenceTime side data. Instead + // of letting the mov muxer generate one, 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; + } + if (os->first_pts == AV_NOPTS_VALUE) { + os->producer_reference_time = *prft; + 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; @@ -2033,15 +2059,13 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) pkt->dts = 0; } + if (c->write_prft) { + ret = dash_parse_prft(c, pkt); + if (ret < 0) + return ret; + } + 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; } os->last_pts = pkt->pts; @@ -2118,10 +2142,10 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) } } - if (c->write_prft && os->producer_reference_time && !os->producer_reference_time_str[0]) + if (c->write_prft && os->producer_reference_time.wallclock && !os->producer_reference_time_str[0]) format_date(os->producer_reference_time_str, sizeof(os->producer_reference_time_str), - os->producer_reference_time); + os->producer_reference_time.wallclock); if ((ret = dash_flush(s, 0, pkt->stream_index)) < 0) return ret; |