Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 23 Mar 2012 20:20:06 +0000 (21:20 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 23 Mar 2012 20:20:06 +0000 (21:20 +0100)
* qatar/master:
  rv34: Handle only complete frames in frame-mt.
  MPV: set reference frame pointers to NULL when allocation of dummy pictures fails
  configure: die if x11grab dependencies are unavailable
  zerocodec: factorize loop
  avconv: fix the resampling safety factors for output audio buffer allocation
  avconv: move audio output buffer allocation to a separate function
  avconv: make the async buffer global and free it in exit_program()

Conflicts:
ffmpeg.c
libavcodec/mpegvideo.c
libavcodec/rv34.c
libavcodec/zerocodec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
configure
ffmpeg.c
libavcodec/mpegvideo.c
libavcodec/rv34.c
libavcodec/zerocodec.c

diff --cc configure
+++ b/configure
@@@ -1636,10 -1496,8 +1636,9 @@@ v4l2_indev_deps_any="linux_videodev2_h 
  vfwcap_indev_deps="capCreateCaptureWindow vfwcap_defines"
  vfwcap_indev_extralibs="-lavicap32"
  x11_grab_device_indev_deps="x11grab XShmCreateImage"
- x11_grab_device_indev_extralibs="-lX11 -lXext -lXfixes"
  
  # protocols
 +bluray_protocol_deps="libbluray"
  gopher_protocol_deps="network"
  httpproxy_protocol_deps="network"
  httpproxy_protocol_select="tcp_protocol"
@@@ -3279,19 -3025,14 +3278,16 @@@ enabled_any sndio_indev sndio_outdev &
  enabled libcdio &&
      check_lib2 "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open "-lcdio_paranoia -lcdio_cdda -lcdio"
  
- enabled x11grab                         &&
- check_header X11/Xlib.h                 &&
- check_header X11/extensions/XShm.h      &&
- check_header X11/extensions/Xfixes.h    &&
- check_func XOpenDisplay -lX11           &&
- check_func XShmCreateImage -lX11 -lXext &&
- check_func XFixesGetCursorImage -lX11 -lXext -lXfixes
+ enabled x11grab                                           &&
+ require X11 X11/Xlib.h XOpenDisplay -lX11                 &&
+ require Xext X11/extensions/XShm.h XShmCreateImage -lXext &&
+ require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes
  
 -# check for VDA header
 -if ! disabled vda && check_header VideoDecodeAcceleration/VDADecoder.h; then
 -    enable vda && add_extralibs -framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore
 +if ! disabled vaapi; then
 +    check_lib va/va.h vaInitialize -lva && {
 +        check_cpp_condition va/va_version.h "VA_CHECK_VERSION(0,32,0)" ||
 +        warn "Please upgrade to VA-API >= 0.32 if you would like full VA-API support.";
 +    } || disable vaapi
  fi
  
  if ! disabled vdpau && enabled vdpau_vdpau_h; then
diff --cc ffmpeg.c
+++ b/ffmpeg.c
@@@ -179,10 -142,10 +179,10 @@@ static int debug_ts = 0
  
  static uint8_t *audio_buf;
  static unsigned int allocated_audio_buf_size;
- static uint8_t *input_tmp= NULL;
+ static uint8_t *async_buf;
+ static unsigned int allocated_async_buf_size;
  
 -#define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass"
 +#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
  
  typedef struct FrameBuffer {
      uint8_t *base[4];
@@@ -868,8 -718,10 +868,10 @@@ void av_noreturn exit_program(int ret
      av_freep(&output_files);
  
      uninit_opts();
--    av_free(audio_buf);
++    av_freep(&audio_buf);
      allocated_audio_buf_size = 0;
 -    av_free(async_buf);
++    av_freep(&async_buf);
+     allocated_async_buf_size = 0;
  
  #if CONFIG_AVFILTER
      avfilter_uninit();
@@@ -1112,57 -1006,53 +1112,70 @@@ static int encode_audio_frame(AVFormatC
          write_frame(s, &pkt, ost);
  
          audio_size += pkt.size;
 +
 +        av_free_packet(&pkt);
 +    }
 +
 +    if (debug_ts) {
 +        av_log(NULL, AV_LOG_INFO, "encoder -> type:audio "
 +               "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
 +               av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base),
 +               av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base));
      }
  
 -    return pkt.size;
 +    return ret;
  }
  
 -    audio_buf_samples = 4 * audio_buf_samples + 16; // safety factors for resampling
+ static int alloc_audio_output_buf(AVCodecContext *dec, AVCodecContext *enc,
+                                   int nb_samples)
+ {
+     int64_t audio_buf_samples;
+     int audio_buf_size;
+     /* calculate required number of samples to allocate */
+     audio_buf_samples = ((int64_t)nb_samples * enc->sample_rate + dec->sample_rate) /
+                         dec->sample_rate;
++    audio_buf_samples = 4 * audio_buf_samples + 10000; // safety factors for resampling
+     audio_buf_samples = FFMAX(audio_buf_samples, enc->frame_size);
+     if (audio_buf_samples > INT_MAX)
+         return AVERROR(EINVAL);
+     audio_buf_size = av_samples_get_buffer_size(NULL, enc->channels,
+                                                 audio_buf_samples,
+                                                 enc->sample_fmt, 32);
+     if (audio_buf_size < 0)
+         return audio_buf_size;
+     av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size);
+     if (!audio_buf)
+         return AVERROR(ENOMEM);
+     return 0;
+ }
  static void do_audio_out(AVFormatContext *s, OutputStream *ost,
                           InputStream *ist, AVFrame *decoded_frame)
  {
      uint8_t *buftmp;
-     int64_t audio_buf_size, size_out;
++    int64_t size_out;
  
 -    int size_out, frame_bytes, resample_changed;
 +    int frame_bytes, resample_changed;
      AVCodecContext *enc = ost->st->codec;
      AVCodecContext *dec = ist->st->codec;
      int osize = av_get_bytes_per_sample(enc->sample_fmt);
      int isize = av_get_bytes_per_sample(dec->sample_fmt);
 -    uint8_t *buf = decoded_frame->data[0];
 +    uint8_t *buf[AV_NUM_DATA_POINTERS];
      int size     = decoded_frame->nb_samples * dec->channels * isize;
-     int64_t allocated_for_size = size;
 +    int planes   = av_sample_fmt_is_planar(dec->sample_fmt) ? dec->channels : 1;
 +    int i;
 +
 +    av_assert0(planes <= AV_NUM_DATA_POINTERS);
 +
 +    for(i=0; i<planes; i++)
 +        buf[i]= decoded_frame->data[i];
  
- need_realloc:
-     audio_buf_size  = (allocated_for_size + isize * dec->channels - 1) / (isize * dec->channels);
-     audio_buf_size  = (audio_buf_size * enc->sample_rate + dec->sample_rate) / dec->sample_rate;
-     audio_buf_size  = audio_buf_size * 2 + 10000; // safety factors for the deprecated resampling API
-     audio_buf_size  = FFMAX(audio_buf_size, enc->frame_size);
-     audio_buf_size *= osize * enc->channels;
-     if (audio_buf_size > INT_MAX) {
-         av_log(NULL, AV_LOG_FATAL, "Buffer sizes too large\n");
-         exit_program(1);
-     }
-     av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size);
-     if (!audio_buf) {
-         av_log(NULL, AV_LOG_FATAL, "Out of memory in do_audio_out\n");
+     if (alloc_audio_output_buf(dec, enc, decoded_frame->nb_samples) < 0) {
+         av_log(NULL, AV_LOG_FATAL, "Error allocating audio buffer\n");
          exit_program(1);
      }
  
                      }
                      ist->is_start = 0;
  
 -                    generate_silence(async_buf, dec->sample_fmt, byte_delta);
 -                    memcpy(async_buf + byte_delta, buf, size);
 -                    buf = async_buf;
 +                    for (i=0; i<planes; i++) {
-                         uint8_t *t = input_tmp + i*((byte_delta + size)/planes);
++                        uint8_t *t = async_buf + i*((byte_delta + size)/planes);
 +                        generate_silence(t, dec->sample_fmt, byte_delta/planes);
 +                        memcpy(t + byte_delta/planes, buf[i], size/planes);
 +                        buf[i] = t;
 +                    }
                      size += byte_delta;
                      av_log(NULL, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", idelta);
                  }
              }
          }
      } else
 -        ost->sync_opts = lrintf(get_sync_ipts(ost, ist->last_dts) * enc->sample_rate) -
 +        ost->sync_opts = lrintf(get_sync_ipts(ost, ist->pts) * enc->sample_rate) -
                                  av_fifo_size(ost->fifo) / (enc->channels * osize); // FIXME wrong
  
 -    if (ost->audio_resample) {
 +    if (ost->audio_resample || ost->audio_channels_mapped) {
          buftmp = audio_buf;
-         size_out = swr_convert(ost->swr, (      uint8_t*[]){buftmp}, audio_buf_size / (enc->channels * osize),
 -        size_out = audio_resample(ost->resample,
 -                                  (short *)buftmp, (short *)buf,
 -                                  size / (dec->channels * isize));
++        size_out = swr_convert(ost->swr, (      uint8_t*[]){buftmp}, allocated_audio_buf_size / (enc->channels * osize),
 +                                         buf, size / (dec->channels * isize));
 +        if (size_out < 0) {
 +            av_log(NULL, AV_LOG_FATAL, "swr_convert failed\n");
 +            exit_program(1);
 +        }
          size_out = size_out * enc->channels * osize;
      } else {
 -        buftmp = buf;
 +        buftmp = buf[0];
          size_out = size;
      }
  
@@@ -1235,18 -1266,11 +1235,20 @@@ int ff_MPV_frame_start(MpegEncContext *
  
              /* Allocate a dummy frame */
              i = ff_find_unused_picture(s, 0);
-             s->last_picture_ptr= &s->picture[i];
 +            if (i < 0)
 +                return i;
-             if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0)
+             s->last_picture_ptr = &s->picture[i];
 +            s->last_picture_ptr->f.key_frame = 0;
+             if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) {
+                 s->last_picture_ptr = NULL;
                  return -1;
+             }
 +
 +            if(s->codec_id == CODEC_ID_FLV1 || s->codec_id == CODEC_ID_H263){
 +                for(i=0; i<avctx->height; i++)
 +                    memset(s->last_picture_ptr->f.data[0] + s->last_picture_ptr->f.linesize[0]*i, 16, avctx->width);
 +            }
 +
              ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 0);
              ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 1);
              s->last_picture_ptr->f.reference = 3;
              s->pict_type == AV_PICTURE_TYPE_B) {
              /* Allocate a dummy frame */
              i = ff_find_unused_picture(s, 0);
-             s->next_picture_ptr= &s->picture[i];
 +            if (i < 0)
 +                return i;
-             if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0)
+             s->next_picture_ptr = &s->picture[i];
 +            s->next_picture_ptr->f.key_frame = 0;
+             if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) {
+                 s->next_picture_ptr = NULL;
                  return -1;
+             }
              ff_thread_report_progress(&s->next_picture_ptr->f, INT_MAX, 0);
              ff_thread_report_progress(&s->next_picture_ptr->f, INT_MAX, 1);
              s->next_picture_ptr->f.reference = 3;
@@@ -1406,65 -1406,11 +1406,15 @@@ static int rv34_decode_slice(RV34DecCon
          return -1;
      }
  
-     if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
-         if (s->width != r->si.width || s->height != r->si.height) {
-             int err;
-             av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n",
-                    r->si.width, r->si.height);
-             ff_MPV_common_end(s);
-             s->width  = r->si.width;
-             s->height = r->si.height;
-             avcodec_set_dimensions(s->avctx, s->width, s->height);
-             if ((err = ff_MPV_common_init(s)) < 0)
-                 return err;
-             if ((err = rv34_decoder_realloc(r)) < 0)
-                 return err;
-         }
-         s->pict_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
-         if(ff_MPV_frame_start(s, s->avctx) < 0)
-             return -1;
-         ff_er_frame_start(s);
-         if (!r->tmp_b_block_base) {
-             int i;
-             r->tmp_b_block_base = av_malloc(s->linesize * 48);
-             for (i = 0; i < 2; i++)
-                 r->tmp_b_block_y[i] = r->tmp_b_block_base + i * 16 * s->linesize;
-             for (i = 0; i < 4; i++)
-                 r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize
-                                        + (i >> 1) * 8 * s->uvlinesize + (i & 1) * 16;
-         }
-         r->cur_pts = r->si.pts;
-         if(s->pict_type != AV_PICTURE_TYPE_B){
-             r->last_pts = r->next_pts;
-             r->next_pts = r->cur_pts;
-         }else{
-             int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
-             int dist0   = GET_PTS_DIFF(r->cur_pts,  r->last_pts);
-             int dist1   = GET_PTS_DIFF(r->next_pts, r->cur_pts);
-             if(!refdist){
-                 r->weight1 = r->weight2 = 8192;
-             }else{
-                 r->weight1 = (dist0 << 14) / refdist;
-                 r->weight2 = (dist1 << 14) / refdist;
-             }
-         }
-         s->mb_x = s->mb_y = 0;
-         ff_thread_finish_setup(s->avctx);
-     } else {
-         int slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
-         if (slice_type != s->pict_type) {
-             av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
-             return AVERROR_INVALIDDATA;
-         }
-         if (s->width != r->si.width || s->height != r->si.height) {
-             av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n");
-             return AVERROR_INVALIDDATA;
-         }
+     slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
+     if (slice_type != s->pict_type) {
+         av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
+         return AVERROR_INVALIDDATA;
+     }
++    if (s->width != r->si.width || s->height != r->si.height) {
++        av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n");
++        return AVERROR_INVALIDDATA;
 +    }
  
      r->si.end = end;
      s->qscale = r->si.quant;
@@@ -73,16 -70,13 +70,12 @@@ static int zerocodec_decode_frame(AVCod
      }
  
      for (i = 0; i < avctx->height; i++) {
          zstream->next_out  = dst;
          zstream->avail_out = avctx->width << 1;
--
          zret = inflate(zstream, Z_SYNC_FLUSH);
          if (zret != Z_OK && zret != Z_STREAM_END) {
              av_log(avctx, AV_LOG_ERROR,
-                     "Inflate failed with return code: %d\n", zret);
+                    "Inflate failed with return code: %d\n", zret);
              return AVERROR(EINVAL);
          }