diff options
author | Eric Hameleers <alien@slackware.com> | 2010-12-30 21:27:22 +0000 |
---|---|---|
committer | Eric Hameleers <alien@slackware.com> | 2010-12-30 21:27:22 +0000 |
commit | f330922d9c84de31ab27cf1d8e149f99e7d4299e (patch) | |
tree | b38e75a4c4072018d869b94e2524ae42690cf882 /vlc/build/ffmpeg-0.6.1_libvpx-0.9.2-3.diff | |
parent | 1c22b469b8776b2cd915a1931c592404d7ea6ae0 (diff) | |
download | asb-f330922d9c84de31ab27cf1d8e149f99e7d4299e.tar.gz asb-f330922d9c84de31ab27cf1d8e149f99e7d4299e.tar.xz |
Initial revision
Diffstat (limited to 'vlc/build/ffmpeg-0.6.1_libvpx-0.9.2-3.diff')
-rw-r--r-- | vlc/build/ffmpeg-0.6.1_libvpx-0.9.2-3.diff | 760 |
1 files changed, 760 insertions, 0 deletions
diff --git a/vlc/build/ffmpeg-0.6.1_libvpx-0.9.2-3.diff b/vlc/build/ffmpeg-0.6.1_libvpx-0.9.2-3.diff new file mode 100644 index 00000000..2746b2ea --- /dev/null +++ b/vlc/build/ffmpeg-0.6.1_libvpx-0.9.2-3.diff @@ -0,0 +1,760 @@ +diff --git a/cmdutils.c b/cmdutils.c +index 2349b70..8f7ad3e 100644 +--- a/cmdutils.c ++++ b/cmdutils.c +@@ -47,6 +47,7 @@ + #endif + + const char **opt_names; ++const char **opt_values; + static int opt_name_count; + AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; + AVFormatContext *avformat_opts; +@@ -213,15 +214,25 @@ int opt_default(const char *opt, const char *arg){ + exit(1); + } + if (!o) { ++ AVCodec *p = NULL; ++ while ((p=av_codec_next(p))){ ++ AVClass *c= p->priv_class; ++ if(c && av_find_opt(&c, opt, NULL, 0, 0)) ++ break; ++ } ++ if(!p){ + fprintf(stderr, "Unrecognized option '%s'\n", opt); + exit(1); ++ } + } + + // av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL)); + + //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this ++ opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1)); ++ opt_values[opt_name_count]= o ? NULL : arg; + opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1)); +- opt_names[opt_name_count++]= o->name; ++ opt_names[opt_name_count++]= o ? o->name : opt; + + if(avcodec_opts[0]->debug || avformat_opts->debug) + av_log_set_level(AV_LOG_DEBUG); +@@ -276,9 +287,16 @@ int opt_timelimit(const char *opt, const char *arg) + return 0; + } + +-void set_context_opts(void *ctx, void *opts_ctx, int flags) ++void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec) + { + int i; ++ void *priv_ctx=NULL; ++ if(!strcmp("AVCodecContext", (*(AVClass**)ctx)->class_name)){ ++ AVCodecContext *avctx= ctx; ++ if(codec && codec->priv_class && avctx->priv_data){ ++ priv_ctx= avctx->priv_data; ++ } ++ } + for(i=0; i<opt_name_count; i++){ + char buf[256]; + const AVOption *opt; +@@ -286,6 +304,12 @@ void set_context_opts(void *ctx, void *opts_ctx, int flags) + /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */ + if(str && ((opt->flags & flags) == flags)) + av_set_string3(ctx, opt_names[i], str, 1, NULL); ++ /* We need to use a differnt system to pass options to the private context because ++ it is not known which codec and thus context kind that will be when parsing options ++ we thus use opt_values directly instead of opts_ctx */ ++ if(!str && priv_ctx && av_get_string(priv_ctx, opt_names[i], &opt, buf, sizeof(buf))){ ++ av_set_string3(priv_ctx, opt_names[i], opt_values[i], 1, NULL); ++ } + } + } + +diff --git a/cmdutils.h b/cmdutils.h +index 5656370..011d84b 100644 +--- a/cmdutils.h ++++ b/cmdutils.h +@@ -132,7 +132,7 @@ void show_help_options(const OptionDef *options, const char *msg, int mask, int + void parse_options(int argc, char **argv, const OptionDef *options, + void (* parse_arg_function)(const char*)); + +-void set_context_opts(void *ctx, void *opts_ctx, int flags); ++void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec); + + /** + * Prints an error message to stderr, indicating filename and a human +diff --git a/ffmpeg.c b/ffmpeg.c +index 6b9380f..c386430 100644 +--- a/ffmpeg.c ++++ b/ffmpeg.c +@@ -2988,7 +2988,7 @@ static void opt_input_file(const char *filename) + ap->channel = video_channel; + ap->standard = video_standard; + +- set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM); ++ set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL); + + ic->video_codec_id = + find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0, +@@ -3063,45 +3063,46 @@ static void opt_input_file(const char *filename) + /* update the current parameters so that they match the one of the input stream */ + for(i=0;i<ic->nb_streams;i++) { + AVStream *st = ic->streams[i]; +- AVCodecContext *enc = st->codec; +- avcodec_thread_init(enc, thread_count); +- switch(enc->codec_type) { ++ AVCodecContext *dec = st->codec; ++ avcodec_thread_init(dec, thread_count); ++ switch (dec->codec_type) { + case AVMEDIA_TYPE_AUDIO: +- set_context_opts(enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM); +- //fprintf(stderr, "\nInput Audio channels: %d", enc->channels); +- channel_layout = enc->channel_layout; +- audio_channels = enc->channels; +- audio_sample_rate = enc->sample_rate; +- audio_sample_fmt = enc->sample_fmt; + input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(audio_codec_name); ++ set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_icodecs-1]); ++ //fprintf(stderr, "\nInput Audio channels: %d", dec->channels); ++ channel_layout = dec->channel_layout; ++ audio_channels = dec->channels; ++ audio_sample_rate = dec->sample_rate; ++ audio_sample_fmt = dec->sample_fmt; + if(audio_disable) + st->discard= AVDISCARD_ALL; + break; + case AVMEDIA_TYPE_VIDEO: +- set_context_opts(enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM); +- frame_height = enc->height; +- frame_width = enc->width; ++ input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(video_codec_name); ++ set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_icodecs-1]); ++ frame_height = dec->height; ++ frame_width = dec->width; + if(ic->streams[i]->sample_aspect_ratio.num) + frame_aspect_ratio=av_q2d(ic->streams[i]->sample_aspect_ratio); + else +- frame_aspect_ratio=av_q2d(enc->sample_aspect_ratio); +- frame_aspect_ratio *= (float) enc->width / enc->height; +- frame_pix_fmt = enc->pix_fmt; ++ frame_aspect_ratio=av_q2d(dec->sample_aspect_ratio); ++ frame_aspect_ratio *= (float) dec->width / dec->height; ++ frame_pix_fmt = dec->pix_fmt; + rfps = ic->streams[i]->r_frame_rate.num; + rfps_base = ic->streams[i]->r_frame_rate.den; +- if(enc->lowres) { +- enc->flags |= CODEC_FLAG_EMU_EDGE; +- frame_height >>= enc->lowres; +- frame_width >>= enc->lowres; ++ if (dec->lowres) { ++ dec->flags |= CODEC_FLAG_EMU_EDGE; ++ frame_height >>= dec->lowres; ++ frame_width >>= dec->lowres; + } + if(me_threshold) +- enc->debug |= FF_DEBUG_MV; ++ dec->debug |= FF_DEBUG_MV; + +- if (enc->time_base.den != rfps*enc->ticks_per_frame || enc->time_base.num != rfps_base) { ++ if (dec->time_base.den != rfps*dec->ticks_per_frame || dec->time_base.num != rfps_base) { + + if (verbose >= 0) + fprintf(stderr,"\nSeems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d)\n", +- i, (float)enc->time_base.den / enc->time_base.num, enc->time_base.den, enc->time_base.num, ++ i, (float)dec->time_base.den / dec->time_base.num, dec->time_base.den, dec->time_base.num, + + (float)rfps / rfps_base, rfps, rfps_base); + } +@@ -3109,7 +3110,6 @@ static void opt_input_file(const char *filename) + frame_rate.num = rfps; + frame_rate.den = rfps_base; + +- input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(video_codec_name); + if(video_disable) + st->discard= AVDISCARD_ALL; + else if(video_discard) +@@ -3188,13 +3188,27 @@ static void new_video_stream(AVFormatContext *oc) + AVStream *st; + AVCodecContext *video_enc; + enum CodecID codec_id; ++ AVCodec *codec= NULL; + + st = av_new_stream(oc, oc->nb_streams); + if (!st) { + fprintf(stderr, "Could not alloc stream\n"); + av_exit(1); + } +- avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_VIDEO); ++ ++ if(!video_stream_copy){ ++ if (video_codec_name) { ++ codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1, ++ avcodec_opts[AVMEDIA_TYPE_VIDEO]->strict_std_compliance); ++ codec = avcodec_find_encoder_by_name(video_codec_name); ++ output_codecs[nb_ocodecs] = codec; ++ } else { ++ codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); ++ codec = avcodec_find_encoder(codec_id); ++ } ++ } ++ ++ avcodec_get_context_defaults3(st->codec, codec); + bitstream_filters[nb_output_files][oc->nb_streams - 1]= video_bitstream_filters; + video_bitstream_filters= NULL; + +@@ -3223,22 +3237,10 @@ static void new_video_stream(AVFormatContext *oc) + } else { + const char *p; + int i; +- AVCodec *codec; + AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1}; + +- if (video_codec_name) { +- codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1, +- video_enc->strict_std_compliance); +- codec = avcodec_find_encoder_by_name(video_codec_name); +- output_codecs[nb_ocodecs] = codec; +- } else { +- codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); +- codec = avcodec_find_encoder(codec_id); +- } +- + video_enc->codec_id = codec_id; +- +- set_context_opts(video_enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM); ++ set_context_opts(video_enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec); + + if (codec && codec->supported_framerates && !force_fps) + fps = codec->supported_framerates[av_find_nearest_q_idx(fps, codec->supported_framerates)]; +@@ -3324,6 +3326,7 @@ static void new_video_stream(AVFormatContext *oc) + static void new_audio_stream(AVFormatContext *oc) + { + AVStream *st; ++ AVCodec *codec= NULL; + AVCodecContext *audio_enc; + enum CodecID codec_id; + +@@ -3332,7 +3335,20 @@ static void new_audio_stream(AVFormatContext *oc) + fprintf(stderr, "Could not alloc stream\n"); + av_exit(1); + } +- avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_AUDIO); ++ ++ if(!audio_stream_copy){ ++ if (audio_codec_name) { ++ codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1, ++ avcodec_opts[AVMEDIA_TYPE_AUDIO]->strict_std_compliance); ++ codec = avcodec_find_encoder_by_name(audio_codec_name); ++ output_codecs[nb_ocodecs] = codec; ++ } else { ++ codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO); ++ codec = avcodec_find_encoder(codec_id); ++ } ++ } ++ ++ avcodec_get_context_defaults3(st->codec, codec); + + bitstream_filters[nb_output_files][oc->nb_streams - 1]= audio_bitstream_filters; + audio_bitstream_filters= NULL; +@@ -3354,20 +3370,8 @@ static void new_audio_stream(AVFormatContext *oc) + audio_enc->channels = audio_channels; + audio_enc->sample_rate = audio_sample_rate; + } else { +- AVCodec *codec; +- +- set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM); +- +- if (audio_codec_name) { +- codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1, +- audio_enc->strict_std_compliance); +- codec = avcodec_find_encoder_by_name(audio_codec_name); +- output_codecs[nb_ocodecs] = codec; +- } else { +- codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO); +- codec = avcodec_find_encoder(codec_id); +- } + audio_enc->codec_id = codec_id; ++ set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec); + + if (audio_qscale > QSCALE_NONE) { + audio_enc->flags |= CODEC_FLAG_QSCALE; +@@ -3398,6 +3402,7 @@ static void new_audio_stream(AVFormatContext *oc) + static void new_subtitle_stream(AVFormatContext *oc) + { + AVStream *st; ++ AVCodec *codec=NULL; + AVCodecContext *subtitle_enc; + + st = av_new_stream(oc, oc->nb_streams); +@@ -3405,12 +3410,17 @@ static void new_subtitle_stream(AVFormatContext *oc) + fprintf(stderr, "Could not alloc stream\n"); + av_exit(1); + } +- avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_SUBTITLE); ++ subtitle_enc = st->codec; ++ if(!subtitle_stream_copy){ ++ subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1, ++ avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance); ++ codec= output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name); ++ } ++ avcodec_get_context_defaults3(st->codec, codec); + + bitstream_filters[nb_output_files][oc->nb_streams - 1]= subtitle_bitstream_filters; + subtitle_bitstream_filters= NULL; + +- subtitle_enc = st->codec; + subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE; + + if(subtitle_codec_tag) +@@ -3419,10 +3429,7 @@ static void new_subtitle_stream(AVFormatContext *oc) + if (subtitle_stream_copy) { + st->stream_copy = 1; + } else { +- set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM); +- subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1, +- subtitle_enc->strict_std_compliance); +- output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name); ++ set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec); + } + nb_ocodecs++; + +@@ -3615,7 +3622,7 @@ static void opt_output_file(const char *filename) + oc->loop_output = loop_output; + oc->flags |= AVFMT_FLAG_NONBLOCK; + +- set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM); ++ set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL); + } + + /* same option as mencoder */ +diff --git a/ffplay.c b/ffplay.c +index e79e17b..9c58940 100644 +--- a/ffplay.c ++++ b/ffplay.c +@@ -2206,7 +2206,7 @@ static int stream_component_open(VideoState *is, int stream_index) + avctx->error_concealment= error_concealment; + avcodec_thread_init(avctx, thread_count); + +- set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0); ++ set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0, codec); + + if (!codec || + avcodec_open(avctx, codec) < 0) +@@ -2384,7 +2384,7 @@ static int decode_thread(void *arg) + ap->time_base= (AVRational){1, 25}; + ap->pix_fmt = frame_pix_fmt; + +- set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM); ++ set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL); + + err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap); + if (err < 0) { +diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h +index 974e87c..6a6f2a7 100644 +--- a/libavcodec/avcodec.h ++++ b/libavcodec/avcodec.h +@@ -30,7 +30,7 @@ + #include "libavutil/avutil.h" + + #define LIBAVCODEC_VERSION_MAJOR 52 +-#define LIBAVCODEC_VERSION_MINOR 72 ++#define LIBAVCODEC_VERSION_MINOR 73 + #define LIBAVCODEC_VERSION_MICRO 2 + + #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ +@@ -2652,6 +2652,15 @@ typedef struct AVCodecContext { + * - decoding: unused + */ + int rc_lookahead; ++ ++ /** ++ * Number of slices. ++ * Indicates number of picture subdivisions. Used for parallelized ++ * decoding. ++ * - encoding: Set by user ++ * - decoding: unused ++ */ ++ int slices; + } AVCodecContext; + + /** +@@ -2693,6 +2702,7 @@ typedef struct AVCodec { + const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 + const enum SampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 + const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 ++ AVClass *priv_class; ///< AVClass for the private context + } AVCodec; + + /** +@@ -3327,6 +3337,10 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); + void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, + int linesize_align[4]); + ++/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! ++ * we WILL change its arguments and name a few times! */ ++int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec); ++ + /** + * Checks if the given dimension of a picture is valid, meaning that all + * bytes of the picture can be addressed with a signed int. +@@ -3344,6 +3358,10 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v + int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); + //FIXME func typedef + ++/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! ++ * we WILL change its arguments and name a few times! */ ++AVCodecContext *avcodec_alloc_context3(AVCodec *codec); ++ + /** + * Initializes the AVCodecContext to use the given AVCodec. Prior to using this + * function the context has to be allocated. +diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c +index fa393b8..37b51b2 100644 +--- a/libavcodec/libvpxenc.c ++++ b/libavcodec/libvpxenc.c +@@ -30,19 +30,20 @@ + + #include "avcodec.h" + #include "libavutil/base64.h" ++#include "libavcodec/opt.h" + + /** + * Portion of struct vpx_codec_cx_pkt from vpx_encoder.h. + * One encoded frame returned from the library. + */ + struct FrameListData { +- void *buf; /**≤ compressed data buffer */ +- size_t sz; /**≤ length of compressed data */ +- int64_t pts; /**≤ time stamp to show frame ++ void *buf; /**< compressed data buffer */ ++ size_t sz; /**< length of compressed data */ ++ int64_t pts; /**< time stamp to show frame + (in timebase units) */ +- unsigned long duration; /**≤ duration to show frame ++ unsigned long duration; /**< duration to show frame + (in timebase units) */ +- uint32_t flags; /**≤ flags for this frame */ ++ uint32_t flags; /**< flags for this frame */ + struct FrameListData *next; + }; + +@@ -50,10 +51,32 @@ typedef struct VP8EncoderContext { + struct vpx_codec_ctx encoder; + struct vpx_image rawimg; + struct vpx_fixed_buf twopass_stats; +- unsigned long deadline; //i.e., RT/GOOD/BEST ++ int deadline; //i.e., RT/GOOD/BEST + struct FrameListData *coded_frame_list; ++ ++ int cpuused; ++ ++ /** ++ * VP8 specific flags, see VP8F_* below. ++ */ ++ int flags; ++#define VP8F_ERROR_RESILIENT 0x00000001 ///< Enable measures appropriate for streaming over lossy links ++#define VP8F_AUTO_ALT_REF 0x00000002 ///< Enable automatic alternate reference frame generation + } VP8Context; + ++static const AVOption options[]={ ++{"speed", "", offsetof(VP8Context, cpuused), FF_OPT_TYPE_INT, 3, -16, 16, AV_OPT_FLAG_ENCODING_PARAM}, ++{"quality", "", offsetof(VP8Context, deadline), FF_OPT_TYPE_INT, VPX_DL_GOOD_QUALITY, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "quality"}, ++{"best", NULL, 0, FF_OPT_TYPE_CONST, VPX_DL_BEST_QUALITY, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "quality"}, ++{"good", NULL, 0, FF_OPT_TYPE_CONST, VPX_DL_GOOD_QUALITY, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "quality"}, ++{"realtime", NULL, 0, FF_OPT_TYPE_CONST, VPX_DL_REALTIME, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "quality"}, ++{"vp8flags", "", offsetof(VP8Context, flags), FF_OPT_TYPE_FLAGS, 0, 0, UINT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flags"}, ++{"error_resilient", "enable error resilience", 0, FF_OPT_TYPE_CONST, VP8F_ERROR_RESILIENT, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flags"}, ++{"altref", "enable use of alternate reference frames (VP8/2-pass only)", 0, FF_OPT_TYPE_CONST, VP8F_AUTO_ALT_REF, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flags"}, ++{NULL} ++}; ++static const AVClass class = { "libvpx", av_default_item_name, options, LIBAVUTIL_VERSION_INT }; ++ + /** String mappings for enum vp8e_enc_control_id */ + static const char *ctlidstr[] = { + [VP8E_UPD_ENTROPY] = "VP8E_UPD_ENTROPY", +@@ -204,7 +227,6 @@ static av_cold int vp8_init(AVCodecContext *avctx) + { + VP8Context *ctx = avctx->priv_data; + const struct vpx_codec_iface *iface = &vpx_codec_vp8_cx_algo; +- int cpuused = 3; + struct vpx_codec_enc_cfg enccfg; + int res; + +@@ -218,11 +240,21 @@ static av_cold int vp8_init(AVCodecContext *avctx) + } + dump_enc_cfg(avctx, &enccfg); + ++ /* With altref set an additional frame at the same pts may be produced. ++ Increasing the time_base gives the library a window to place these frames ++ ensuring strictly increasing timestamps. */ ++ if (ctx->flags & VP8F_AUTO_ALT_REF) { ++ avctx->ticks_per_frame = 2; ++ avctx->time_base = av_mul_q(avctx->time_base, ++ (AVRational){1, avctx->ticks_per_frame}); ++ } ++ + enccfg.g_w = avctx->width; + enccfg.g_h = avctx->height; + enccfg.g_timebase.num = avctx->time_base.num; + enccfg.g_timebase.den = avctx->time_base.den; + enccfg.g_threads = avctx->thread_count; ++ enccfg.g_lag_in_frames= FFMIN(avctx->rc_lookahead, 25); //0-25, avoids init failure + + if (avctx->flags & CODEC_FLAG_PASS1) + enccfg.g_pass = VPX_RC_FIRST_PASS; +@@ -240,11 +272,27 @@ static av_cold int vp8_init(AVCodecContext *avctx) + //convert [1,51] -> [0,63] + enccfg.rc_min_quantizer = ((avctx->qmin * 5 + 1) >> 2) - 1; + enccfg.rc_max_quantizer = ((avctx->qmax * 5 + 1) >> 2) - 1; +- ++ enccfg.rc_dropframe_thresh = avctx->frame_skip_threshold; ++ ++ //0-100 (0 => CBR, 100 => VBR) ++ enccfg.rc_2pass_vbr_bias_pct = round(avctx->qcompress * 100); ++ enccfg.rc_2pass_vbr_minsection_pct = ++ avctx->rc_min_rate * 100LL / avctx->bit_rate; ++ if (avctx->rc_max_rate) ++ enccfg.rc_2pass_vbr_maxsection_pct = ++ avctx->rc_max_rate * 100LL / avctx->bit_rate; ++ ++ if (avctx->rc_buffer_size) ++ enccfg.rc_buf_sz = ++ avctx->rc_buffer_size * 1000LL / avctx->bit_rate; ++ if (avctx->rc_initial_buffer_occupancy) ++ enccfg.rc_buf_initial_sz = ++ avctx->rc_initial_buffer_occupancy * 1000LL / avctx->bit_rate; ++ enccfg.rc_buf_optimal_sz = enccfg.rc_buf_sz * 5 / 6; ++ enccfg.rc_undershoot_pct = round(avctx->rc_buffer_aggressivity * 100); ++ ++ //_enc_init() will balk if kf_min_dist differs from max w/VPX_KF_AUTO + if (avctx->keyint_min == avctx->gop_size) +- enccfg.kf_mode = VPX_KF_FIXED; +- //_enc_init() will balk if kf_min_dist is set in this case +- if (enccfg.kf_mode != VPX_KF_AUTO) + enccfg.kf_min_dist = avctx->keyint_min; + enccfg.kf_max_dist = avctx->gop_size; + +@@ -277,7 +325,13 @@ static av_cold int vp8_init(AVCodecContext *avctx) + enccfg.rc_twopass_stats_in = ctx->twopass_stats; + } + +- ctx->deadline = VPX_DL_GOOD_QUALITY; ++ /* 0-3: For non-zero values the encoder increasingly optimizes for reduced ++ complexity playback on low powered devices at the expense of encode ++ quality. */ ++ if (avctx->profile != FF_PROFILE_UNKNOWN) ++ enccfg.g_profile = avctx->profile; ++ ++ enccfg.g_error_resilient = ctx->flags & VP8F_ERROR_RESILIENT; + + dump_enc_cfg(avctx, &enccfg); + /* Construct Encoder Context */ +@@ -289,8 +343,12 @@ static av_cold int vp8_init(AVCodecContext *avctx) + + //codec control failures are currently treated only as warnings + av_log(avctx, AV_LOG_DEBUG, "vpx_codec_control\n"); +- codecctl_int(avctx, VP8E_SET_CPUUSED, cpuused); ++ codecctl_int(avctx, VP8E_SET_CPUUSED, ctx->cpuused); + codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction); ++ codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS, av_log2(avctx->slices)); ++ codecctl_int(avctx, VP8E_SET_ENABLEAUTOALTREF, !!(ctx->flags & VP8F_AUTO_ALT_REF)); ++ ++ av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline); + + //provide dummy value to initialize wrapper, values will be updated each _encode() + vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1, +@@ -486,4 +544,5 @@ AVCodec libvpx_encoder = { + CODEC_CAP_DELAY, + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"), ++ .priv_class= &class, + }; +diff --git a/libavcodec/options.c b/libavcodec/options.c +index 97d705e..73dcb85 100644 +--- a/libavcodec/options.c ++++ b/libavcodec/options.c +@@ -411,6 +411,7 @@ static const AVOption options[]={ + {"aq_strength", "specify aq strength", OFFSET(aq_strength), FF_OPT_TYPE_FLOAT, 1.0, 0, FLT_MAX, V|E}, + {"rc_lookahead", "specify number of frames to look ahead for frametype", OFFSET(rc_lookahead), FF_OPT_TYPE_INT, 40, 0, INT_MAX, V|E}, + {"ssim", "ssim will be calculated during encoding", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_SSIM, INT_MIN, INT_MAX, V|E, "flags2"}, ++{"slices", "number of slices, used in parallelized decoding", OFFSET(slices), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|E}, + {NULL}, + }; + +@@ -453,6 +454,36 @@ void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_typ + s->reordered_opaque= AV_NOPTS_VALUE; + } + ++int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){ ++ avcodec_get_context_defaults2(s, codec ? codec->type : AVMEDIA_TYPE_UNKNOWN); ++ if(codec && codec->priv_data_size){ ++ if(!s->priv_data){ ++ s->priv_data= av_mallocz(codec->priv_data_size); ++ if (!s->priv_data) { ++ return AVERROR(ENOMEM); ++ } ++ } ++ if(codec->priv_class){ ++ *(AVClass**)s->priv_data= codec->priv_class; ++ av_opt_set_defaults(s->priv_data); ++ } ++ } ++ return 0; ++} ++ ++AVCodecContext *avcodec_alloc_context3(AVCodec *codec){ ++ AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); ++ ++ if(avctx==NULL) return NULL; ++ ++ if(avcodec_get_context_defaults3(avctx, codec) < 0){ ++ av_free(avctx); ++ return NULL; ++ } ++ ++ return avctx; ++} ++ + AVCodecContext *avcodec_alloc_context2(enum AVMediaType codec_type){ + AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); + +diff --git a/libavcodec/utils.c b/libavcodec/utils.c +index 014427d..99e754e 100644 +--- a/libavcodec/utils.c ++++ b/libavcodec/utils.c +@@ -479,11 +479,17 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) + goto end; + + if (codec->priv_data_size > 0) { ++ if(!avctx->priv_data){ + avctx->priv_data = av_mallocz(codec->priv_data_size); + if (!avctx->priv_data) { + ret = AVERROR(ENOMEM); + goto end; + } ++ if(codec->priv_class){ //this can be droped once all user apps use avcodec_get_context_defaults3() ++ *(AVClass**)avctx->priv_data= codec->priv_class; ++ av_opt_set_defaults(avctx->priv_data); ++ } ++ } + } else { + avctx->priv_data = NULL; + } +diff --git a/libavutil/log.c b/libavutil/log.c +index 9a8b66e..f1501c5 100644 +--- a/libavutil/log.c ++++ b/libavutil/log.c +@@ -55,6 +55,10 @@ static void colored_fputs(int color, const char *str){ + } + } + ++const char* av_default_item_name(void* ptr){ ++ return (*(AVClass**)ptr)->class_name; ++} ++ + void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) + { + static int print_prefix=1; +diff --git a/libavutil/log.h b/libavutil/log.h +index 1c3e490..cf61f0c 100644 +--- a/libavutil/log.h ++++ b/libavutil/log.h +@@ -119,5 +119,6 @@ int av_log_get_level(void); + void av_log_set_level(int); + void av_log_set_callback(void (*)(void*, int, const char*, va_list)); + void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl); ++const char* av_default_item_name(void* ctx); + + #endif /* AVUTIL_LOG_H */ +Index: ffpresets/libvpx-720p50_60.ffpreset +=================================================================== +--- ffpresets/libvpx-720p50_60.ffpreset (revision 0) ++++ ffpresets/libvpx-720p50_60.ffpreset (revision 0) +@@ -0,0 +1,14 @@ ++vcodec=libvpx ++g=120 ++rc_lookahead=25 ++quality=good ++speed=0 ++profile=0 ++qmax=51 ++qmin=11 ++slices=4 ++vb=2M ++ ++#ignored unless using -pass 2 ++maxrate=24M ++minrate=100k +Index: ffpresets/libvpx-1080p.ffpreset +=================================================================== +--- ffpresets/libvpx-1080p.ffpreset (revision 0) ++++ ffpresets/libvpx-1080p.ffpreset (revision 0) +@@ -0,0 +1,14 @@ ++vcodec=libvpx ++g=120 ++rc_lookahead=16 ++quality=good ++speed=0 ++profile=1 ++qmax=51 ++qmin=11 ++slices=4 ++vb=2M ++ ++#ignored unless using -pass 2 ++maxrate=24M ++minrate=100k +Index: ffpresets/libvpx-1080p50_60.ffpreset +=================================================================== +--- ffpresets/libvpx-1080p50_60.ffpreset (revision 0) ++++ ffpresets/libvpx-1080p50_60.ffpreset (revision 0) +@@ -0,0 +1,14 @@ ++vcodec=libvpx ++g=120 ++rc_lookahead=25 ++quality=good ++speed=0 ++profile=1 ++qmax=51 ++qmin=11 ++slices=4 ++vb=2M ++ ++#ignored unless using -pass 2 ++maxrate=24M ++minrate=100k +Index: ffpresets/libvpx-360p.ffpreset +=================================================================== +--- ffpresets/libvpx-360p.ffpreset (revision 0) ++++ ffpresets/libvpx-360p.ffpreset (revision 0) +@@ -0,0 +1,13 @@ ++vcodec=libvpx ++g=120 ++rc_lookahead=16 ++quality=good ++speed=0 ++profile=0 ++qmax=63 ++qmin=0 ++vb=768k ++ ++#ignored unless using -pass 2 ++maxrate=1.5M ++minrate=40k +Index: ffpresets/libvpx-720p.ffpreset +=================================================================== +--- ffpresets/libvpx-720p.ffpreset (revision 0) ++++ ffpresets/libvpx-720p.ffpreset (revision 0) +@@ -0,0 +1,14 @@ ++vcodec=libvpx ++g=120 ++rc_lookahead=16 ++quality=good ++speed=0 ++profile=0 ++qmax=51 ++qmin=11 ++slices=4 ++vb=2M ++ ++#ignored unless using -pass 2 ++maxrate=24M ++minrate=100k |