Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 29 Jul 2012 22:56:33 +0000 (00:56 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 29 Jul 2012 22:56:33 +0000 (00:56 +0200)
* qatar/master:
  flvdec: remove spurious use of stream id
  lavf: deprecate r_frame_rate.
  lavf: round estimated average fps to a "standard" fps.

Conflicts:
ffmpeg.c
ffprobe.c
libavformat/avformat.h
libavformat/electronicarts.c
libavformat/flvdec.c
libavformat/rawdec.c
libavformat/utils.c
tests/ref/fate/iv8-demux

Merged-by: Michael Niedermayer <michaelni@gmx.at>
15 files changed:
1  2 
ffmpeg.c
libavformat/avformat.h
libavformat/avisynth.c
libavformat/avs.c
libavformat/electronicarts.c
libavformat/flvdec.c
libavformat/flvenc.c
libavformat/matroskadec.c
libavformat/mov.c
libavformat/nuv.c
libavformat/r3d.c
libavformat/rmdec.c
libavformat/utils.c
libavformat/vc1testenc.c
libavformat/version.h

diff --cc ffmpeg.c
+++ b/ffmpeg.c
@@@ -3078,11 -2512,21 +3078,12 @@@ static int transcode_init(void
                  ist->decoding_needed = 1;
              ost->encoding_needed = 1;
  
 -            /*
 -             * We want CFR output if and only if one of those is true:
 -             * 1) user specified output framerate with -r
 -             * 2) user specified -vsync cfr
 -             * 3) output format is CFR and the user didn't force vsync to
 -             *    something else than CFR
 -             *
 -             * in such a case, set ost->frame_rate
 -             */
 -            if (codec->codec_type == AVMEDIA_TYPE_VIDEO &&
 -                !ost->frame_rate.num && ist &&
 -                (video_sync_method ==  VSYNC_CFR ||
 -                 (video_sync_method ==  VSYNC_AUTO &&
 -                  !(oc->oformat->flags & (AVFMT_NOTIMESTAMPS | AVFMT_VARIABLE_FPS))))) {
 -                ost->frame_rate = ist->st->avg_frame_rate.num ? ist->st->avg_frame_rate : (AVRational){25, 1};
 +            if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 +                if (ost->filter && !ost->frame_rate.num)
 +                    ost->frame_rate = av_buffersink_get_frame_rate(ost->filter->filter);
 +                if (ist && !ost->frame_rate.num)
 +                    ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25, 1};
++//                    ost->frame_rate = ist->st->avg_frame_rate.num ? ist->st->avg_frame_rate : (AVRational){25, 1};
                  if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) {
                      int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
                      ost->frame_rate = ost->enc->supported_framerates[idx];
Simple merge
Simple merge
Simple merge
@@@ -436,11 -431,11 +436,11 @@@ static int ea_read_header(AVFormatConte
          st->codec->codec_tag = 0;  /* no fourcc */
          st->codec->width = ea->width;
          st->codec->height = ea->height;
 -        avpriv_set_pts_info(st, 33, ea->time_base.num, ea->time_base.den);
 -#if FF_API_R_FRAME_RATE
 +        st->duration = st->nb_frames = ea->nb_frames;
 +        if (ea->time_base.num)
 +            avpriv_set_pts_info(st, 64, ea->time_base.num, ea->time_base.den);
-         st->r_frame_rate = st->avg_frame_rate = (AVRational){ea->time_base.den,
-                                                              ea->time_base.num};
+         st->r_frame_rate =
 -#endif
+         st->avg_frame_rate = (AVRational){ea->time_base.den, ea->time_base.num};
      }
  
      if (ea->audio_codec) {
@@@ -69,13 -74,7 +70,12 @@@ static AVStream *create_stream(AVFormat
      AVStream *st = avformat_new_stream(s, NULL);
      if (!st)
          return NULL;
-     st->id = tag;
      st->codec->codec_type = codec_type;
 +    if(s->nb_streams>=3 ||(   s->nb_streams==2
 +                           && s->streams[0]->codec->codec_type != AVMEDIA_TYPE_DATA
 +                           && s->streams[1]->codec->codec_type != AVMEDIA_TYPE_DATA))
 +        s->ctx_flags &= ~AVFMTCTX_NOHEADER;
 +
      avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
      return st;
  }
@@@ -513,11 -510,9 +513,11 @@@ static int flv_read_header(AVFormatCont
              return AVERROR(ENOMEM);
      }
      if(flags & FLV_HEADER_FLAG_HASAUDIO){
-         if(!create_stream(s, 1, AVMEDIA_TYPE_AUDIO))
+         if(!create_stream(s, AVMEDIA_TYPE_AUDIO))
              return AVERROR(ENOMEM);
      }
 +    // Flag doesn't indicate whether or not there is script-data present. Must
 +    // create that stream if it's encountered.
  
      offset = avio_rb32(s->pb);
      avio_seek(s->pb, offset, SEEK_SET);
@@@ -726,13 -712,13 +726,13 @@@ static int flv_read_packet(AVFormatCont
          }
      }
      if(i == s->nb_streams){
-         st = create_stream(s, stream_type,
 +        av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");
 -            is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO);
 -        s->ctx_flags &= ~AVFMTCTX_NOHEADER;
+         st = create_stream(s,
 +             (int[]){AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA}[stream_type]);
      }
 -    av_dlog(s, "%d %X %d \n", is_audio, flags, st->discard);
 -    if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||         is_audio))
 -       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio))
 +    av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);
 +    if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))
 +       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))
         || st->discard >= AVDISCARD_ALL
         ){
          avio_seek(s->pb, next, SEEK_SET);
Simple merge
@@@ -1703,31 -1591,15 +1703,33 @@@ static int matroska_read_header(AVForma
                        st->codec->height * track->video.display_width,
                        st->codec-> width * track->video.display_height,
                        255);
 -            if (st->codec->codec_id != CODEC_ID_H264)
              st->need_parsing = AVSTREAM_PARSE_HEADERS;
              if (track->default_duration) {
-                 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
+                 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
                            1000000000, track->default_duration, 30000);
-                 st->avg_frame_rate = st->r_frame_rate;
+ #if FF_API_R_FRAME_RATE
+                 st->r_frame_rate = st->avg_frame_rate;
+ #endif
              }
 +
 +            /* export stereo mode flag as metadata tag */
 +            if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREO_MODE_COUNT)
 +                av_dict_set(&st->metadata, "stereo_mode", matroska_video_stereo_mode[track->video.stereo_mode], 0);
 +
 +            /* if we have virtual track, mark the real tracks */
 +            for (j=0; j < track->operation.combine_planes.nb_elem; j++) {
 +                char buf[32];
 +                if (planes[j].type >= MATROSKA_VIDEO_STEREO_PLANE_COUNT)
 +                    continue;
 +                snprintf(buf, sizeof(buf), "%s_%d",
 +                         matroska_video_stereo_plane[planes[j].type], i);
 +                for (k=0; k < matroska->tracks.nb_elem; k++)
 +                    if (planes[j].uid == tracks[k].uid) {
 +                        av_dict_set(&s->streams[k]->metadata,
 +                                    "stereo_mode", buf, 0);
 +                        break;
 +                    }
 +            }
          } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
              st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
              st->codec->sample_rate = track->audio.out_samplerate;
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -2662,20 -2417,15 +2664,21 @@@ int avformat_find_stream_info(AVFormatC
              }
              st->info->fps_last_dts = pkt->dts;
              st->info->fps_last_dts_idx = st->codec_info_nb_frames;
 -
 -            /* check max_analyze_duration */
 -            if (av_rescale_q(pkt->dts - st->info->fps_first_dts, st->time_base,
 -                             AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
 -                av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");
 +        }
 +        if (st->codec_info_nb_frames>1) {
 +            int64_t t=0;
 +            if (st->time_base.den > 0)
 +                t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q);
 +            if (st->avg_frame_rate.num > 0)
 +                t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, (AVRational){st->avg_frame_rate.den, st->avg_frame_rate.num}, AV_TIME_BASE_Q));
 +
 +            if (t >= ic->max_analyze_duration) {
 +                av_log(ic, AV_LOG_WARNING, "max_analyze_duration %d reached at %"PRId64"\n", ic->max_analyze_duration, t);
                  break;
              }
 +            st->info->codec_info_duration += pkt->duration;
          }
+ #if FF_API_R_FRAME_RATE
          {
              int64_t last = st->info->last_dts;
  
      for(i=0;i<ic->nb_streams;i++) {
          st = ic->streams[i];
          if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 +            if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample){
 +                uint32_t tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
 +                if(ff_find_pix_fmt(ff_raw_pix_fmt_tags, tag) == st->codec->pix_fmt)
 +                    st->codec->codec_tag= tag;
 +            }
 +
              /* estimate average framerate if not set by demuxer */
 -            if (!st->avg_frame_rate.num && st->info->fps_last_dts != st->info->fps_first_dts) {
 -                int64_t delta_dts = st->info->fps_last_dts - st->info->fps_first_dts;
 -                int delta_packets = st->info->fps_last_dts_idx - st->info->fps_first_dts_idx;
 +            if (st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && st->info->codec_info_duration) {
+                 int      best_fps = 0;
+                 double best_error = 0.01;
                  av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
 -                          delta_packets*(int64_t)st->time_base.den,
 -                          delta_dts*(int64_t)st->time_base.num, 60000);
 +                          (st->codec_info_nb_frames-2)*(int64_t)st->time_base.den,
 +                          st->info->codec_info_duration*(int64_t)st->time_base.num, 60000);
+                 /* round guessed framerate to a "standard" framerate if it's
+                  * within 1% of the original estimate*/
+                 for (j = 1; j < MAX_STD_TIMEBASES; j++) {
+                     AVRational std_fps = (AVRational){get_std_framerate(j), 12*1001};
+                     double error = fabs(av_q2d(st->avg_frame_rate) / av_q2d(std_fps) - 1);
+                     if (error < best_error) {
+                         best_error = error;
+                         best_fps   = std_fps.num;
+                     }
+                 }
+                 if (best_fps) {
+                     av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
+                               best_fps, 12*1001, INT_MAX);
+                 }
              }
 -#if FF_API_R_FRAME_RATE
              // the check for tb_unreliable() is not completely correct, since this is not about handling
              // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
              // ipmovie.c produces.
Simple merge
Simple merge