Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / third_party / libvpx / source / libvpx / examples / decode_with_partial_drops.txt
1 @TEMPLATE decoder_tmpl.c
2 Decode With Partial Drops Example
3 =========================
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
5 This is an example utility which drops a series of frames (or parts of frames),
6 as specified on the command line. This is useful for observing the error
7 recovery features of the codec.
8 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
9
10 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTRA_INCLUDES
11 #include <time.h>
12 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTRA_INCLUDES
13
14 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HELPERS
15 struct parsed_header
16 {
17     char key_frame;
18     int version;
19     char show_frame;
20     int first_part_size;
21 };
22
23 int next_packet(struct parsed_header* hdr, int pos, int length, int mtu)
24 {
25     int size = 0;
26     int remaining = length - pos;
27     /* Uncompressed part is 3 bytes for P frames and 10 bytes for I frames */
28     int uncomp_part_size = (hdr->key_frame ? 10 : 3);
29     /* number of bytes yet to send from header and the first partition */
30     int remainFirst = uncomp_part_size + hdr->first_part_size - pos;
31     if (remainFirst > 0)
32     {
33         if (remainFirst <= mtu)
34         {
35             size = remainFirst;
36         }
37         else
38         {
39             size = mtu;
40         }
41
42         return size;
43     }
44
45     /* second partition; just slot it up according to MTU */
46     if (remaining <= mtu)
47     {
48         size = remaining;
49         return size;
50     }
51     return mtu;
52 }
53
54 void throw_packets(unsigned char* frame, int* size, int loss_rate,
55                    int* thrown, int* kept)
56 {
57     unsigned char loss_frame[256*1024];
58     int pkg_size = 1;
59     int pos = 0;
60     int loss_pos = 0;
61     struct parsed_header hdr;
62     unsigned int tmp;
63     int mtu = 1500;
64
65     if (*size < 3)
66     {
67         return;
68     }
69     putc('|', stdout);
70     /* parse uncompressed 3 bytes */
71     tmp = (frame[2] << 16) | (frame[1] << 8) | frame[0];
72     hdr.key_frame = !(tmp & 0x1); /* inverse logic */
73     hdr.version = (tmp >> 1) & 0x7;
74     hdr.show_frame = (tmp >> 4) & 0x1;
75     hdr.first_part_size = (tmp >> 5) & 0x7FFFF;
76
77     /* don't drop key frames */
78     if (hdr.key_frame)
79     {
80         int i;
81         *kept = *size/mtu + ((*size % mtu > 0) ? 1 : 0); /* approximate */
82         for (i=0; i < *kept; i++)
83             putc('.', stdout);
84         return;
85     }
86
87     while ((pkg_size = next_packet(&hdr, pos, *size, mtu)) > 0)
88     {
89         int loss_event = ((rand() + 1.0)/(RAND_MAX + 1.0) < loss_rate/100.0);
90         if (*thrown == 0 && !loss_event)
91         {
92             memcpy(loss_frame + loss_pos, frame + pos, pkg_size);
93             loss_pos += pkg_size;
94             (*kept)++;
95             putc('.', stdout);
96         }
97         else
98         {
99             (*thrown)++;
100             putc('X', stdout);
101         }
102         pos += pkg_size;
103     }
104     memcpy(frame, loss_frame, loss_pos);
105     memset(frame + loss_pos, 0, *size - loss_pos);
106     *size = loss_pos;
107 }
108 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HELPERS
109
110 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INIT
111 /* Initialize codec */
112 flags = VPX_CODEC_USE_ERROR_CONCEALMENT;
113 res = vpx_codec_dec_init(&codec, interface, &dec_cfg, flags);
114 if(res)
115     die_codec(&codec, "Failed to initialize decoder");
116
117 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INIT
118
119 Usage
120 -----
121 This example adds a single argument to the `simple_decoder` example,
122 which specifies the range or pattern of frames to drop. The parameter is
123 parsed as follows:
124
125 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
126 if(argc < 4 || argc > 6)
127     die("Usage: %s <infile> <outfile> [-t <num threads>] <N-M|N/M|L,S>\n",
128         argv[0]);
129 {
130     char *nptr;
131     int arg_num = 3;
132     if (argc == 6 && strncmp(argv[arg_num++], "-t", 2) == 0)
133         dec_cfg.threads = strtol(argv[arg_num++], NULL, 0);
134     n = strtol(argv[arg_num], &nptr, 0);
135     mode = (*nptr == '\0' || *nptr == ',') ? 2 : (*nptr == '-') ? 1 : 0;
136
137     m = strtol(nptr+1, NULL, 0);
138     if((!n && !m) || (*nptr != '-' && *nptr != '/' &&
139         *nptr != '\0' && *nptr != ','))
140         die("Couldn't parse pattern %s\n", argv[3]);
141 }
142 seed = (m > 0) ? m : (unsigned int)time(NULL);
143 srand(seed);thrown_frame = 0;
144 printf("Seed: %u\n", seed);
145 printf("Threads: %d\n", dec_cfg.threads);
146 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
147
148
149 Dropping A Range Of Frames
150 --------------------------
151 To drop a range of frames, specify the starting frame and the ending
152 frame to drop, separated by a dash. The following command will drop
153 frames 5 through 10 (base 1).
154
155   $ ./decode_with_partial_drops in.ivf out.i420 5-10
156
157
158 Dropping A Pattern Of Frames
159 ----------------------------
160 To drop a pattern of frames, specify the number of frames to drop and
161 the number of frames after which to repeat the pattern, separated by
162 a forward-slash. The following command will drop 3 of 7 frames.
163 Specifically, it will decode 4 frames, then drop 3 frames, and then
164 repeat.
165
166   $ ./decode_with_partial_drops in.ivf out.i420 3/7
167
168 Dropping Random Parts Of Frames
169 -------------------------------
170 A third argument tuple is available to split the frame into 1500 bytes pieces
171 and randomly drop pieces rather than frames. The frame will be split at
172 partition boundaries where possible. The following example will seed the RNG
173 with the seed 123 and drop approximately 5% of the pieces. Pieces which
174 are depending on an already dropped piece will also be dropped.
175
176   $ ./decode_with_partial_drops in.ivf out.i420 5,123
177
178
179 Extra Variables
180 ---------------
181 This example maintains the pattern passed on the command line in the
182 `n`, `m`, and `is_range` variables:
183
184 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTRA_VARS
185 int              n, m, mode;
186 unsigned int     seed;
187 int              thrown=0, kept=0;
188 int              thrown_frame=0, kept_frame=0;
189 vpx_codec_dec_cfg_t  dec_cfg = {0};
190 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTRA_VARS
191
192
193 Making The Drop Decision
194 ------------------------
195 The example decides whether to drop the frame based on the current
196 frame number, immediately before decoding the frame.
197
198 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PRE_DECODE
199 /* Decide whether to throw parts of the frame or the whole frame
200    depending on the drop mode */
201 thrown_frame = 0;
202 kept_frame = 0;
203 switch (mode)
204 {
205 case 0:
206     if (m - (frame_cnt-1)%m <= n)
207     {
208         frame_sz = 0;
209     }
210     break;
211 case 1:
212     if (frame_cnt >= n && frame_cnt <= m)
213     {
214         frame_sz = 0;
215     }
216     break;
217 case 2:
218     throw_packets(frame, &frame_sz, n, &thrown_frame, &kept_frame);
219     break;
220 default: break;
221 }
222 if (mode < 2)
223 {
224     if (frame_sz == 0)
225     {
226         putc('X', stdout);
227         thrown_frame++;
228     }
229     else
230     {
231         putc('.', stdout);
232         kept_frame++;
233     }
234 }
235 thrown += thrown_frame;
236 kept += kept_frame;
237 fflush(stdout);
238 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PRE_DECODE