lavc: Introduce AVCodec internal capabilities

This field is designed for marking codec properties useful to lavc internals.
Two internal capabilities are added:
 - FF_CODEC_CAP_INIT_THREADSAFE: codec can be opened without locks;
 - FF_CODEC_CAP_INIT_CLEANUP: codec frees memory if initialization fails.
pull/125/head
Vittorio Giovara 10 years ago
parent 9993a067f6
commit 117b432748
  1. 5
      libavcodec/avcodec.h
  2. 10
      libavcodec/internal.h
  3. 7
      libavcodec/utils.c

@ -2924,6 +2924,11 @@ typedef struct AVCodec {
* Will be called when seeking * Will be called when seeking
*/ */
void (*flush)(AVCodecContext *); void (*flush)(AVCodecContext *);
/**
* Internal codec capabilities.
* See FF_CODEC_CAP_* in internal.h
*/
int caps_internal;
} AVCodec; } AVCodec;
/** /**

@ -33,6 +33,16 @@
#include "avcodec.h" #include "avcodec.h"
#include "config.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_SANE_NB_CHANNELS 63U
#define FF_SIGNBIT(x) (x >> CHAR_BIT * sizeof(x) - 1) #define FF_SIGNBIT(x) (x >> CHAR_BIT * sizeof(x) - 1)

@ -1049,7 +1049,8 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
} }
entangled_thread_counter++; entangled_thread_counter++;
if (entangled_thread_counter != 1) { if (entangled_thread_counter != 1 &&
!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE)) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
"Insufficient thread locking. At least %d threads are " "Insufficient thread locking. At least %d threads are "
"calling avcodec_open2() at the same time right now.\n", "calling avcodec_open2() at the same time right now.\n",
@ -1286,6 +1287,10 @@ end:
return ret; return ret;
free_and_end: free_and_end:
if (avctx->codec &&
(avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP))
avctx->codec->close(avctx);
av_dict_free(&tmp); av_dict_free(&tmp);
av_freep(&avctx->priv_data); av_freep(&avctx->priv_data);
if (avctx->internal) { if (avctx->internal) {

Loading…
Cancel
Save