Second patchset addresses feedback after discussion with Martin. It is now accounting for the fact that avg_frame_rate may not always be set.
On Wed, Nov 18, 2015 at 1:13 AM, Bryan Huh <br...@box.com> wrote: > DASH manifest should have framerate specified as an attribute in the > AdaptationSet element and Representation elements. Though ISO/IEC > 23009-1:2014 doesn't seem to define frameRate as a required attribute, > it is at least optional, and DASH-IF IOP 3.0 seems to require it. See > section 3.2.4 of http://dashif.org/w/2015/04/DASH-IF-IOP-v3.0.pdf > > In the event that avg_frame_rate is not set in the muxer, we ignore the > frameRate tag altogther. > --- > libavformat/dashenc.c | 31 +++++++++++++++++++++++++++---- > 1 files changed, 27 insertions(+), 4 deletions(-) > > diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c > index 7a93214..9c2b4dd 100644 > --- a/libavformat/dashenc.c > +++ b/libavformat/dashenc.c > @@ -24,10 +24,12 @@ > #include <unistd.h> > #endif > > +#include "libavutil/avassert.h" > #include "libavutil/avstring.h" > #include "libavutil/intreadwrite.h" > #include "libavutil/mathematics.h" > #include "libavutil/opt.h" > +#include "libavutil/rational.h" > #include "libavutil/time_internal.h" > > #include "avc.h" > @@ -94,6 +96,8 @@ typedef struct DASHContext { > const char *single_file_name; > const char *init_seg_name; > const char *media_seg_name; > + AVRational min_frame_rate, max_frame_rate; > + int ambiguous_frame_rate; > } DASHContext; > > static int dash_write(void *opaque, uint8_t *buf, int buf_size) > @@ -503,7 +507,11 @@ static int write_manifest(AVFormatContext *s, int > final) > } > > if (c->has_video) { > - avio_printf(out, "\t\t<AdaptationSet contentType=\"video\" > segmentAlignment=\"true\" bitstreamSwitching=\"true\">\n"); > + avio_printf(out, "\t\t<AdaptationSet contentType=\"video\" > segmentAlignment=\"true\" bitstreamSwitching=\"true\""); > + if (c->max_frame_rate.num && !c->ambiguous_frame_rate) > + avio_printf(out, " %s=\"%d/%d\"", > (av_cmp_q(c->min_frame_rate, c->max_frame_rate) < 0) ? "maxFrameRate" : > "frameRate", c->max_frame_rate.num, c->max_frame_rate.den); > + avio_printf(out, ">\n"); > + > for (i = 0; i < s->nb_streams; i++) { > AVStream *st = s->streams[i]; > OutputStream *os = &c->streams[i]; > @@ -511,7 +519,11 @@ static int write_manifest(AVFormatContext *s, int > final) > if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO) > continue; > > - avio_printf(out, "\t\t\t<Representation id=\"%d\" > mimeType=\"video/mp4\" codecs=\"%s\"%s width=\"%d\" height=\"%d\">\n", i, > os->codec_str, os->bandwidth_str, st->codec->width, st->codec->height); > + avio_printf(out, "\t\t\t<Representation id=\"%d\" > mimeType=\"video/mp4\" codecs=\"%s\"%s width=\"%d\" height=\"%d\"", i, > os->codec_str, os->bandwidth_str, st->codec->width, st->codec->height); > + if (st->avg_frame_rate.num) > + avio_printf(out, " frameRate=\"%d/%d\"", > st->avg_frame_rate.num, st->avg_frame_rate.den); > + avio_printf(out, ">\n"); > + > output_segment_list(&c->streams[i], out, c); > avio_printf(out, "\t\t\t</Representation>\n"); > } > @@ -552,6 +564,7 @@ static int dash_write_header(AVFormatContext *s) > c->single_file = 1; > if (c->single_file) > c->use_template = 0; > + c->ambiguous_frame_rate = 0; > > av_strlcpy(c->dirname, s->filename, sizeof(c->dirname)); > ptr = strrchr(c->dirname, '/'); > @@ -655,10 +668,20 @@ static int dash_write_header(AVFormatContext *s) > // already before being handed to this muxer, so we don't have > mismatches > // between the MPD and the actual segments. > s->avoid_negative_ts = ctx->avoid_negative_ts; > - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) > + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { > + AVRational avg_frame_rate = s->streams[i]->avg_frame_rate; > + if (avg_frame_rate.num > 0) { > + if (av_cmp_q(avg_frame_rate, c->min_frame_rate) < 0) > + c->min_frame_rate = avg_frame_rate; > + if (av_cmp_q(c->max_frame_rate, avg_frame_rate) < 0) > + c->max_frame_rate = avg_frame_rate; > + } else { > + c->ambiguous_frame_rate = 1; > + } > c->has_video = 1; > - else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) > + } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { > c->has_audio = 1; > + } > > set_codec_str(s, st->codec, os->codec_str, sizeof(os->codec_str)); > os->first_pts = AV_NOPTS_VALUE; > -- > 1.7.1 > > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel