Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c

Issue 1158913006: Move libvpx from DEPS to src (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add DEPS file with #include paths Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2010 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 #include <assert.h>
12 #include <limits.h>
13 #include <stdio.h>
14
15 #include "./vp9_rtcd.h"
16 #include "./vpx_dsp_rtcd.h"
17 #include "./vpx_scale_rtcd.h"
18
19 #include "vpx_mem/vpx_mem.h"
20 #include "vpx_ports/vpx_once.h"
21 #include "vpx_ports/vpx_timer.h"
22 #include "vpx_scale/vpx_scale.h"
23
24 #include "vp9/common/vp9_alloccommon.h"
25 #include "vp9/common/vp9_loopfilter.h"
26 #include "vp9/common/vp9_onyxc_int.h"
27 #if CONFIG_VP9_POSTPROC
28 #include "vp9/common/vp9_postproc.h"
29 #endif
30 #include "vp9/common/vp9_quant_common.h"
31 #include "vp9/common/vp9_reconintra.h"
32 #include "vp9/common/vp9_systemdependent.h"
33 #include "vp9/common/vp9_thread.h"
34
35 #include "vp9/decoder/vp9_decodeframe.h"
36 #include "vp9/decoder/vp9_decoder.h"
37 #include "vp9/decoder/vp9_detokenize.h"
38
39 static void initialize_dec(void) {
40 static volatile int init_done = 0;
41
42 if (!init_done) {
43 vp9_rtcd();
44 vpx_dsp_rtcd();
45 vpx_scale_rtcd();
46 vp9_init_intra_predictors();
47 init_done = 1;
48 }
49 }
50
51 static void vp9_dec_setup_mi(VP9_COMMON *cm) {
52 cm->mi = cm->mip + cm->mi_stride + 1;
53 memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
54 cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
55 memset(cm->mi_grid_base, 0,
56 cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base));
57 }
58
59 static int vp9_dec_alloc_mi(VP9_COMMON *cm, int mi_size) {
60 cm->mip = vpx_calloc(mi_size, sizeof(*cm->mip));
61 if (!cm->mip)
62 return 1;
63 cm->mi_alloc_size = mi_size;
64 cm->mi_grid_base = (MODE_INFO **)vpx_calloc(mi_size, sizeof(MODE_INFO*));
65 if (!cm->mi_grid_base)
66 return 1;
67 return 0;
68 }
69
70 static void vp9_dec_free_mi(VP9_COMMON *cm) {
71 vpx_free(cm->mip);
72 cm->mip = NULL;
73 vpx_free(cm->mi_grid_base);
74 cm->mi_grid_base = NULL;
75 }
76
77 VP9Decoder *vp9_decoder_create(BufferPool *const pool) {
78 VP9Decoder *volatile const pbi = vpx_memalign(32, sizeof(*pbi));
79 VP9_COMMON *volatile const cm = pbi ? &pbi->common : NULL;
80
81 if (!cm)
82 return NULL;
83
84 vp9_zero(*pbi);
85
86 if (setjmp(cm->error.jmp)) {
87 cm->error.setjmp = 0;
88 vp9_decoder_remove(pbi);
89 return NULL;
90 }
91
92 cm->error.setjmp = 1;
93
94 CHECK_MEM_ERROR(cm, cm->fc,
95 (FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc)));
96 CHECK_MEM_ERROR(cm, cm->frame_contexts,
97 (FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS,
98 sizeof(*cm->frame_contexts)));
99
100 pbi->need_resync = 1;
101 once(initialize_dec);
102
103 // Initialize the references to not point to any frame buffers.
104 memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map));
105 memset(&cm->next_ref_frame_map, -1, sizeof(cm->next_ref_frame_map));
106
107 cm->current_video_frame = 0;
108 pbi->ready_for_new_data = 1;
109 pbi->common.buffer_pool = pool;
110
111 cm->bit_depth = VPX_BITS_8;
112 cm->dequant_bit_depth = VPX_BITS_8;
113
114 cm->alloc_mi = vp9_dec_alloc_mi;
115 cm->free_mi = vp9_dec_free_mi;
116 cm->setup_mi = vp9_dec_setup_mi;
117
118 vp9_loop_filter_init(cm);
119
120 cm->error.setjmp = 0;
121
122 vp9_get_worker_interface()->init(&pbi->lf_worker);
123
124 return pbi;
125 }
126
127 void vp9_decoder_remove(VP9Decoder *pbi) {
128 int i;
129
130 vp9_get_worker_interface()->end(&pbi->lf_worker);
131 vpx_free(pbi->lf_worker.data1);
132 vpx_free(pbi->tile_data);
133 for (i = 0; i < pbi->num_tile_workers; ++i) {
134 VP9Worker *const worker = &pbi->tile_workers[i];
135 vp9_get_worker_interface()->end(worker);
136 }
137 vpx_free(pbi->tile_worker_data);
138 vpx_free(pbi->tile_worker_info);
139 vpx_free(pbi->tile_workers);
140
141 if (pbi->num_tile_workers > 0) {
142 vp9_loop_filter_dealloc(&pbi->lf_row_sync);
143 }
144
145 vpx_free(pbi);
146 }
147
148 static int equal_dimensions(const YV12_BUFFER_CONFIG *a,
149 const YV12_BUFFER_CONFIG *b) {
150 return a->y_height == b->y_height && a->y_width == b->y_width &&
151 a->uv_height == b->uv_height && a->uv_width == b->uv_width;
152 }
153
154 vpx_codec_err_t vp9_copy_reference_dec(VP9Decoder *pbi,
155 VP9_REFFRAME ref_frame_flag,
156 YV12_BUFFER_CONFIG *sd) {
157 VP9_COMMON *cm = &pbi->common;
158
159 /* TODO(jkoleszar): The decoder doesn't have any real knowledge of what the
160 * encoder is using the frame buffers for. This is just a stub to keep the
161 * vpxenc --test-decode functionality working, and will be replaced in a
162 * later commit that adds VP9-specific controls for this functionality.
163 */
164 if (ref_frame_flag == VP9_LAST_FLAG) {
165 const YV12_BUFFER_CONFIG *const cfg = get_ref_frame(cm, 0);
166 if (cfg == NULL) {
167 vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
168 "No 'last' reference frame");
169 return VPX_CODEC_ERROR;
170 }
171 if (!equal_dimensions(cfg, sd))
172 vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
173 "Incorrect buffer dimensions");
174 else
175 vp8_yv12_copy_frame(cfg, sd);
176 } else {
177 vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
178 "Invalid reference frame");
179 }
180
181 return cm->error.error_code;
182 }
183
184
185 vpx_codec_err_t vp9_set_reference_dec(VP9_COMMON *cm,
186 VP9_REFFRAME ref_frame_flag,
187 YV12_BUFFER_CONFIG *sd) {
188 RefBuffer *ref_buf = NULL;
189 RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
190
191 // TODO(jkoleszar): The decoder doesn't have any real knowledge of what the
192 // encoder is using the frame buffers for. This is just a stub to keep the
193 // vpxenc --test-decode functionality working, and will be replaced in a
194 // later commit that adds VP9-specific controls for this functionality.
195 if (ref_frame_flag == VP9_LAST_FLAG) {
196 ref_buf = &cm->frame_refs[0];
197 } else if (ref_frame_flag == VP9_GOLD_FLAG) {
198 ref_buf = &cm->frame_refs[1];
199 } else if (ref_frame_flag == VP9_ALT_FLAG) {
200 ref_buf = &cm->frame_refs[2];
201 } else {
202 vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
203 "Invalid reference frame");
204 return cm->error.error_code;
205 }
206
207 if (!equal_dimensions(ref_buf->buf, sd)) {
208 vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
209 "Incorrect buffer dimensions");
210 } else {
211 int *ref_fb_ptr = &ref_buf->idx;
212
213 // Find an empty frame buffer.
214 const int free_fb = get_free_fb(cm);
215 // Decrease ref_count since it will be increased again in
216 // ref_cnt_fb() below.
217 --frame_bufs[free_fb].ref_count;
218
219 // Manage the reference counters and copy image.
220 ref_cnt_fb(frame_bufs, ref_fb_ptr, free_fb);
221 ref_buf->buf = &frame_bufs[*ref_fb_ptr].buf;
222 vp8_yv12_copy_frame(sd, ref_buf->buf);
223 }
224
225 return cm->error.error_code;
226 }
227
228 /* If any buffer updating is signaled it should be done here. */
229 static void swap_frame_buffers(VP9Decoder *pbi) {
230 int ref_index = 0, mask;
231 VP9_COMMON *const cm = &pbi->common;
232 BufferPool *const pool = cm->buffer_pool;
233 RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
234
235 lock_buffer_pool(pool);
236 for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
237 const int old_idx = cm->ref_frame_map[ref_index];
238 // Current thread releases the holding of reference frame.
239 decrease_ref_count(old_idx, frame_bufs, pool);
240
241 // Release the reference frame in reference map.
242 if ((mask & 1) && old_idx >= 0) {
243 decrease_ref_count(old_idx, frame_bufs, pool);
244 }
245 cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
246 ++ref_index;
247 }
248
249 // Current thread releases the holding of reference frame.
250 for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) {
251 const int old_idx = cm->ref_frame_map[ref_index];
252 decrease_ref_count(old_idx, frame_bufs, pool);
253 cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
254 }
255 unlock_buffer_pool(pool);
256 pbi->hold_ref_buf = 0;
257 cm->frame_to_show = get_frame_new_buffer(cm);
258
259 if (!pbi->frame_parallel_decode || !cm->show_frame) {
260 lock_buffer_pool(pool);
261 --frame_bufs[cm->new_fb_idx].ref_count;
262 unlock_buffer_pool(pool);
263 }
264
265 // Invalidate these references until the next frame starts.
266 for (ref_index = 0; ref_index < 3; ref_index++)
267 cm->frame_refs[ref_index].idx = -1;
268 }
269
270 int vp9_receive_compressed_data(VP9Decoder *pbi,
271 size_t size, const uint8_t **psource) {
272 VP9_COMMON *volatile const cm = &pbi->common;
273 BufferPool *volatile const pool = cm->buffer_pool;
274 RefCntBuffer *volatile const frame_bufs = cm->buffer_pool->frame_bufs;
275 const uint8_t *source = *psource;
276 int retcode = 0;
277 cm->error.error_code = VPX_CODEC_OK;
278
279 if (size == 0) {
280 // This is used to signal that we are missing frames.
281 // We do not know if the missing frame(s) was supposed to update
282 // any of the reference buffers, but we act conservative and
283 // mark only the last buffer as corrupted.
284 //
285 // TODO(jkoleszar): Error concealment is undefined and non-normative
286 // at this point, but if it becomes so, [0] may not always be the correct
287 // thing to do here.
288 if (cm->frame_refs[0].idx > 0) {
289 assert(cm->frame_refs[0].buf != NULL);
290 cm->frame_refs[0].buf->corrupted = 1;
291 }
292 }
293
294 pbi->ready_for_new_data = 0;
295
296 // Check if the previous frame was a frame without any references to it.
297 // Release frame buffer if not decoding in frame parallel mode.
298 if (!pbi->frame_parallel_decode && cm->new_fb_idx >= 0
299 && frame_bufs[cm->new_fb_idx].ref_count == 0)
300 pool->release_fb_cb(pool->cb_priv,
301 &frame_bufs[cm->new_fb_idx].raw_frame_buffer);
302 cm->new_fb_idx = get_free_fb(cm);
303
304 // Assign a MV array to the frame buffer.
305 cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx];
306
307 pbi->hold_ref_buf = 0;
308 if (pbi->frame_parallel_decode) {
309 VP9Worker *const worker = pbi->frame_worker_owner;
310 vp9_frameworker_lock_stats(worker);
311 frame_bufs[cm->new_fb_idx].frame_worker_owner = worker;
312 // Reset decoding progress.
313 pbi->cur_buf = &frame_bufs[cm->new_fb_idx];
314 pbi->cur_buf->row = -1;
315 pbi->cur_buf->col = -1;
316 vp9_frameworker_unlock_stats(worker);
317 } else {
318 pbi->cur_buf = &frame_bufs[cm->new_fb_idx];
319 }
320
321
322 if (setjmp(cm->error.jmp)) {
323 const VP9WorkerInterface *const winterface = vp9_get_worker_interface();
324 int i;
325
326 cm->error.setjmp = 0;
327 pbi->ready_for_new_data = 1;
328
329 // Synchronize all threads immediately as a subsequent decode call may
330 // cause a resize invalidating some allocations.
331 winterface->sync(&pbi->lf_worker);
332 for (i = 0; i < pbi->num_tile_workers; ++i) {
333 winterface->sync(&pbi->tile_workers[i]);
334 }
335
336 lock_buffer_pool(pool);
337 // Release all the reference buffers if worker thread is holding them.
338 if (pbi->hold_ref_buf == 1) {
339 int ref_index = 0, mask;
340 for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
341 const int old_idx = cm->ref_frame_map[ref_index];
342 // Current thread releases the holding of reference frame.
343 decrease_ref_count(old_idx, frame_bufs, pool);
344
345 // Release the reference frame in reference map.
346 if ((mask & 1) && old_idx >= 0) {
347 decrease_ref_count(old_idx, frame_bufs, pool);
348 }
349 ++ref_index;
350 }
351
352 // Current thread releases the holding of reference frame.
353 for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) {
354 const int old_idx = cm->ref_frame_map[ref_index];
355 decrease_ref_count(old_idx, frame_bufs, pool);
356 }
357 pbi->hold_ref_buf = 0;
358 }
359 // Release current frame.
360 decrease_ref_count(cm->new_fb_idx, frame_bufs, pool);
361 unlock_buffer_pool(pool);
362
363 vp9_clear_system_state();
364 return -1;
365 }
366
367 cm->error.setjmp = 1;
368 vp9_decode_frame(pbi, source, source + size, psource);
369
370 swap_frame_buffers(pbi);
371
372 vp9_clear_system_state();
373
374 if (!cm->show_existing_frame) {
375 cm->last_show_frame = cm->show_frame;
376 cm->prev_frame = cm->cur_frame;
377 if (cm->seg.enabled && !pbi->frame_parallel_decode)
378 vp9_swap_current_and_last_seg_map(cm);
379 }
380
381 // Update progress in frame parallel decode.
382 if (pbi->frame_parallel_decode) {
383 // Need to lock the mutex here as another thread may
384 // be accessing this buffer.
385 VP9Worker *const worker = pbi->frame_worker_owner;
386 FrameWorkerData *const frame_worker_data = worker->data1;
387 vp9_frameworker_lock_stats(worker);
388
389 if (cm->show_frame) {
390 cm->current_video_frame++;
391 }
392 frame_worker_data->frame_decoded = 1;
393 frame_worker_data->frame_context_ready = 1;
394 vp9_frameworker_signal_stats(worker);
395 vp9_frameworker_unlock_stats(worker);
396 } else {
397 cm->last_width = cm->width;
398 cm->last_height = cm->height;
399 if (cm->show_frame) {
400 cm->current_video_frame++;
401 }
402 }
403
404 cm->error.setjmp = 0;
405 return retcode;
406 }
407
408 int vp9_get_raw_frame(VP9Decoder *pbi, YV12_BUFFER_CONFIG *sd,
409 vp9_ppflags_t *flags) {
410 VP9_COMMON *const cm = &pbi->common;
411 int ret = -1;
412 #if !CONFIG_VP9_POSTPROC
413 (void)*flags;
414 #endif
415
416 if (pbi->ready_for_new_data == 1)
417 return ret;
418
419 pbi->ready_for_new_data = 1;
420
421 /* no raw frame to show!!! */
422 if (!cm->show_frame)
423 return ret;
424
425 pbi->ready_for_new_data = 1;
426
427 #if CONFIG_VP9_POSTPROC
428 if (!cm->show_existing_frame) {
429 ret = vp9_post_proc_frame(cm, sd, flags);
430 } else {
431 *sd = *cm->frame_to_show;
432 ret = 0;
433 }
434 #else
435 *sd = *cm->frame_to_show;
436 ret = 0;
437 #endif /*!CONFIG_POSTPROC*/
438 vp9_clear_system_state();
439 return ret;
440 }
441
442 vpx_codec_err_t vp9_parse_superframe_index(const uint8_t *data,
443 size_t data_sz,
444 uint32_t sizes[8], int *count,
445 vpx_decrypt_cb decrypt_cb,
446 void *decrypt_state) {
447 // A chunk ending with a byte matching 0xc0 is an invalid chunk unless
448 // it is a super frame index. If the last byte of real video compression
449 // data is 0xc0 the encoder must add a 0 byte. If we have the marker but
450 // not the associated matching marker byte at the front of the index we have
451 // an invalid bitstream and need to return an error.
452
453 uint8_t marker;
454
455 assert(data_sz);
456 marker = read_marker(decrypt_cb, decrypt_state, data + data_sz - 1);
457 *count = 0;
458
459 if ((marker & 0xe0) == 0xc0) {
460 const uint32_t frames = (marker & 0x7) + 1;
461 const uint32_t mag = ((marker >> 3) & 0x3) + 1;
462 const size_t index_sz = 2 + mag * frames;
463
464 // This chunk is marked as having a superframe index but doesn't have
465 // enough data for it, thus it's an invalid superframe index.
466 if (data_sz < index_sz)
467 return VPX_CODEC_CORRUPT_FRAME;
468
469 {
470 const uint8_t marker2 = read_marker(decrypt_cb, decrypt_state,
471 data + data_sz - index_sz);
472
473 // This chunk is marked as having a superframe index but doesn't have
474 // the matching marker byte at the front of the index therefore it's an
475 // invalid chunk.
476 if (marker != marker2)
477 return VPX_CODEC_CORRUPT_FRAME;
478 }
479
480 {
481 // Found a valid superframe index.
482 uint32_t i, j;
483 const uint8_t *x = &data[data_sz - index_sz + 1];
484
485 // Frames has a maximum of 8 and mag has a maximum of 4.
486 uint8_t clear_buffer[32];
487 assert(sizeof(clear_buffer) >= frames * mag);
488 if (decrypt_cb) {
489 decrypt_cb(decrypt_state, x, clear_buffer, frames * mag);
490 x = clear_buffer;
491 }
492
493 for (i = 0; i < frames; ++i) {
494 uint32_t this_sz = 0;
495
496 for (j = 0; j < mag; ++j)
497 this_sz |= (*x++) << (j * 8);
498 sizes[i] = this_sz;
499 }
500 *count = frames;
501 }
502 }
503 return VPX_CODEC_OK;
504 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698