On 26 September 2012 13:21, Luca Barbato <[email protected]> wrote:
> Split away option settings, sanity checks and general setup.
> ---
>  libavformat/output.c | 122 
> +++++++++++++++++++++++++++++++++------------------
>  1 file changed, 80 insertions(+), 42 deletions(-)
>
> diff --git a/libavformat/output.c b/libavformat/output.c
> index f63cffe..aa8d228 100644
> --- a/libavformat/output.c
> +++ b/libavformat/output.c
> @@ -135,93 +135,109 @@ static int validate_codec_tag(AVFormatContext *s, 
> AVStream *st)
>      return 1;
>  }
>
> -int avformat_write_header(AVFormatContext *s, AVDictionary **options)
> +
> +static int write_setup(AVFormatContext *s, AVDictionary **options)
>  {
>      int ret = 0, i;
>      AVStream *st;
>      AVDictionary *tmp = NULL;
> +    AVCodecContext *ctx = NULL;
> +    AVOutputFormat *of = s->oformat;
>
>      if (options)
>          av_dict_copy(&tmp, *options, 0);
> +
>      if ((ret = av_opt_set_dict(s, &tmp)) < 0)
>          goto fail;
>
>      // some sanity checks
> -    if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) {
> +    if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {
>          av_log(s, AV_LOG_ERROR, "no streams\n");
>          ret = AVERROR(EINVAL);
>          goto fail;
>      }
>
>      for (i = 0; i < s->nb_streams; i++) {
> -        st = s->streams[i];
> +        st  = s->streams[i];
> +        ctx = st->codec;
>
> -        switch (st->codec->codec_type) {
> +        switch (ctx->codec_type) {
>          case AVMEDIA_TYPE_AUDIO:
> -            if (st->codec->sample_rate <= 0) {
> +            if (ctx->sample_rate <= 0) {
>                  av_log(s, AV_LOG_ERROR, "sample rate not set\n");
>                  ret = AVERROR(EINVAL);
>                  goto fail;
>              }
> -            if (!st->codec->block_align)
> -                st->codec->block_align = st->codec->channels *
> -                                         
> av_get_bits_per_sample(st->codec->codec_id) >> 3;
> +            if (!ctx->block_align)
> +                ctx->block_align = ctx->channels *
> +                                     av_get_bits_per_sample(ctx->codec_id) 
> >> 3;
>              break;
>          case AVMEDIA_TYPE_VIDEO:
> -            if (st->codec->time_base.num <= 0 || st->codec->time_base.den <= 
> 0) { //FIXME audio too?
> +            if (ctx->time_base.num <= 0 ||
> +                ctx->time_base.den <= 0) { //FIXME audio too?
>                  av_log(s, AV_LOG_ERROR, "time base not set\n");
>                  ret = AVERROR(EINVAL);
>                  goto fail;
>              }
> -            if ((st->codec->width <= 0 || st->codec->height <= 0) && 
> !(s->oformat->flags & AVFMT_NODIMENSIONS)) {
> +
> +            if ((ctx->width <= 0 || ctx->height <= 0) &&
> +                !(of->flags & AVFMT_NODIMENSIONS)) {
>                  av_log(s, AV_LOG_ERROR, "dimensions not set\n");
>                  ret = AVERROR(EINVAL);
>                  goto fail;
>              }
> -            if (av_cmp_q(st->sample_aspect_ratio, 
> st->codec->sample_aspect_ratio)) {
> +
> +            if (av_cmp_q(st->sample_aspect_ratio,
> +                         ctx->sample_aspect_ratio)) {
>                  av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer 
> "
>                                          "(%d/%d) and encoder layer 
> (%d/%d)\n",
>                         st->sample_aspect_ratio.num, 
> st->sample_aspect_ratio.den,
> -                       st->codec->sample_aspect_ratio.num,
> -                       st->codec->sample_aspect_ratio.den);
> +                       ctx->sample_aspect_ratio.num,
> +                       ctx->sample_aspect_ratio.den);
>                  ret = AVERROR(EINVAL);
>                  goto fail;
>              }
>              break;
>          }
>
> -        if (s->oformat->codec_tag) {
> -            if (st->codec->codec_tag && st->codec->codec_id == 
> AV_CODEC_ID_RAWVIDEO && av_codec_get_tag(s->oformat->codec_tag, 
> st->codec->codec_id) == 0 && !validate_codec_tag(s, st)) {
> -                //the current rawvideo encoding system ends up setting the 
> wrong codec_tag for avi, we override it here
> -                st->codec->codec_tag = 0;
> +        if (of->codec_tag) {
> +            if (ctx->codec_tag &&
> +                ctx->codec_id == AV_CODEC_ID_RAWVIDEO &&
> +                !av_codec_get_tag(of->codec_tag, ctx->codec_id) &&
> +                !validate_codec_tag(s, st)) {
> +                // the current rawvideo encoding system ends up setting
> +                // the wrong codec_tag for avi, we override it here
> +                ctx->codec_tag = 0;
>              }
> -            if (st->codec->codec_tag) {
> +            if (ctx->codec_tag) {
>                  if (!validate_codec_tag(s, st)) {
>                      char tagbuf[32];
> -                    av_get_codec_tag_string(tagbuf, sizeof(tagbuf), 
> st->codec->codec_tag);
> +                    av_get_codec_tag_string(tagbuf, sizeof(tagbuf), 
> ctx->codec_tag);
>                      av_log(s, AV_LOG_ERROR,
>                             "Tag %s/0x%08x incompatible with output codec id 
> '%d'\n",
> -                           tagbuf, st->codec->codec_tag, 
> st->codec->codec_id);
> +                           tagbuf, ctx->codec_tag, ctx->codec_id);
>                      ret = AVERROR_INVALIDDATA;
>                      goto fail;
>                  }
>              } else
> -                st->codec->codec_tag = 
> av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id);
> +                ctx->codec_tag = av_codec_get_tag(of->codec_tag, 
> ctx->codec_id);
>          }
>
> -        if (s->oformat->flags & AVFMT_GLOBALHEADER &&
> -            !(st->codec->flags & CODEC_FLAG_GLOBAL_HEADER))
> -            av_log(s, AV_LOG_WARNING, "Codec for stream %d does not use 
> global headers but container format requires global headers\n", i);
> +        if (of->flags & AVFMT_GLOBALHEADER &&
> +            !(ctx->flags & CODEC_FLAG_GLOBAL_HEADER))
> +            av_log(s, AV_LOG_WARNING,
> +                   "Codec for stream %d does not use global headers "
> +                   "but container format requires global headers\n", i);
>      }
>
> -    if (!s->priv_data && s->oformat->priv_data_size > 0) {
> -        s->priv_data = av_mallocz(s->oformat->priv_data_size);
> +    if (!s->priv_data && of->priv_data_size > 0) {
> +        s->priv_data = av_mallocz(of->priv_data_size);
>          if (!s->priv_data) {
>              ret = AVERROR(ENOMEM);
>              goto fail;
>          }
> -        if (s->oformat->priv_class) {
> -            *(const AVClass **)s->priv_data = s->oformat->priv_class;
> +        if (of->priv_class) {
> +            *(const AVClass **)s->priv_data = of->priv_class;
>              av_opt_set_defaults(s->priv_data);
>              if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
>                  goto fail;
> @@ -233,12 +249,23 @@ int avformat_write_header(AVFormatContext *s, 
> AVDictionary **options)
>          av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
>      }
>
> -    if (s->oformat->write_header) {
> -        ret = s->oformat->write_header(s);
> -        if (ret < 0)
> -            goto fail;
> +    if (options) {
> +         av_dict_free(options);
> +         *options = tmp;
>      }
>
> +    return 0;
> +
> +    fail:
> +    av_dict_free(&tmp);
> +    return ret;
> +}
> +
> +static int init_pts(AVFormatContext *s)
> +{
> +    int i;
> +    AVStream *st;
> +
>      /* init PTS generation */
>      for (i = 0; i < s->nb_streams; i++) {
>          int64_t den = AV_NOPTS_VALUE;
> @@ -255,22 +282,33 @@ int avformat_write_header(AVFormatContext *s, 
> AVDictionary **options)
>              break;
>          }
>          if (den != AV_NOPTS_VALUE) {
> -            if (den <= 0) {
> -                ret = AVERROR_INVALIDDATA;
> -                goto fail;
> -            }
> +            if (den <= 0)
> +                return AVERROR_INVALIDDATA;
> +
>              frac_init(&st->pts, 0, 0, den);
>          }
>      }
>
> -    if (options) {
> -        av_dict_free(options);
> -        *options = tmp;
> +    return 0;
> +}
> +
> +int avformat_write_header(AVFormatContext *s, AVDictionary **options)
> +{
> +    int ret = 0;
> +
> +    if (ret = write_setup(s, options))
> +        return ret;
> +

Will this be used in other places? But OK since it makes the code
easier to read.

Generally the rest looks good, but I wonder if the mechanical/cosmetic
changes could be patched separately from the actual splitting, to make
a patch of this size easier to reason about.

> +    if (s->oformat->write_header) {
> +        ret = s->oformat->write_header(s);
> +        if (ret < 0)
> +            return ret;
>      }
> +
> +    if ((ret = init_pts(s) < 0))
> +        return ret;
> +
>      return 0;
> -fail:
> -    av_dict_free(&tmp);
> -    return ret;
>  }
>
>  //FIXME merge with compute_pkt_fields
> --
> 1.7.12
>
> _______________________________________________
> libav-devel mailing list
> [email protected]
> https://lists.libav.org/mailman/listinfo/libav-devel
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to