Adds support for decoder-private options and makes setting other options
simpler.
---
libavcodec/avcodec.h | 33 +++++++++++++++++++++++++++++++++
libavcodec/options.c | 21 ++++++++++++++++++++-
libavcodec/utils.c | 21 ++++++++++++++++++++-
3 files changed, 73 insertions(+), 2 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index e067ee0..a97f1f9 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -30,6 +30,7 @@
#include "libavutil/samplefmt.h"
#include "libavutil/avutil.h"
#include "libavutil/cpu.h"
+#include "libavutil/meta.h"
#include "libavcodec/version.h"
@@ -3612,6 +3613,38 @@ int avcodec_default_execute2(AVCodecContext *c, int
(*func)(AVCodecContext *c2,
int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
/**
+ * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
+ * function the context has to be allocated with avcodec_alloc_context().
+ *
+ * The functions avcodec_find_decoder_by_name(),
avcodec_find_encoder_by_name(),
+ * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
+ * retrieving a codec.
+ *
+ * @warning This function is not thread safe!
+ *
+ * @code
+ * avcodec_register_all();
+ * avmeta_set(&opts, "b", "2.5M", 0);
+ * codec = avcodec_find_decoder(CODEC_ID_H264);
+ * if (!codec)
+ * exit(1);
+ *
+ * context = avcodec_alloc_context();
+ *
+ * if (avcodec_open(context, codec, opts) < 0)
+ * exit(1);
+ * @endcode
+ *
+ * @param avctx The context to initialize.
+ * @param options Metadata filled with AVCodecContext and codec-private
options.
+ * One return this object will be filled with options that
were not found.
+ *
+ * @return zero on success, a negative value on error
+ * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder
+ */
+int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVMetadata **options);
+
+/**
* Decode the audio frame of size avpkt->size from avpkt->data into samples.
* Some decoders may support multiple frames in a single AVPacket, such
* decoders would then just decode the first frame. In this case,
diff --git a/libavcodec/options.c b/libavcodec/options.c
index 8f9aec4..58292d7 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -37,6 +37,25 @@ static const char* context_to_name(void* ptr) {
return "NULL";
}
+static const AVOption *opt_find(void *obj, const char *name, const char *unit,
int opt_flags, int search_flags)
+{
+ AVCodecContext *s = obj;
+ AVCodec *c = NULL;
+
+ if (s->priv_data) {
+ if (s->codec->priv_class)
+ return avopt_find(s->priv_data, name, unit, opt_flags,
search_flags);
+ return NULL;
+ }
+
+ while ((c = av_codec_next(c))) {
+ const AVOption *o;
+ if (c->priv_class && (o = avopt_find(&c->priv_class, name, unit,
opt_flags, search_flags)))
+ return o;
+ }
+ return NULL;
+}
+
#define OFFSET(x) offsetof(AVCodecContext,x)
#define DEFAULT 0 //should be NAN but it does not work as it is not a constant
in glibc as required by ANSI/ISO C
//these names are too long to be readable
@@ -457,7 +476,7 @@ static const AVOption options[]={
#undef D
#undef DEFAULT
-static const AVClass av_codec_context_class = { "AVCodecContext",
context_to_name, options, LIBAVUTIL_VERSION_INT, OFFSET(log_level_offset) };
+static const AVClass av_codec_context_class = { "AVCodecContext",
context_to_name, options, LIBAVUTIL_VERSION_INT, OFFSET(log_level_offset),
.opt_find = opt_find};
void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType
codec_type){
int flags=0;
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 9e87994..dc21d96 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -32,6 +32,7 @@
#include "libavutil/audioconvert.h"
#include "libavutil/imgutils.h"
#include "libavutil/samplefmt.h"
+#include "libavutil/meta.h"
#include "avcodec.h"
#include "dsputil.h"
#include "libavutil/opt.h"
@@ -463,7 +464,16 @@ AVFrame *avcodec_alloc_frame(void){
int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec)
{
+ return avcodec_open2(avctx, codec, NULL);
+}
+
+int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec,
AVMetadata **options)
+{
int ret = 0;
+ AVMetadata *tmp = NULL;
+
+ if (options)
+ avmeta_copy(&tmp, *options, 0);
/* If there is a user-supplied mutex locking routine, call it. */
if (ff_lockmgr_cb) {
@@ -490,14 +500,18 @@ int attribute_align_arg avcodec_open(AVCodecContext
*avctx, AVCodec *codec)
ret = AVERROR(ENOMEM);
goto end;
}
- if(codec->priv_class){ //this can be droped once all user apps use
avcodec_get_context_defaults3()
+ if (codec->priv_class) {
*(AVClass**)avctx->priv_data= codec->priv_class;
av_opt_set_defaults(avctx->priv_data);
+ if ((ret = avopt_process(avctx->priv_data, &tmp)) < 0)
+ goto free_and_end;
}
}
} else {
avctx->priv_data = NULL;
}
+ if ((ret = avopt_process(avctx, &tmp)) < 0)
+ goto free_and_end;
if(avctx->coded_width && avctx->coded_height)
avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height);
@@ -609,6 +623,11 @@ end:
if (ff_lockmgr_cb) {
(*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
}
+ if (options) {
+ avmeta_free(options);
+ *options = tmp;
+ }
+
return ret;
free_and_end:
av_freep(&avctx->priv_data);
--
1.7.5.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel