summaryrefslogtreecommitdiffstats
path: root/vlc/build/ffmpeg-0.6.1_libvpx-0.9.2-3.diff
blob: 2746b2ea39bcf4ed34a1914e435dbddc627aa7cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
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