Merge commit '117b432748ca87de4cd0f09d9b1495545e264733'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 13 Mar 2015 21:20:17 +0000 (22:20 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 13 Mar 2015 21:38:53 +0000 (22:38 +0100)
* commit '117b432748ca87de4cd0f09d9b1495545e264733':
  lavc: Introduce AVCodec internal capabilities

Conflicts:
libavcodec/utils.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/avcodec.h
libavcodec/internal.h
libavcodec/utils.c

@@@ -3262,12 -2924,13 +3262,17 @@@ typedef struct AVCodec 
       * Will be called when seeking
       */
      void (*flush)(AVCodecContext *);
+     /**
+      * Internal codec capabilities.
+      * See FF_CODEC_CAP_* in internal.h
+      */
+     int caps_internal;
  } AVCodec;
  
 +int av_codec_get_max_lowres(const AVCodec *codec);
 +
 +struct MpegEncContext;
 +
  /**
   * @defgroup lavc_hwaccel AVHWAccel
   * @{
  #include "avcodec.h"
  #include "config.h"
  
+ /**
+  * Codec is thread safe.
+  */
+ #define FF_CODEC_CAP_INIT_THREADSAFE        (1 << 0)
+ /**
+  * Codec cleans up memory on init failure.
+  */
+ #define FF_CODEC_CAP_INIT_CLEANUP           (1 << 1)
  #define FF_SANE_NB_CHANNELS 63U
  
 -#define FF_SIGNBIT(x) (x >> CHAR_BIT * sizeof(x) - 1)
 +#define FF_SIGNBIT(x) ((x) >> CHAR_BIT * sizeof(x) - 1)
 +
 +#if HAVE_AVX
 +#   define STRIDE_ALIGN 32
 +#elif HAVE_SIMD_ALIGN_16
 +#   define STRIDE_ALIGN 16
 +#else
 +#   define STRIDE_ALIGN 8
 +#endif
  
  typedef struct FramePool {
      /**
@@@ -148,18 -127,6 +158,18 @@@ int ff_match_2uint16(const uint16_t (*t
  
  unsigned int avpriv_toupper4(unsigned int x);
  
- int ff_lock_avcodec(AVCodecContext *log_ctx);
 +/**
 + * does needed setup of pkt_pts/pos and such for (re)get_buffer();
 + */
 +int ff_init_buffer_info(AVCodecContext *s, AVFrame *frame);
 +
 +
 +void avpriv_color_frame(AVFrame *frame, const int color[4]);
 +
 +extern volatile int ff_avcodec_locked;
++int ff_lock_avcodec(AVCodecContext *log_ctx, AVCodec *codec);
 +int ff_unlock_avcodec(void);
 +
  int avpriv_lock_avformat(void);
  int avpriv_unlock_avformat(void);
  
@@@ -1270,58 -1016,6 +1270,58 @@@ void avcodec_free_frame(AVFrame **frame
  }
  #endif
  
-     ff_lock_avcodec(avctx);
 +MAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase)
 +MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor)
 +MAKE_ACCESSORS(AVCodecContext, codec, int, lowres)
 +MAKE_ACCESSORS(AVCodecContext, codec, int, seek_preroll)
 +MAKE_ACCESSORS(AVCodecContext, codec, uint16_t*, chroma_intra_matrix)
 +
 +int av_codec_get_max_lowres(const AVCodec *codec)
 +{
 +    return codec->max_lowres;
 +}
 +
 +static void get_subtitle_defaults(AVSubtitle *sub)
 +{
 +    memset(sub, 0, sizeof(*sub));
 +    sub->pts = AV_NOPTS_VALUE;
 +}
 +
 +static int get_bit_rate(AVCodecContext *ctx)
 +{
 +    int bit_rate;
 +    int bits_per_sample;
 +
 +    switch (ctx->codec_type) {
 +    case AVMEDIA_TYPE_VIDEO:
 +    case AVMEDIA_TYPE_DATA:
 +    case AVMEDIA_TYPE_SUBTITLE:
 +    case AVMEDIA_TYPE_ATTACHMENT:
 +        bit_rate = ctx->bit_rate;
 +        break;
 +    case AVMEDIA_TYPE_AUDIO:
 +        bits_per_sample = av_get_bits_per_sample(ctx->codec_id);
 +        bit_rate = bits_per_sample ? ctx->sample_rate * ctx->channels * bits_per_sample : ctx->bit_rate;
 +        break;
 +    default:
 +        bit_rate = 0;
 +        break;
 +    }
 +    return bit_rate;
 +}
 +
 +int attribute_align_arg ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
 +{
 +    int ret = 0;
 +
 +    ff_unlock_avcodec();
 +
 +    ret = avcodec_open2(avctx, codec, options);
 +
++    ff_lock_avcodec(avctx, codec);
 +    return ret;
 +}
 +
  int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
  {
      int ret = 0;
      if (options)
          av_dict_copy(&tmp, *options, 0);
  
-     ret = ff_lock_avcodec(avctx);
 -    /* If there is a user-supplied mutex locking routine, call it. */
 -    if (lockmgr_cb) {
 -        if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
 -            return -1;
 -    }
 -
 -    entangled_thread_counter++;
 -    if (entangled_thread_counter != 1 &&
 -        !(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE)) {
 -        av_log(avctx, AV_LOG_ERROR,
 -               "Insufficient thread locking. At least %d threads are "
 -               "calling avcodec_open2() at the same time right now.\n",
 -               entangled_thread_counter);
 -        ret = -1;
 -        goto end;
 -    }
++    ret = ff_lock_avcodec(avctx, codec);
 +    if (ret < 0)
 +        return ret;
  
      avctx->internal = av_mallocz(sizeof(AVCodecInternal));
      if (!avctx->internal) {
          avctx->time_base.den = avctx->sample_rate;
      }
  
 -    if (HAVE_THREADS) {
 +    if (!HAVE_THREADS)
 +        av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n");
 +
 +    if (CONFIG_FRAME_THREAD_ENCODER) {
 +        ff_unlock_avcodec(); //we will instanciate a few encoders thus kick the counter to prevent false detection of a problem
 +        ret = ff_frame_thread_encoder_init(avctx, options ? *options : NULL);
-         ff_lock_avcodec(avctx);
++        ff_lock_avcodec(avctx, codec);
 +        if (ret < 0)
 +            goto free_and_end;
 +    }
 +
 +    if (HAVE_THREADS
 +        && !(avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))) {
          ret = ff_thread_init(avctx);
          if (ret < 0) {
              goto free_and_end;
  
      return ret;
  free_and_end:
+     if (avctx->codec &&
+         (avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP))
+         avctx->codec->close(avctx);
      av_dict_free(&tmp);
 +    if (codec->priv_class && codec->priv_data_size)
 +        av_opt_free(avctx->priv_data);
      av_freep(&avctx->priv_data);
      if (avctx->internal) {
          av_frame_free(&avctx->internal->to_free);
@@@ -3600,42 -2428,6 +3604,43 @@@ int av_lockmgr_register(int (*cb)(void 
      return 0;
  }
  
- int ff_lock_avcodec(AVCodecContext *log_ctx)
++int ff_lock_avcodec(AVCodecContext *log_ctx, AVCodec *codec)
 +{
 +    if (lockmgr_cb) {
 +        if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
 +            return -1;
 +    }
 +    entangled_thread_counter++;
-     if (entangled_thread_counter != 1) {
++    if (entangled_thread_counter != 1 &&
++        !(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE)) {
 +        av_log(log_ctx, AV_LOG_ERROR,
 +               "Insufficient thread locking. At least %d threads are "
 +               "calling avcodec_open2() at the same time right now.\n",
 +               entangled_thread_counter);
 +        if (!lockmgr_cb)
 +            av_log(log_ctx, AV_LOG_ERROR, "No lock manager is set, please see av_lockmgr_register()\n");
 +        ff_avcodec_locked = 1;
 +        ff_unlock_avcodec();
 +        return AVERROR(EINVAL);
 +    }
 +    av_assert0(!ff_avcodec_locked);
 +    ff_avcodec_locked = 1;
 +    return 0;
 +}
 +
 +int ff_unlock_avcodec(void)
 +{
 +    av_assert0(ff_avcodec_locked);
 +    ff_avcodec_locked = 0;
 +    entangled_thread_counter--;
 +    if (lockmgr_cb) {
 +        if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE))
 +            return -1;
 +    }
 +
 +    return 0;
 +}
 +
  int avpriv_lock_avformat(void)
  {
      if (lockmgr_cb) {