Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / third_party / libvpx / source / libvpx / vp8_scalable_patterns.c
1 /*
2  *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11
12 /*
13  * This is an example demonstrating how to implement a multi-layer VP8
14  * encoding scheme based on temporal scalability for video applications
15  * that benefit from a scalable bitstream.
16  */
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdarg.h>
20 #include <string.h>
21 #define VPX_CODEC_DISABLE_COMPAT 1
22 #include "vpx/vpx_encoder.h"
23 #include "vpx/vp8cx.h"
24 #define interface (vpx_codec_vp8_cx())
25 #define fourcc    0x30385056
26
27 #define IVF_FILE_HDR_SZ  (32)
28 #define IVF_FRAME_HDR_SZ (12)
29
30 static void mem_put_le16(char *mem, unsigned int val) {
31     mem[0] = val;
32     mem[1] = val>>8;
33 }
34
35 static void mem_put_le32(char *mem, unsigned int val) {
36     mem[0] = val;
37     mem[1] = val>>8;
38     mem[2] = val>>16;
39     mem[3] = val>>24;
40 }
41
42 static void die(const char *fmt, ...) {
43     va_list ap;
44
45     va_start(ap, fmt);
46     vprintf(fmt, ap);
47     if(fmt[strlen(fmt)-1] != '\n')
48         printf("\n");
49     exit(EXIT_FAILURE);
50 }
51
52 static void die_codec(vpx_codec_ctx_t *ctx, const char *s) {
53     const char *detail = vpx_codec_error_detail(ctx);
54
55     printf("%s: %s\n", s, vpx_codec_error(ctx));
56     if(detail)
57         printf("    %s\n",detail);
58     exit(EXIT_FAILURE);
59 }
60
61 static int read_frame(FILE *f, vpx_image_t *img) {
62     size_t nbytes, to_read;
63     int    res = 1;
64
65     to_read = img->w*img->h*3/2;
66     nbytes = fread(img->planes[0], 1, to_read, f);
67     if(nbytes != to_read) {
68         res = 0;
69         if(nbytes > 0)
70             printf("Warning: Read partial frame. Check your width & height!\n");
71     }
72     return res;
73 }
74
75 static void write_ivf_file_header(FILE *outfile,
76                                   const vpx_codec_enc_cfg_t *cfg,
77                                   int frame_cnt) {
78     char header[32];
79
80     if(cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS)
81         return;
82     header[0] = 'D';
83     header[1] = 'K';
84     header[2] = 'I';
85     header[3] = 'F';
86     mem_put_le16(header+4,  0);                   /* version */
87     mem_put_le16(header+6,  32);                  /* headersize */
88     mem_put_le32(header+8,  fourcc);              /* headersize */
89     mem_put_le16(header+12, cfg->g_w);            /* width */
90     mem_put_le16(header+14, cfg->g_h);            /* height */
91     mem_put_le32(header+16, cfg->g_timebase.den); /* rate */
92     mem_put_le32(header+20, cfg->g_timebase.num); /* scale */
93     mem_put_le32(header+24, frame_cnt);           /* length */
94     mem_put_le32(header+28, 0);                   /* unused */
95
96     (void) fwrite(header, 1, 32, outfile);
97 }
98
99
100 static void write_ivf_frame_header(FILE *outfile,
101                                    const vpx_codec_cx_pkt_t *pkt)
102 {
103     char             header[12];
104     vpx_codec_pts_t  pts;
105
106     if(pkt->kind != VPX_CODEC_CX_FRAME_PKT)
107         return;
108
109     pts = pkt->data.frame.pts;
110     mem_put_le32(header, pkt->data.frame.sz);
111     mem_put_le32(header+4, pts&0xFFFFFFFF);
112     mem_put_le32(header+8, pts >> 32);
113
114     (void) fwrite(header, 1, 12, outfile);
115 }
116
117 static int mode_to_num_layers[12] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3};
118
119 int main(int argc, char **argv) {
120     FILE                *infile, *outfile[VPX_TS_MAX_LAYERS];
121     vpx_codec_ctx_t      codec;
122     vpx_codec_enc_cfg_t  cfg;
123     int                  frame_cnt = 0;
124     vpx_image_t          raw;
125     vpx_codec_err_t      res;
126     unsigned int         width;
127     unsigned int         height;
128     int                  frame_avail;
129     int                  got_data;
130     int                  flags = 0;
131     int                  i;
132     int                  pts = 0;              /* PTS starts at 0 */
133     int                  frame_duration = 1;   /* 1 timebase tick per frame */
134
135     int                  layering_mode = 0;
136     int                  frames_in_layer[VPX_TS_MAX_LAYERS] = {0};
137     int                  layer_flags[VPX_TS_MAX_PERIODICITY] = {0};
138     int                  flag_periodicity;
139     int                  max_intra_size_pct;
140
141     /* Check usage and arguments */
142     if (argc < 9)
143         die("Usage: %s <infile> <outfile> <width> <height> <rate_num> "
144             " <rate_den> <mode> <Rate_0> ... <Rate_nlayers-1>\n", argv[0]);
145
146     width  = strtol (argv[3], NULL, 0);
147     height = strtol (argv[4], NULL, 0);
148     if (width < 16 || width%2 || height <16 || height%2)
149         die ("Invalid resolution: %d x %d", width, height);
150
151     if (!sscanf(argv[7], "%d", &layering_mode))
152         die ("Invalid mode %s", argv[7]);
153     if (layering_mode<0 || layering_mode>11)
154         die ("Invalid mode (0..11) %s", argv[7]);
155
156     if (argc != 8+mode_to_num_layers[layering_mode])
157         die ("Invalid number of arguments");
158
159     if (!vpx_img_alloc (&raw, VPX_IMG_FMT_I420, width, height, 32))
160         die ("Failed to allocate image", width, height);
161
162     printf("Using %s\n",vpx_codec_iface_name(interface));
163
164     /* Populate encoder configuration */
165     res = vpx_codec_enc_config_default(interface, &cfg, 0);
166     if(res) {
167         printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
168         return EXIT_FAILURE;
169     }
170
171     /* Update the default configuration with our settings */
172     cfg.g_w = width;
173     cfg.g_h = height;
174
175     /* Timebase format e.g. 30fps: numerator=1, demoninator=30 */
176     if (!sscanf (argv[5], "%d", &cfg.g_timebase.num ))
177         die ("Invalid timebase numerator %s", argv[5]);
178     if (!sscanf (argv[6], "%d", &cfg.g_timebase.den ))
179         die ("Invalid timebase denominator %s", argv[6]);
180
181     for (i=8; i<8+mode_to_num_layers[layering_mode]; i++)
182         if (!sscanf(argv[i], "%ud", &cfg.ts_target_bitrate[i-8]))
183             die ("Invalid data rate %s", argv[i]);
184
185     /* Real time parameters */
186     cfg.rc_dropframe_thresh = 0;
187     cfg.rc_end_usage        = VPX_CBR;
188     cfg.rc_resize_allowed   = 0;
189     cfg.rc_min_quantizer    = 2;
190     cfg.rc_max_quantizer    = 56;
191     cfg.rc_undershoot_pct   = 100;
192     cfg.rc_overshoot_pct    = 15;
193     cfg.rc_buf_initial_sz   = 500;
194     cfg.rc_buf_optimal_sz   = 600;
195     cfg.rc_buf_sz           = 1000;
196
197     /* Enable error resilient mode */
198     cfg.g_error_resilient = 1;
199     cfg.g_lag_in_frames   = 0;
200     cfg.kf_mode           = VPX_KF_DISABLED;
201
202     /* Disable automatic keyframe placement */
203     cfg.kf_min_dist = cfg.kf_max_dist = 3000;
204
205     /* Default setting for bitrate: used in special case of 1 layer (case 0). */
206     cfg.rc_target_bitrate = cfg.ts_target_bitrate[0];
207
208     /* Temporal scaling parameters: */
209     /* NOTE: The 3 prediction frames cannot be used interchangeably due to
210      * differences in the way they are handled throughout the code. The
211      * frames should be allocated to layers in the order LAST, GF, ARF.
212      * Other combinations work, but may produce slightly inferior results.
213      */
214     switch (layering_mode)
215     {
216     case 0:
217     {
218         /* 1-layer */
219        int ids[1] = {0};
220        cfg.ts_number_layers     = 1;
221        cfg.ts_periodicity       = 1;
222        cfg.ts_rate_decimator[0] = 1;
223        memcpy(cfg.ts_layer_id, ids, sizeof(ids));
224
225        flag_periodicity = cfg.ts_periodicity;
226
227        // Update L only.
228        layer_flags[0] = VPX_EFLAG_FORCE_KF  |
229                         VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
230        break;
231     }
232     case 1:
233     {
234         /* 2-layers, 2-frame period */
235         int ids[2] = {0,1};
236         cfg.ts_number_layers     = 2;
237         cfg.ts_periodicity       = 2;
238         cfg.ts_rate_decimator[0] = 2;
239         cfg.ts_rate_decimator[1] = 1;
240         memcpy(cfg.ts_layer_id, ids, sizeof(ids));
241
242         flag_periodicity = cfg.ts_periodicity;
243 #if 1
244         /* 0=L, 1=GF, Intra-layer prediction enabled */
245         layer_flags[0] = VPX_EFLAG_FORCE_KF  |
246                          VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
247                          VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
248         layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
249                          VP8_EFLAG_NO_REF_ARF;
250 #else
251         /* 0=L, 1=GF, Intra-layer prediction disabled */
252         layer_flags[0] = VPX_EFLAG_FORCE_KF  |
253                          VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
254                          VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
255         layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
256                          VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST;
257 #endif
258         break;
259     }
260
261     case 2:
262     {
263         /* 2-layers, 3-frame period */
264         int ids[3] = {0,1,1};
265         cfg.ts_number_layers     = 2;
266         cfg.ts_periodicity       = 3;
267         cfg.ts_rate_decimator[0] = 3;
268         cfg.ts_rate_decimator[1] = 1;
269         memcpy(cfg.ts_layer_id, ids, sizeof(ids));
270
271         flag_periodicity = cfg.ts_periodicity;
272
273         /* 0=L, 1=GF, Intra-layer prediction enabled */
274         layer_flags[0] = VPX_EFLAG_FORCE_KF  |
275                          VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
276                          VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
277         layer_flags[1] =
278         layer_flags[2] = VP8_EFLAG_NO_REF_GF  |
279                          VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
280                                                 VP8_EFLAG_NO_UPD_LAST;
281         break;
282     }
283
284     case 3:
285     {
286         /* 3-layers, 6-frame period */
287         int ids[6] = {0,2,2,1,2,2};
288         cfg.ts_number_layers     = 3;
289         cfg.ts_periodicity       = 6;
290         cfg.ts_rate_decimator[0] = 6;
291         cfg.ts_rate_decimator[1] = 3;
292         cfg.ts_rate_decimator[2] = 1;
293         memcpy(cfg.ts_layer_id, ids, sizeof(ids));
294
295         flag_periodicity = cfg.ts_periodicity;
296
297         /* 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled */
298         layer_flags[0] = VPX_EFLAG_FORCE_KF  |
299                          VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
300                          VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
301         layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
302                                                 VP8_EFLAG_NO_UPD_LAST;
303         layer_flags[1] =
304         layer_flags[2] =
305         layer_flags[4] =
306         layer_flags[5] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
307         break;
308     }
309
310     case 4:
311     {
312         /* 3-layers, 4-frame period */
313         int ids[4] = {0,2,1,2};
314         cfg.ts_number_layers     = 3;
315         cfg.ts_periodicity       = 4;
316         cfg.ts_rate_decimator[0] = 4;
317         cfg.ts_rate_decimator[1] = 2;
318         cfg.ts_rate_decimator[2] = 1;
319         memcpy(cfg.ts_layer_id, ids, sizeof(ids));
320
321         flag_periodicity = cfg.ts_periodicity;
322
323         /* 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled */
324         layer_flags[0] = VPX_EFLAG_FORCE_KF  |
325                          VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
326                          VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
327         layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
328                          VP8_EFLAG_NO_UPD_ARF |
329                          VP8_EFLAG_NO_UPD_LAST;
330         layer_flags[1] =
331         layer_flags[3] = VP8_EFLAG_NO_REF_ARF |
332                          VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
333                          VP8_EFLAG_NO_UPD_ARF;
334         break;
335     }
336
337     case 5:
338     {
339         /* 3-layers, 4-frame period */
340         int ids[4] = {0,2,1,2};
341         cfg.ts_number_layers     = 3;
342         cfg.ts_periodicity       = 4;
343         cfg.ts_rate_decimator[0] = 4;
344         cfg.ts_rate_decimator[1] = 2;
345         cfg.ts_rate_decimator[2] = 1;
346         memcpy(cfg.ts_layer_id, ids, sizeof(ids));
347
348         flag_periodicity = cfg.ts_periodicity;
349
350         /* 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1,
351          * disabled in layer 2
352          */
353         layer_flags[0] = VPX_EFLAG_FORCE_KF  |
354                          VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
355                          VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
356         layer_flags[2] = VP8_EFLAG_NO_REF_ARF |
357                          VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
358         layer_flags[1] =
359         layer_flags[3] = VP8_EFLAG_NO_REF_ARF |
360                          VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
361                          VP8_EFLAG_NO_UPD_ARF;
362         break;
363     }
364
365     case 6:
366     {
367         /* 3-layers, 4-frame period */
368         int ids[4] = {0,2,1,2};
369         cfg.ts_number_layers     = 3;
370         cfg.ts_periodicity       = 4;
371         cfg.ts_rate_decimator[0] = 4;
372         cfg.ts_rate_decimator[1] = 2;
373         cfg.ts_rate_decimator[2] = 1;
374         memcpy(cfg.ts_layer_id, ids, sizeof(ids));
375
376         flag_periodicity = cfg.ts_periodicity;
377
378         /* 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled */
379         layer_flags[0] = VPX_EFLAG_FORCE_KF  |
380                          VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
381                          VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
382         layer_flags[2] = VP8_EFLAG_NO_REF_ARF |
383                          VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
384         layer_flags[1] =
385         layer_flags[3] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
386         break;
387     }
388
389     case 7:
390     {
391         /* NOTE: Probably of academic interest only */
392
393         /* 5-layers, 16-frame period */
394         int ids[16] = {0,4,3,4,2,4,3,4,1,4,3,4,2,4,3,4};
395         cfg.ts_number_layers     = 5;
396         cfg.ts_periodicity       = 16;
397         cfg.ts_rate_decimator[0] = 16;
398         cfg.ts_rate_decimator[1] = 8;
399         cfg.ts_rate_decimator[2] = 4;
400         cfg.ts_rate_decimator[3] = 2;
401         cfg.ts_rate_decimator[4] = 1;
402         memcpy(cfg.ts_layer_id, ids, sizeof(ids));
403
404         flag_periodicity = cfg.ts_periodicity;
405
406         layer_flags[0]  = VPX_EFLAG_FORCE_KF;
407         layer_flags[1]  =
408         layer_flags[3]  =
409         layer_flags[5]  =
410         layer_flags[7]  =
411         layer_flags[9]  =
412         layer_flags[11] =
413         layer_flags[13] =
414         layer_flags[15] = VP8_EFLAG_NO_UPD_LAST |
415                           VP8_EFLAG_NO_UPD_GF   |
416                           VP8_EFLAG_NO_UPD_ARF;
417         layer_flags[2]  =
418         layer_flags[6]  =
419         layer_flags[10] =
420         layer_flags[14] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF;
421         layer_flags[4]  =
422         layer_flags[12] = VP8_EFLAG_NO_REF_LAST |
423                           VP8_EFLAG_NO_UPD_ARF;
424         layer_flags[8]  = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF;
425         break;
426     }
427
428     case 8:
429     {
430         /* 2-layers, with sync point at first frame of layer 1. */
431         int ids[2] = {0,1};
432         cfg.ts_number_layers     = 2;
433         cfg.ts_periodicity       = 2;
434         cfg.ts_rate_decimator[0] = 2;
435         cfg.ts_rate_decimator[1] = 1;
436         memcpy(cfg.ts_layer_id, ids, sizeof(ids));
437
438         flag_periodicity = 8;
439
440         /* 0=L, 1=GF */
441         // ARF is used as predictor for all frames, and is only updated on
442         // key frame. Sync point every 8 frames.
443
444         // Layer 0: predict from L and ARF, update L and G.
445         layer_flags[0] = VPX_EFLAG_FORCE_KF  |
446                          VP8_EFLAG_NO_REF_GF |
447                          VP8_EFLAG_NO_UPD_ARF;
448
449         // Layer 1: sync point: predict from L and ARF, and update G.
450         layer_flags[1] = VP8_EFLAG_NO_REF_GF |
451                          VP8_EFLAG_NO_UPD_LAST |
452                          VP8_EFLAG_NO_UPD_ARF;
453
454         // Layer 0, predict from L and ARF, update L.
455         layer_flags[2] = VP8_EFLAG_NO_REF_GF  |
456                          VP8_EFLAG_NO_UPD_GF  |
457                          VP8_EFLAG_NO_UPD_ARF;
458
459         // Layer 1: predict from L, G and ARF, and update G.
460         layer_flags[3] = VP8_EFLAG_NO_UPD_ARF |
461                          VP8_EFLAG_NO_UPD_LAST |
462                          VP8_EFLAG_NO_UPD_ENTROPY;
463
464         // Layer 0
465         layer_flags[4] = layer_flags[2];
466
467         // Layer 1
468         layer_flags[5] = layer_flags[3];
469
470         // Layer 0
471         layer_flags[6] = layer_flags[4];
472
473         // Layer 1
474         layer_flags[7] = layer_flags[5];
475         break;
476     }
477
478     case 9:
479     {
480         /* 3-layers */
481         // Sync points for layer 1 and 2 every 8 frames.
482
483         int ids[4] = {0,2,1,2};
484         cfg.ts_number_layers     = 3;
485         cfg.ts_periodicity       = 4;
486         cfg.ts_rate_decimator[0] = 4;
487         cfg.ts_rate_decimator[1] = 2;
488         cfg.ts_rate_decimator[2] = 1;
489         memcpy(cfg.ts_layer_id, ids, sizeof(ids));
490
491         flag_periodicity = 8;
492
493         /* 0=L, 1=GF, 2=ARF */
494         layer_flags[0] = VPX_EFLAG_FORCE_KF  |
495                          VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
496                          VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
497         layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
498                          VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
499         layer_flags[2] = VP8_EFLAG_NO_REF_GF   | VP8_EFLAG_NO_REF_ARF |
500                          VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
501         layer_flags[3] =
502         layer_flags[5] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
503         layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
504                          VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
505         layer_flags[6] = VP8_EFLAG_NO_REF_ARF |
506                          VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
507         layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
508                          VP8_EFLAG_NO_UPD_ARF |
509                          VP8_EFLAG_NO_UPD_ENTROPY;
510         break;
511     }
512     case 10:
513     {
514         // 3-layers structure where ARF is used as predictor for all frames,
515         // and is only updated on key frame.
516         // Sync points for layer 1 and 2 every 8 frames.
517
518         int ids[4] = {0,2,1,2};
519         cfg.ts_number_layers     = 3;
520         cfg.ts_periodicity       = 4;
521         cfg.ts_rate_decimator[0] = 4;
522         cfg.ts_rate_decimator[1] = 2;
523         cfg.ts_rate_decimator[2] = 1;
524         memcpy(cfg.ts_layer_id, ids, sizeof(ids));
525
526         flag_periodicity = 8;
527
528         /* 0=L, 1=GF, 2=ARF */
529
530         // Layer 0: predict from L and ARF; update L and G.
531         layer_flags[0] =  VPX_EFLAG_FORCE_KF  |
532                           VP8_EFLAG_NO_UPD_ARF |
533                           VP8_EFLAG_NO_REF_GF;
534
535         // Layer 2: sync point: predict from L and ARF; update none.
536         layer_flags[1] = VP8_EFLAG_NO_REF_GF |
537                          VP8_EFLAG_NO_UPD_GF |
538                          VP8_EFLAG_NO_UPD_ARF |
539                          VP8_EFLAG_NO_UPD_LAST |
540                          VP8_EFLAG_NO_UPD_ENTROPY;
541
542         // Layer 1: sync point: predict from L and ARF; update G.
543         layer_flags[2] = VP8_EFLAG_NO_REF_GF |
544                          VP8_EFLAG_NO_UPD_ARF |
545                          VP8_EFLAG_NO_UPD_LAST;
546
547         // Layer 2: predict from L, G, ARF; update none.
548         layer_flags[3] = VP8_EFLAG_NO_UPD_GF |
549                          VP8_EFLAG_NO_UPD_ARF |
550                          VP8_EFLAG_NO_UPD_LAST |
551                          VP8_EFLAG_NO_UPD_ENTROPY;
552
553         // Layer 0: predict from L and ARF; update L.
554         layer_flags[4] = VP8_EFLAG_NO_UPD_GF |
555                          VP8_EFLAG_NO_UPD_ARF |
556                          VP8_EFLAG_NO_REF_GF;
557
558         // Layer 2: predict from L, G, ARF; update none.
559         layer_flags[5] = layer_flags[3];
560
561         // Layer 1: predict from L, G, ARF; update G.
562         layer_flags[6] = VP8_EFLAG_NO_UPD_ARF |
563                          VP8_EFLAG_NO_UPD_LAST;
564
565         // Layer 2: predict from L, G, ARF; update none.
566         layer_flags[7] = layer_flags[3];
567         break;
568     }
569     case 11:
570     default:
571     {
572        // 3-layers structure as in case 10, but no sync/refresh points for
573        // layer 1 and 2.
574
575        int ids[4] = {0,2,1,2};
576        cfg.ts_number_layers     = 3;
577        cfg.ts_periodicity       = 4;
578        cfg.ts_rate_decimator[0] = 4;
579        cfg.ts_rate_decimator[1] = 2;
580        cfg.ts_rate_decimator[2] = 1;
581        memcpy(cfg.ts_layer_id, ids, sizeof(ids));
582
583        flag_periodicity = 8;
584
585        /* 0=L, 1=GF, 2=ARF */
586
587        // Layer 0: predict from L and ARF; update L.
588        layer_flags[0] = VP8_EFLAG_NO_UPD_GF |
589                         VP8_EFLAG_NO_UPD_ARF |
590                         VP8_EFLAG_NO_REF_GF;
591        layer_flags[4] = layer_flags[0];
592
593        // Layer 1: predict from L, G, ARF; update G.
594        layer_flags[2] = VP8_EFLAG_NO_UPD_ARF |
595                         VP8_EFLAG_NO_UPD_LAST;
596        layer_flags[6] = layer_flags[2];
597
598        // Layer 2: predict from L, G, ARF; update none.
599        layer_flags[1] = VP8_EFLAG_NO_UPD_GF |
600                         VP8_EFLAG_NO_UPD_ARF |
601                         VP8_EFLAG_NO_UPD_LAST |
602                         VP8_EFLAG_NO_UPD_ENTROPY;
603        layer_flags[3] = layer_flags[1];
604        layer_flags[5] = layer_flags[1];
605        layer_flags[7] = layer_flags[1];
606        break;
607     }
608     }
609
610     /* Open input file */
611     if(!(infile = fopen(argv[1], "rb")))
612         die("Failed to open %s for reading", argv[1]);
613
614     /* Open an output file for each stream */
615     for (i=0; i<cfg.ts_number_layers; i++)
616     {
617         char file_name[512];
618         sprintf (file_name, "%s_%d.ivf", argv[2], i);
619         if (!(outfile[i] = fopen(file_name, "wb")))
620             die("Failed to open %s for writing", file_name);
621         write_ivf_file_header(outfile[i], &cfg, 0);
622     }
623
624     /* Initialize codec */
625     if (vpx_codec_enc_init (&codec, interface, &cfg, 0))
626         die_codec (&codec, "Failed to initialize encoder");
627
628     /* Cap CPU & first I-frame size */
629     vpx_codec_control (&codec, VP8E_SET_CPUUSED,                -6);
630     vpx_codec_control (&codec, VP8E_SET_STATIC_THRESHOLD,      1);
631     vpx_codec_control (&codec, VP8E_SET_NOISE_SENSITIVITY,       1);
632     vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS,       1);
633
634     max_intra_size_pct = (int) (((double)cfg.rc_buf_optimal_sz * 0.5)
635                          * ((double) cfg.g_timebase.den / cfg.g_timebase.num)
636                          / 10.0);
637     /* printf ("max_intra_size_pct=%d\n", max_intra_size_pct); */
638
639     vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
640                       max_intra_size_pct);
641
642     frame_avail = 1;
643     while (frame_avail || got_data) {
644         vpx_codec_iter_t iter = NULL;
645         const vpx_codec_cx_pkt_t *pkt;
646
647         flags = layer_flags[frame_cnt % flag_periodicity];
648
649         frame_avail = read_frame(infile, &raw);
650         if (vpx_codec_encode(&codec, frame_avail? &raw : NULL, pts,
651                             1, flags, VPX_DL_REALTIME))
652             die_codec(&codec, "Failed to encode frame");
653
654         /* Reset KF flag */
655         if (layering_mode != 7)
656             layer_flags[0] &= ~VPX_EFLAG_FORCE_KF;
657
658         got_data = 0;
659         while ( (pkt = vpx_codec_get_cx_data(&codec, &iter)) ) {
660             got_data = 1;
661             switch (pkt->kind) {
662             case VPX_CODEC_CX_FRAME_PKT:
663                 for (i=cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
664                                               i<cfg.ts_number_layers; i++)
665                 {
666                     write_ivf_frame_header(outfile[i], pkt);
667                     (void) fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
668                                   outfile[i]);
669                     frames_in_layer[i]++;
670                 }
671                 break;
672             default:
673                 break;
674             }
675         }
676         frame_cnt++;
677         pts += frame_duration;
678     }
679     fclose (infile);
680
681     printf ("Processed %d frames.\n",frame_cnt-1);
682     if (vpx_codec_destroy(&codec))
683             die_codec (&codec, "Failed to destroy codec");
684
685     /* Try to rewrite the output file headers with the actual frame count */
686     for (i=0; i<cfg.ts_number_layers; i++)
687     {
688         if (!fseek(outfile[i], 0, SEEK_SET))
689             write_ivf_file_header (outfile[i], &cfg, frames_in_layer[i]);
690         fclose (outfile[i]);
691     }
692
693     return EXIT_SUCCESS;
694 }