OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <assert.h> | 11 #include <assert.h> |
12 #include <limits.h> | 12 #include <limits.h> |
13 #include <stdio.h> | 13 #include <stdio.h> |
14 | 14 |
15 #include "./vpx_scale_rtcd.h" | 15 #include "./vpx_scale_rtcd.h" |
16 | 16 |
17 #include "vpx_mem/vpx_mem.h" | 17 #include "vpx_mem/vpx_mem.h" |
| 18 #include "vpx_ports/vpx_once.h" |
18 #include "vpx_ports/vpx_timer.h" | 19 #include "vpx_ports/vpx_timer.h" |
19 #include "vpx_scale/vpx_scale.h" | 20 #include "vpx_scale/vpx_scale.h" |
20 | 21 |
21 #include "vp9/common/vp9_alloccommon.h" | 22 #include "vp9/common/vp9_alloccommon.h" |
22 #include "vp9/common/vp9_loopfilter.h" | 23 #include "vp9/common/vp9_loopfilter.h" |
23 #include "vp9/common/vp9_onyxc_int.h" | 24 #include "vp9/common/vp9_onyxc_int.h" |
24 #if CONFIG_VP9_POSTPROC | 25 #if CONFIG_VP9_POSTPROC |
25 #include "vp9/common/vp9_postproc.h" | 26 #include "vp9/common/vp9_postproc.h" |
26 #endif | 27 #endif |
27 #include "vp9/common/vp9_quant_common.h" | 28 #include "vp9/common/vp9_quant_common.h" |
28 #include "vp9/common/vp9_reconintra.h" | 29 #include "vp9/common/vp9_reconintra.h" |
29 #include "vp9/common/vp9_systemdependent.h" | 30 #include "vp9/common/vp9_systemdependent.h" |
30 | 31 |
31 #include "vp9/decoder/vp9_decodeframe.h" | 32 #include "vp9/decoder/vp9_decodeframe.h" |
32 #include "vp9/decoder/vp9_decoder.h" | 33 #include "vp9/decoder/vp9_decoder.h" |
33 #include "vp9/decoder/vp9_detokenize.h" | 34 #include "vp9/decoder/vp9_detokenize.h" |
34 #include "vp9/decoder/vp9_dthread.h" | 35 #include "vp9/decoder/vp9_dthread.h" |
35 | 36 |
36 static void initialize_dec() { | 37 static void initialize_dec(void) { |
37 static int init_done = 0; | 38 static volatile int init_done = 0; |
38 | 39 |
39 if (!init_done) { | 40 if (!init_done) { |
40 vp9_rtcd(); | 41 vp9_rtcd(); |
41 vp9_init_intra_predictors(); | 42 vp9_init_intra_predictors(); |
42 init_done = 1; | 43 init_done = 1; |
43 } | 44 } |
44 } | 45 } |
45 | 46 |
46 static void vp9_dec_setup_mi(VP9_COMMON *cm) { | 47 static void vp9_dec_setup_mi(VP9_COMMON *cm) { |
47 cm->mi = cm->mip + cm->mi_stride + 1; | 48 cm->mi = cm->mip + cm->mi_stride + 1; |
48 vpx_memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip)); | 49 vpx_memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip)); |
49 } | 50 } |
50 | 51 |
51 static int vp9_dec_alloc_mi(VP9_COMMON *cm, int mi_size) { | 52 static int vp9_dec_alloc_mi(VP9_COMMON *cm, int mi_size) { |
52 cm->mip = vpx_calloc(mi_size, sizeof(*cm->mip)); | 53 cm->mip = vpx_calloc(mi_size, sizeof(*cm->mip)); |
53 if (!cm->mip) | 54 if (!cm->mip) |
54 return 1; | 55 return 1; |
55 cm->mi_alloc_size = mi_size; | 56 cm->mi_alloc_size = mi_size; |
56 return 0; | 57 return 0; |
57 } | 58 } |
58 | 59 |
59 static void vp9_dec_free_mi(VP9_COMMON *cm) { | 60 static void vp9_dec_free_mi(VP9_COMMON *cm) { |
60 vpx_free(cm->mip); | 61 vpx_free(cm->mip); |
61 cm->mip = NULL; | 62 cm->mip = NULL; |
62 } | 63 } |
63 | 64 |
64 VP9Decoder *vp9_decoder_create() { | 65 VP9Decoder *vp9_decoder_create() { |
65 VP9Decoder *const pbi = vpx_memalign(32, sizeof(*pbi)); | 66 VP9Decoder *volatile const pbi = vpx_memalign(32, sizeof(*pbi)); |
66 VP9_COMMON *const cm = pbi ? &pbi->common : NULL; | 67 VP9_COMMON *volatile const cm = pbi ? &pbi->common : NULL; |
67 | 68 |
68 if (!cm) | 69 if (!cm) |
69 return NULL; | 70 return NULL; |
70 | 71 |
71 vp9_zero(*pbi); | 72 vp9_zero(*pbi); |
72 | 73 |
73 if (setjmp(cm->error.jmp)) { | 74 if (setjmp(cm->error.jmp)) { |
74 cm->error.setjmp = 0; | 75 cm->error.setjmp = 0; |
75 vp9_decoder_remove(pbi); | 76 vp9_decoder_remove(pbi); |
76 return NULL; | 77 return NULL; |
77 } | 78 } |
78 | 79 |
79 cm->error.setjmp = 1; | 80 cm->error.setjmp = 1; |
80 | 81 |
81 CHECK_MEM_ERROR(cm, cm->fc, | 82 CHECK_MEM_ERROR(cm, cm->fc, |
82 (FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc))); | 83 (FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc))); |
83 CHECK_MEM_ERROR(cm, cm->frame_contexts, | 84 CHECK_MEM_ERROR(cm, cm->frame_contexts, |
84 (FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS, | 85 (FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS, |
85 sizeof(*cm->frame_contexts))); | 86 sizeof(*cm->frame_contexts))); |
86 | 87 |
87 pbi->need_resync = 1; | 88 pbi->need_resync = 1; |
88 initialize_dec(); | 89 once(initialize_dec); |
89 | 90 |
90 // Initialize the references to not point to any frame buffers. | 91 // Initialize the references to not point to any frame buffers. |
91 vpx_memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); | 92 vpx_memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); |
92 | 93 |
93 cm->current_video_frame = 0; | 94 cm->current_video_frame = 0; |
94 pbi->ready_for_new_data = 1; | 95 pbi->ready_for_new_data = 1; |
95 cm->bit_depth = VPX_BITS_8; | 96 cm->bit_depth = VPX_BITS_8; |
96 cm->dequant_bit_depth = VPX_BITS_8; | 97 cm->dequant_bit_depth = VPX_BITS_8; |
97 | 98 |
98 cm->alloc_mi = vp9_dec_alloc_mi; | 99 cm->alloc_mi = vp9_dec_alloc_mi; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 &cm->frame_bufs[old_idx].raw_frame_buffer); | 231 &cm->frame_bufs[old_idx].raw_frame_buffer); |
231 } | 232 } |
232 ++ref_index; | 233 ++ref_index; |
233 } | 234 } |
234 | 235 |
235 cm->frame_to_show = get_frame_new_buffer(cm); | 236 cm->frame_to_show = get_frame_new_buffer(cm); |
236 cm->frame_bufs[cm->new_fb_idx].ref_count--; | 237 cm->frame_bufs[cm->new_fb_idx].ref_count--; |
237 | 238 |
238 // Invalidate these references until the next frame starts. | 239 // Invalidate these references until the next frame starts. |
239 for (ref_index = 0; ref_index < 3; ref_index++) | 240 for (ref_index = 0; ref_index < 3; ref_index++) |
240 cm->frame_refs[ref_index].idx = INT_MAX; | 241 cm->frame_refs[ref_index].idx = -1; |
241 } | 242 } |
242 | 243 |
243 int vp9_receive_compressed_data(VP9Decoder *pbi, | 244 int vp9_receive_compressed_data(VP9Decoder *pbi, |
244 size_t size, const uint8_t **psource) { | 245 size_t size, const uint8_t **psource) { |
245 VP9_COMMON *const cm = &pbi->common; | 246 VP9_COMMON *volatile const cm = &pbi->common; |
246 const uint8_t *source = *psource; | 247 const uint8_t *source = *psource; |
247 int retcode = 0; | 248 int retcode = 0; |
248 | 249 |
249 cm->error.error_code = VPX_CODEC_OK; | 250 cm->error.error_code = VPX_CODEC_OK; |
250 | 251 |
251 if (size == 0) { | 252 if (size == 0) { |
252 // This is used to signal that we are missing frames. | 253 // This is used to signal that we are missing frames. |
253 // We do not know if the missing frame(s) was supposed to update | 254 // We do not know if the missing frame(s) was supposed to update |
254 // any of the reference buffers, but we act conservative and | 255 // any of the reference buffers, but we act conservative and |
255 // mark only the last buffer as corrupted. | 256 // mark only the last buffer as corrupted. |
256 // | 257 // |
257 // TODO(jkoleszar): Error concealment is undefined and non-normative | 258 // TODO(jkoleszar): Error concealment is undefined and non-normative |
258 // at this point, but if it becomes so, [0] may not always be the correct | 259 // at this point, but if it becomes so, [0] may not always be the correct |
259 // thing to do here. | 260 // thing to do here. |
260 if (cm->frame_refs[0].idx != INT_MAX) | 261 if (cm->frame_refs[0].idx > 0) |
261 cm->frame_refs[0].buf->corrupted = 1; | 262 cm->frame_refs[0].buf->corrupted = 1; |
262 } | 263 } |
263 | 264 |
264 pbi->ready_for_new_data = 0; | 265 pbi->ready_for_new_data = 0; |
265 | 266 |
266 // Check if the previous frame was a frame without any references to it. | 267 // Check if the previous frame was a frame without any references to it. |
267 if (cm->new_fb_idx >= 0 && cm->frame_bufs[cm->new_fb_idx].ref_count == 0) | 268 if (cm->new_fb_idx >= 0 && cm->frame_bufs[cm->new_fb_idx].ref_count == 0) |
268 cm->release_fb_cb(cm->cb_priv, | 269 cm->release_fb_cb(cm->cb_priv, |
269 &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer); | 270 &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer); |
270 cm->new_fb_idx = get_free_fb(cm); | 271 cm->new_fb_idx = get_free_fb(cm); |
(...skipping 10 matching lines...) Expand all Loading... |
281 | 282 |
282 // Synchronize all threads immediately as a subsequent decode call may | 283 // Synchronize all threads immediately as a subsequent decode call may |
283 // cause a resize invalidating some allocations. | 284 // cause a resize invalidating some allocations. |
284 winterface->sync(&pbi->lf_worker); | 285 winterface->sync(&pbi->lf_worker); |
285 for (i = 0; i < pbi->num_tile_workers; ++i) { | 286 for (i = 0; i < pbi->num_tile_workers; ++i) { |
286 winterface->sync(&pbi->tile_workers[i]); | 287 winterface->sync(&pbi->tile_workers[i]); |
287 } | 288 } |
288 | 289 |
289 vp9_clear_system_state(); | 290 vp9_clear_system_state(); |
290 | 291 |
291 // We do not know if the missing frame(s) was supposed to update | |
292 // any of the reference buffers, but we act conservative and | |
293 // mark only the last buffer as corrupted. | |
294 // | |
295 // TODO(jkoleszar): Error concealment is undefined and non-normative | |
296 // at this point, but if it becomes so, [0] may not always be the correct | |
297 // thing to do here. | |
298 if (cm->frame_refs[0].idx != INT_MAX && cm->frame_refs[0].buf != NULL) | |
299 cm->frame_refs[0].buf->corrupted = 1; | |
300 | |
301 if (cm->new_fb_idx > 0 && cm->frame_bufs[cm->new_fb_idx].ref_count > 0) | 292 if (cm->new_fb_idx > 0 && cm->frame_bufs[cm->new_fb_idx].ref_count > 0) |
302 cm->frame_bufs[cm->new_fb_idx].ref_count--; | 293 cm->frame_bufs[cm->new_fb_idx].ref_count--; |
303 | 294 |
304 return -1; | 295 return -1; |
305 } | 296 } |
306 | 297 |
307 cm->error.setjmp = 1; | 298 cm->error.setjmp = 1; |
308 | 299 |
309 vp9_decode_frame(pbi, source, source + size, psource); | 300 vp9_decode_frame(pbi, source, source + size, psource); |
310 | 301 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 | 406 |
416 for (j = 0; j < mag; ++j) | 407 for (j = 0; j < mag; ++j) |
417 this_sz |= (*x++) << (j * 8); | 408 this_sz |= (*x++) << (j * 8); |
418 sizes[i] = this_sz; | 409 sizes[i] = this_sz; |
419 } | 410 } |
420 *count = frames; | 411 *count = frames; |
421 } | 412 } |
422 } | 413 } |
423 return VPX_CODEC_OK; | 414 return VPX_CODEC_OK; |
424 } | 415 } |
OLD | NEW |