Merge commit 'ecf442a58b09bdb1dc1d2c3904b82ac5f79b2878'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 14 Nov 2013 19:56:44 +0000 (20:56 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 14 Nov 2013 20:04:44 +0000 (21:04 +0100)
* commit 'ecf442a58b09bdb1dc1d2c3904b82ac5f79b2878':
  lavf: improve support for AVC-Intra files.

Conflicts:
libavformat/internal.h
libavformat/isom.c
libavformat/mxfdec.c
libavformat/utils.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/internal.h
libavformat/isom.h
libavformat/mov.c
libavformat/mxfdec.c
libavformat/utils.c

@@@ -348,26 -340,9 +348,27 @@@ enum AVCodecID ff_codec_get_id(const AV
  enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags);
  
  /**
-  * Generate standard extradata for AVC-Intra based on width/height and field order.
 + * Chooses a timebase for muxing the specified stream.
 + *
 + * The choosen timebase allows sample accurate timestamps based
 + * on the framerate or sample rate for audio streams. It also is
 + * at least as precisse as 1/min_precission would be.
 + */
 +AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precission);
 +
 +/**
+  * Generate standard extradata for AVC-Intra based on width/height and field
+  * order.
   */
void ff_generate_avci_extradata(AVStream *st);
int ff_generate_avci_extradata(AVStream *st);
  
 +/**
 + * Allocate extradata with additional FF_INPUT_BUFFER_PADDING_SIZE at end
 + * which is always set to 0.
 + *
 + * @param size size of extradata
 + * @return 0 if OK, AVERROR_xxx on error
 + */
 +int ff_alloc_extradata(AVCodecContext *avctx, int size);
 +
  #endif /* AVFORMAT_INTERNAL_H */
Simple merge
Simple merge
@@@ -1506,16 -1465,8 +1506,17 @@@ static int mxf_parse_structural_metadat
  
          /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
          codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);
 -        st->codec->codec_id = codec_ul->id;
 +        st->codec->codec_id = (enum AVCodecID)codec_ul->id;
 +        av_log(mxf->fc, AV_LOG_VERBOSE, "%s: Universal Label: ",
 +               avcodec_get_name(st->codec->codec_id));
 +        for (k = 0; k < 16; k++) {
 +            av_log(mxf->fc, AV_LOG_VERBOSE, "%.2x",
 +                   descriptor->essence_codec_ul[k]);
 +            if (!(k+1 & 19) || k == 5)
 +                av_log(mxf->fc, AV_LOG_VERBOSE, ".");
 +        }
 +        av_log(mxf->fc, AV_LOG_VERBOSE, "\n");
          if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
              source_track->intra_only = mxf_is_intra_only(descriptor);
              container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
              }
          }
          if (descriptor->extradata) {
 -            st->codec->extradata = av_mallocz(descriptor->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
 -            if (st->codec->extradata)
 +            if (!ff_alloc_extradata(st->codec, descriptor->extradata_size)) {
                  memcpy(st->codec->extradata, descriptor->extradata, descriptor->extradata_size);
-         } else if(st->codec->codec_id == AV_CODEC_ID_H264) {
-             ff_generate_avci_extradata(st);
 +            }
+         } else if (st->codec->codec_id == AV_CODEC_ID_H264) {
+             ret = ff_generate_avci_extradata(st);
+             if (ret < 0)
+                 return ret;
          }
          if (st->codec->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {
              /* TODO: decode timestamps */
@@@ -4071,107 -3265,7 +4071,107 @@@ int ff_add_param_change(AVPacket *pkt, 
      return 0;
  }
  
- void ff_generate_avci_extradata(AVStream *st)
 +AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame)
 +{
 +    AVRational undef = {0, 1};
 +    AVRational stream_sample_aspect_ratio = stream ? stream->sample_aspect_ratio : undef;
 +    AVRational codec_sample_aspect_ratio  = stream && stream->codec ? stream->codec->sample_aspect_ratio : undef;
 +    AVRational frame_sample_aspect_ratio  = frame  ? frame->sample_aspect_ratio  : codec_sample_aspect_ratio;
 +
 +    av_reduce(&stream_sample_aspect_ratio.num, &stream_sample_aspect_ratio.den,
 +               stream_sample_aspect_ratio.num,  stream_sample_aspect_ratio.den, INT_MAX);
 +    if (stream_sample_aspect_ratio.num <= 0 || stream_sample_aspect_ratio.den <= 0)
 +        stream_sample_aspect_ratio = undef;
 +
 +    av_reduce(&frame_sample_aspect_ratio.num, &frame_sample_aspect_ratio.den,
 +               frame_sample_aspect_ratio.num,  frame_sample_aspect_ratio.den, INT_MAX);
 +    if (frame_sample_aspect_ratio.num <= 0 || frame_sample_aspect_ratio.den <= 0)
 +        frame_sample_aspect_ratio = undef;
 +
 +    if (stream_sample_aspect_ratio.num)
 +        return stream_sample_aspect_ratio;
 +    else
 +        return frame_sample_aspect_ratio;
 +}
 +
 +AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame)
 +{
 +    AVRational fr = st->r_frame_rate;
 +
 +    if (st->codec->ticks_per_frame > 1) {
 +        AVRational codec_fr = av_inv_q(st->codec->time_base);
 +        AVRational   avg_fr = st->avg_frame_rate;
 +        codec_fr.den *= st->codec->ticks_per_frame;
 +        if (   codec_fr.num > 0 && codec_fr.den > 0 && av_q2d(codec_fr) < av_q2d(fr)*0.7
 +            && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1)
 +            fr = codec_fr;
 +    }
 +
 +    return fr;
 +}
 +
 +int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
 +                                    const char *spec)
 +{
 +    if (*spec <= '9' && *spec >= '0') /* opt:index */
 +        return strtol(spec, NULL, 0) == st->index;
 +    else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
 +             *spec == 't') { /* opt:[vasdt] */
 +        enum AVMediaType type;
 +
 +        switch (*spec++) {
 +        case 'v': type = AVMEDIA_TYPE_VIDEO;      break;
 +        case 'a': type = AVMEDIA_TYPE_AUDIO;      break;
 +        case 's': type = AVMEDIA_TYPE_SUBTITLE;   break;
 +        case 'd': type = AVMEDIA_TYPE_DATA;       break;
 +        case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
 +        default:  av_assert0(0);
 +        }
 +        if (type != st->codec->codec_type)
 +            return 0;
 +        if (*spec++ == ':') { /* possibly followed by :index */
 +            int i, index = strtol(spec, NULL, 0);
 +            for (i = 0; i < s->nb_streams; i++)
 +                if (s->streams[i]->codec->codec_type == type && index-- == 0)
 +                   return i == st->index;
 +            return 0;
 +        }
 +        return 1;
 +    } else if (*spec == 'p' && *(spec + 1) == ':') {
 +        int prog_id, i, j;
 +        char *endptr;
 +        spec += 2;
 +        prog_id = strtol(spec, &endptr, 0);
 +        for (i = 0; i < s->nb_programs; i++) {
 +            if (s->programs[i]->id != prog_id)
 +                continue;
 +
 +            if (*endptr++ == ':') {
 +                int stream_idx = strtol(endptr, NULL, 0);
 +                return stream_idx >= 0 &&
 +                    stream_idx < s->programs[i]->nb_stream_indexes &&
 +                    st->index == s->programs[i]->stream_index[stream_idx];
 +            }
 +
 +            for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
 +                if (st->index == s->programs[i]->stream_index[j])
 +                    return 1;
 +        }
 +        return 0;
 +    } else if (*spec == '#') {
 +        int sid;
 +        char *endptr;
 +        sid = strtol(spec + 1, &endptr, 0);
 +        if (!*endptr)
 +            return st->id == sid;
 +    } else if (!*spec) /* empty specifier, matches everything */
 +        return 1;
 +
 +    av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
 +    return AVERROR(EINVAL);
 +}
 +
+ int ff_generate_avci_extradata(AVStream *st)
  {
      static const uint8_t avci100_1080p_extradata[] = {
          // SPS
          data = avci100_720p_extradata;
          size = sizeof(avci100_720p_extradata);
      }
      if (!size)
-         return;
+         return 0;
      av_freep(&st->codec->extradata);
 -    st->codec->extradata_size = 0;
 -    st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
 -    if (!st->codec->extradata)
 +    if (ff_alloc_extradata(st->codec, size))
-         return;
+         return AVERROR(ENOMEM);
 -
      memcpy(st->codec->extradata, data, size);
 -    st->codec->extradata_size = size;
+     return 0;
  }