| 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 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 #include "vp9/common/vp9_alloccommon.h" | 22 #include "vp9/common/vp9_alloccommon.h" |
| 23 #include "vp9/common/vp9_loopfilter.h" | 23 #include "vp9/common/vp9_loopfilter.h" |
| 24 #include "vp9/common/vp9_onyxc_int.h" | 24 #include "vp9/common/vp9_onyxc_int.h" |
| 25 #if CONFIG_VP9_POSTPROC | 25 #if CONFIG_VP9_POSTPROC |
| 26 #include "vp9/common/vp9_postproc.h" | 26 #include "vp9/common/vp9_postproc.h" |
| 27 #endif | 27 #endif |
| 28 #include "vp9/common/vp9_quant_common.h" | 28 #include "vp9/common/vp9_quant_common.h" |
| 29 #include "vp9/common/vp9_reconintra.h" | 29 #include "vp9/common/vp9_reconintra.h" |
| 30 #include "vp9/common/vp9_systemdependent.h" | 30 #include "vp9/common/vp9_systemdependent.h" |
| 31 #include "vp9/common/vp9_thread.h" | |
| 32 | 31 |
| 33 #include "vp9/decoder/vp9_decodeframe.h" | 32 #include "vp9/decoder/vp9_decodeframe.h" |
| 34 #include "vp9/decoder/vp9_decoder.h" | 33 #include "vp9/decoder/vp9_decoder.h" |
| 35 #include "vp9/decoder/vp9_detokenize.h" | 34 #include "vp9/decoder/vp9_detokenize.h" |
| 36 | 35 |
| 37 static void initialize_dec(void) { | 36 static void initialize_dec(void) { |
| 38 static volatile int init_done = 0; | 37 static volatile int init_done = 0; |
| 39 | 38 |
| 40 if (!init_done) { | 39 if (!init_done) { |
| 41 vp9_rtcd(); | 40 vp9_rtcd(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 55 return 1; | 54 return 1; |
| 56 cm->mi_alloc_size = mi_size; | 55 cm->mi_alloc_size = mi_size; |
| 57 return 0; | 56 return 0; |
| 58 } | 57 } |
| 59 | 58 |
| 60 static void vp9_dec_free_mi(VP9_COMMON *cm) { | 59 static void vp9_dec_free_mi(VP9_COMMON *cm) { |
| 61 vpx_free(cm->mip); | 60 vpx_free(cm->mip); |
| 62 cm->mip = NULL; | 61 cm->mip = NULL; |
| 63 } | 62 } |
| 64 | 63 |
| 65 VP9Decoder *vp9_decoder_create(BufferPool *const pool) { | 64 VP9Decoder *vp9_decoder_create() { |
| 66 VP9Decoder *volatile const pbi = vpx_memalign(32, sizeof(*pbi)); | 65 VP9Decoder *volatile const pbi = vpx_memalign(32, sizeof(*pbi)); |
| 67 VP9_COMMON *volatile const cm = pbi ? &pbi->common : NULL; | 66 VP9_COMMON *volatile const cm = pbi ? &pbi->common : NULL; |
| 68 | 67 |
| 69 if (!cm) | 68 if (!cm) |
| 70 return NULL; | 69 return NULL; |
| 71 | 70 |
| 72 vp9_zero(*pbi); | 71 vp9_zero(*pbi); |
| 73 | 72 |
| 74 if (setjmp(cm->error.jmp)) { | 73 if (setjmp(cm->error.jmp)) { |
| 75 cm->error.setjmp = 0; | 74 cm->error.setjmp = 0; |
| 76 vp9_decoder_remove(pbi); | 75 vp9_decoder_remove(pbi); |
| 77 return NULL; | 76 return NULL; |
| 78 } | 77 } |
| 79 | 78 |
| 80 cm->error.setjmp = 1; | 79 cm->error.setjmp = 1; |
| 81 | 80 |
| 82 CHECK_MEM_ERROR(cm, cm->fc, | 81 CHECK_MEM_ERROR(cm, cm->fc, |
| 83 (FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc))); | 82 (FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc))); |
| 84 CHECK_MEM_ERROR(cm, cm->frame_contexts, | 83 CHECK_MEM_ERROR(cm, cm->frame_contexts, |
| 85 (FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS, | 84 (FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS, |
| 86 sizeof(*cm->frame_contexts))); | 85 sizeof(*cm->frame_contexts))); |
| 87 | 86 |
| 88 pbi->need_resync = 1; | 87 pbi->need_resync = 1; |
| 89 once(initialize_dec); | 88 once(initialize_dec); |
| 90 | 89 |
| 91 // Initialize the references to not point to any frame buffers. | 90 // Initialize the references to not point to any frame buffers. |
| 92 vpx_memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); | 91 vpx_memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); |
| 93 vpx_memset(&cm->next_ref_frame_map, -1, sizeof(cm->next_ref_frame_map)); | |
| 94 | 92 |
| 95 cm->current_video_frame = 0; | 93 cm->current_video_frame = 0; |
| 96 pbi->ready_for_new_data = 1; | 94 pbi->ready_for_new_data = 1; |
| 97 pbi->common.buffer_pool = pool; | |
| 98 | |
| 99 cm->bit_depth = VPX_BITS_8; | 95 cm->bit_depth = VPX_BITS_8; |
| 100 cm->dequant_bit_depth = VPX_BITS_8; | 96 cm->dequant_bit_depth = VPX_BITS_8; |
| 101 | 97 |
| 102 cm->alloc_mi = vp9_dec_alloc_mi; | 98 cm->alloc_mi = vp9_dec_alloc_mi; |
| 103 cm->free_mi = vp9_dec_free_mi; | 99 cm->free_mi = vp9_dec_free_mi; |
| 104 cm->setup_mi = vp9_dec_setup_mi; | 100 cm->setup_mi = vp9_dec_setup_mi; |
| 105 | 101 |
| 106 // vp9_init_dequantizer() is first called here. Add check in | 102 // vp9_init_dequantizer() is first called here. Add check in |
| 107 // frame_init_dequantizer() to avoid unnecessary calling of | 103 // frame_init_dequantizer() to avoid unnecessary calling of |
| 108 // vp9_init_dequantizer() for every frame. | 104 // vp9_init_dequantizer() for every frame. |
| 109 vp9_init_dequantizer(cm); | 105 vp9_init_dequantizer(cm); |
| 110 | 106 |
| 111 vp9_loop_filter_init(cm); | 107 vp9_loop_filter_init(cm); |
| 112 | 108 |
| 113 cm->error.setjmp = 0; | 109 cm->error.setjmp = 0; |
| 114 | 110 |
| 115 vp9_get_worker_interface()->init(&pbi->lf_worker); | 111 vp9_get_worker_interface()->init(&pbi->lf_worker); |
| 116 | 112 |
| 117 return pbi; | 113 return pbi; |
| 118 } | 114 } |
| 119 | 115 |
| 120 void vp9_decoder_remove(VP9Decoder *pbi) { | 116 void vp9_decoder_remove(VP9Decoder *pbi) { |
| 117 VP9_COMMON *const cm = &pbi->common; |
| 121 int i; | 118 int i; |
| 122 | 119 |
| 123 vp9_get_worker_interface()->end(&pbi->lf_worker); | 120 vp9_get_worker_interface()->end(&pbi->lf_worker); |
| 124 vpx_free(pbi->lf_worker.data1); | 121 vpx_free(pbi->lf_worker.data1); |
| 125 vpx_free(pbi->tile_data); | 122 vpx_free(pbi->tile_data); |
| 126 for (i = 0; i < pbi->num_tile_workers; ++i) { | 123 for (i = 0; i < pbi->num_tile_workers; ++i) { |
| 127 VP9Worker *const worker = &pbi->tile_workers[i]; | 124 VP9Worker *const worker = &pbi->tile_workers[i]; |
| 128 vp9_get_worker_interface()->end(worker); | 125 vp9_get_worker_interface()->end(worker); |
| 129 } | 126 } |
| 130 vpx_free(pbi->tile_worker_data); | 127 vpx_free(pbi->tile_worker_data); |
| 131 vpx_free(pbi->tile_worker_info); | 128 vpx_free(pbi->tile_worker_info); |
| 132 vpx_free(pbi->tile_workers); | 129 vpx_free(pbi->tile_workers); |
| 133 | 130 |
| 134 if (pbi->num_tile_workers > 0) { | 131 if (pbi->num_tile_workers > 0) { |
| 135 vp9_loop_filter_dealloc(&pbi->lf_row_sync); | 132 vp9_loop_filter_dealloc(&pbi->lf_row_sync); |
| 136 } | 133 } |
| 137 | 134 |
| 135 vp9_remove_common(cm); |
| 138 vpx_free(pbi); | 136 vpx_free(pbi); |
| 139 } | 137 } |
| 140 | 138 |
| 141 static int equal_dimensions(const YV12_BUFFER_CONFIG *a, | 139 static int equal_dimensions(const YV12_BUFFER_CONFIG *a, |
| 142 const YV12_BUFFER_CONFIG *b) { | 140 const YV12_BUFFER_CONFIG *b) { |
| 143 return a->y_height == b->y_height && a->y_width == b->y_width && | 141 return a->y_height == b->y_height && a->y_width == b->y_width && |
| 144 a->uv_height == b->uv_height && a->uv_width == b->uv_width; | 142 a->uv_height == b->uv_height && a->uv_width == b->uv_width; |
| 145 } | 143 } |
| 146 | 144 |
| 147 vpx_codec_err_t vp9_copy_reference_dec(VP9Decoder *pbi, | 145 vpx_codec_err_t vp9_copy_reference_dec(VP9Decoder *pbi, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 172 } | 170 } |
| 173 | 171 |
| 174 return cm->error.error_code; | 172 return cm->error.error_code; |
| 175 } | 173 } |
| 176 | 174 |
| 177 | 175 |
| 178 vpx_codec_err_t vp9_set_reference_dec(VP9_COMMON *cm, | 176 vpx_codec_err_t vp9_set_reference_dec(VP9_COMMON *cm, |
| 179 VP9_REFFRAME ref_frame_flag, | 177 VP9_REFFRAME ref_frame_flag, |
| 180 YV12_BUFFER_CONFIG *sd) { | 178 YV12_BUFFER_CONFIG *sd) { |
| 181 RefBuffer *ref_buf = NULL; | 179 RefBuffer *ref_buf = NULL; |
| 182 RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; | |
| 183 | 180 |
| 184 // TODO(jkoleszar): The decoder doesn't have any real knowledge of what the | 181 // TODO(jkoleszar): The decoder doesn't have any real knowledge of what the |
| 185 // encoder is using the frame buffers for. This is just a stub to keep the | 182 // encoder is using the frame buffers for. This is just a stub to keep the |
| 186 // vpxenc --test-decode functionality working, and will be replaced in a | 183 // vpxenc --test-decode functionality working, and will be replaced in a |
| 187 // later commit that adds VP9-specific controls for this functionality. | 184 // later commit that adds VP9-specific controls for this functionality. |
| 188 if (ref_frame_flag == VP9_LAST_FLAG) { | 185 if (ref_frame_flag == VP9_LAST_FLAG) { |
| 189 ref_buf = &cm->frame_refs[0]; | 186 ref_buf = &cm->frame_refs[0]; |
| 190 } else if (ref_frame_flag == VP9_GOLD_FLAG) { | 187 } else if (ref_frame_flag == VP9_GOLD_FLAG) { |
| 191 ref_buf = &cm->frame_refs[1]; | 188 ref_buf = &cm->frame_refs[1]; |
| 192 } else if (ref_frame_flag == VP9_ALT_FLAG) { | 189 } else if (ref_frame_flag == VP9_ALT_FLAG) { |
| 193 ref_buf = &cm->frame_refs[2]; | 190 ref_buf = &cm->frame_refs[2]; |
| 194 } else { | 191 } else { |
| 195 vpx_internal_error(&cm->error, VPX_CODEC_ERROR, | 192 vpx_internal_error(&cm->error, VPX_CODEC_ERROR, |
| 196 "Invalid reference frame"); | 193 "Invalid reference frame"); |
| 197 return cm->error.error_code; | 194 return cm->error.error_code; |
| 198 } | 195 } |
| 199 | 196 |
| 200 if (!equal_dimensions(ref_buf->buf, sd)) { | 197 if (!equal_dimensions(ref_buf->buf, sd)) { |
| 201 vpx_internal_error(&cm->error, VPX_CODEC_ERROR, | 198 vpx_internal_error(&cm->error, VPX_CODEC_ERROR, |
| 202 "Incorrect buffer dimensions"); | 199 "Incorrect buffer dimensions"); |
| 203 } else { | 200 } else { |
| 204 int *ref_fb_ptr = &ref_buf->idx; | 201 int *ref_fb_ptr = &ref_buf->idx; |
| 205 | 202 |
| 206 // Find an empty frame buffer. | 203 // Find an empty frame buffer. |
| 207 const int free_fb = get_free_fb(cm); | 204 const int free_fb = get_free_fb(cm); |
| 208 // Decrease ref_count since it will be increased again in | 205 // Decrease ref_count since it will be increased again in |
| 209 // ref_cnt_fb() below. | 206 // ref_cnt_fb() below. |
| 210 --frame_bufs[free_fb].ref_count; | 207 cm->frame_bufs[free_fb].ref_count--; |
| 211 | 208 |
| 212 // Manage the reference counters and copy image. | 209 // Manage the reference counters and copy image. |
| 213 ref_cnt_fb(frame_bufs, ref_fb_ptr, free_fb); | 210 ref_cnt_fb(cm->frame_bufs, ref_fb_ptr, free_fb); |
| 214 ref_buf->buf = &frame_bufs[*ref_fb_ptr].buf; | 211 ref_buf->buf = &cm->frame_bufs[*ref_fb_ptr].buf; |
| 215 vp8_yv12_copy_frame(sd, ref_buf->buf); | 212 vp8_yv12_copy_frame(sd, ref_buf->buf); |
| 216 } | 213 } |
| 217 | 214 |
| 218 return cm->error.error_code; | 215 return cm->error.error_code; |
| 219 } | 216 } |
| 220 | 217 |
| 221 /* If any buffer updating is signaled it should be done here. */ | 218 /* If any buffer updating is signaled it should be done here. */ |
| 222 static void swap_frame_buffers(VP9Decoder *pbi) { | 219 static void swap_frame_buffers(VP9Decoder *pbi) { |
| 223 int ref_index = 0, mask; | 220 int ref_index = 0, mask; |
| 224 VP9_COMMON *const cm = &pbi->common; | 221 VP9_COMMON *const cm = &pbi->common; |
| 225 BufferPool *const pool = cm->buffer_pool; | |
| 226 RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; | |
| 227 | 222 |
| 228 lock_buffer_pool(pool); | |
| 229 for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { | 223 for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { |
| 230 const int old_idx = cm->ref_frame_map[ref_index]; | 224 if (mask & 1) { |
| 231 // Current thread releases the holding of reference frame. | 225 const int old_idx = cm->ref_frame_map[ref_index]; |
| 232 decrease_ref_count(old_idx, frame_bufs, pool); | 226 ref_cnt_fb(cm->frame_bufs, &cm->ref_frame_map[ref_index], |
| 233 | 227 cm->new_fb_idx); |
| 234 // Release the reference frame in reference map. | 228 if (old_idx >= 0 && cm->frame_bufs[old_idx].ref_count == 0) |
| 235 if ((mask & 1) && old_idx >= 0) { | 229 cm->release_fb_cb(cm->cb_priv, |
| 236 decrease_ref_count(old_idx, frame_bufs, pool); | 230 &cm->frame_bufs[old_idx].raw_frame_buffer); |
| 237 } | 231 } |
| 238 cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index]; | |
| 239 ++ref_index; | 232 ++ref_index; |
| 240 } | 233 } |
| 241 | 234 |
| 242 // Current thread releases the holding of reference frame. | |
| 243 for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) { | |
| 244 const int old_idx = cm->ref_frame_map[ref_index]; | |
| 245 decrease_ref_count(old_idx, frame_bufs, pool); | |
| 246 cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index]; | |
| 247 } | |
| 248 unlock_buffer_pool(pool); | |
| 249 pbi->hold_ref_buf = 0; | |
| 250 cm->frame_to_show = get_frame_new_buffer(cm); | 235 cm->frame_to_show = get_frame_new_buffer(cm); |
| 251 | 236 cm->frame_bufs[cm->new_fb_idx].ref_count--; |
| 252 if (!pbi->frame_parallel_decode || !cm->show_frame) { | |
| 253 lock_buffer_pool(pool); | |
| 254 --frame_bufs[cm->new_fb_idx].ref_count; | |
| 255 unlock_buffer_pool(pool); | |
| 256 } | |
| 257 | 237 |
| 258 // Invalidate these references until the next frame starts. | 238 // Invalidate these references until the next frame starts. |
| 259 for (ref_index = 0; ref_index < 3; ref_index++) | 239 for (ref_index = 0; ref_index < 3; ref_index++) |
| 260 cm->frame_refs[ref_index].idx = INT_MAX; | 240 cm->frame_refs[ref_index].idx = -1; |
| 261 } | 241 } |
| 262 | 242 |
| 263 int vp9_receive_compressed_data(VP9Decoder *pbi, | 243 int vp9_receive_compressed_data(VP9Decoder *pbi, |
| 264 size_t size, const uint8_t **psource) { | 244 size_t size, const uint8_t **psource) { |
| 265 VP9_COMMON *volatile const cm = &pbi->common; | 245 VP9_COMMON *volatile const cm = &pbi->common; |
| 266 BufferPool *const pool = cm->buffer_pool; | |
| 267 RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; | |
| 268 const uint8_t *source = *psource; | 246 const uint8_t *source = *psource; |
| 269 int retcode = 0; | 247 int retcode = 0; |
| 248 |
| 270 cm->error.error_code = VPX_CODEC_OK; | 249 cm->error.error_code = VPX_CODEC_OK; |
| 271 | 250 |
| 272 if (size == 0) { | 251 if (size == 0) { |
| 273 // This is used to signal that we are missing frames. | 252 // This is used to signal that we are missing frames. |
| 274 // We do not know if the missing frame(s) was supposed to update | 253 // We do not know if the missing frame(s) was supposed to update |
| 275 // any of the reference buffers, but we act conservative and | 254 // any of the reference buffers, but we act conservative and |
| 276 // mark only the last buffer as corrupted. | 255 // mark only the last buffer as corrupted. |
| 277 // | 256 // |
| 278 // TODO(jkoleszar): Error concealment is undefined and non-normative | 257 // TODO(jkoleszar): Error concealment is undefined and non-normative |
| 279 // at this point, but if it becomes so, [0] may not always be the correct | 258 // at this point, but if it becomes so, [0] may not always be the correct |
| 280 // thing to do here. | 259 // thing to do here. |
| 281 if (cm->frame_refs[0].idx > 0) | 260 if (cm->frame_refs[0].idx > 0) |
| 282 cm->frame_refs[0].buf->corrupted = 1; | 261 cm->frame_refs[0].buf->corrupted = 1; |
| 283 } | 262 } |
| 284 | 263 |
| 285 pbi->ready_for_new_data = 0; | 264 pbi->ready_for_new_data = 0; |
| 286 | 265 |
| 287 // Check if the previous frame was a frame without any references to it. | 266 // Check if the previous frame was a frame without any references to it. |
| 288 // Release frame buffer if not decoding in frame parallel mode. | 267 if (cm->new_fb_idx >= 0 && cm->frame_bufs[cm->new_fb_idx].ref_count == 0) |
| 289 if (!pbi->frame_parallel_decode && cm->new_fb_idx >= 0 | 268 cm->release_fb_cb(cm->cb_priv, |
| 290 && frame_bufs[cm->new_fb_idx].ref_count == 0) | 269 &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer); |
| 291 pool->release_fb_cb(pool->cb_priv, | |
| 292 &frame_bufs[cm->new_fb_idx].raw_frame_buffer); | |
| 293 cm->new_fb_idx = get_free_fb(cm); | 270 cm->new_fb_idx = get_free_fb(cm); |
| 294 | 271 |
| 295 // Assign a MV array to the frame buffer. | 272 // Assign a MV array to the frame buffer. |
| 296 cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx]; | 273 cm->cur_frame = &cm->frame_bufs[cm->new_fb_idx]; |
| 297 | |
| 298 pbi->hold_ref_buf = 0; | |
| 299 if (pbi->frame_parallel_decode) { | |
| 300 VP9Worker *const worker = pbi->frame_worker_owner; | |
| 301 vp9_frameworker_lock_stats(worker); | |
| 302 frame_bufs[cm->new_fb_idx].frame_worker_owner = worker; | |
| 303 // Reset decoding progress. | |
| 304 pbi->cur_buf = &frame_bufs[cm->new_fb_idx]; | |
| 305 pbi->cur_buf->row = -1; | |
| 306 pbi->cur_buf->col = -1; | |
| 307 vp9_frameworker_unlock_stats(worker); | |
| 308 } else { | |
| 309 pbi->cur_buf = &frame_bufs[cm->new_fb_idx]; | |
| 310 } | |
| 311 | |
| 312 | 274 |
| 313 if (setjmp(cm->error.jmp)) { | 275 if (setjmp(cm->error.jmp)) { |
| 314 const VP9WorkerInterface *const winterface = vp9_get_worker_interface(); | 276 const VP9WorkerInterface *const winterface = vp9_get_worker_interface(); |
| 315 VP9_COMMON *const cm = &pbi->common; | |
| 316 int i; | 277 int i; |
| 317 | 278 |
| 279 pbi->need_resync = 1; |
| 318 cm->error.setjmp = 0; | 280 cm->error.setjmp = 0; |
| 319 pbi->ready_for_new_data = 1; | |
| 320 | 281 |
| 321 // Synchronize all threads immediately as a subsequent decode call may | 282 // Synchronize all threads immediately as a subsequent decode call may |
| 322 // cause a resize invalidating some allocations. | 283 // cause a resize invalidating some allocations. |
| 323 winterface->sync(&pbi->lf_worker); | 284 winterface->sync(&pbi->lf_worker); |
| 324 for (i = 0; i < pbi->num_tile_workers; ++i) { | 285 for (i = 0; i < pbi->num_tile_workers; ++i) { |
| 325 winterface->sync(&pbi->tile_workers[i]); | 286 winterface->sync(&pbi->tile_workers[i]); |
| 326 } | 287 } |
| 327 | 288 |
| 328 lock_buffer_pool(pool); | 289 vp9_clear_system_state(); |
| 329 // Release all the reference buffers if worker thread is holding them. | |
| 330 if (pbi->hold_ref_buf == 1) { | |
| 331 int ref_index = 0, mask; | |
| 332 BufferPool *const pool = cm->buffer_pool; | |
| 333 RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; | |
| 334 for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { | |
| 335 const int old_idx = cm->ref_frame_map[ref_index]; | |
| 336 // Current thread releases the holding of reference frame. | |
| 337 decrease_ref_count(old_idx, frame_bufs, pool); | |
| 338 | 290 |
| 339 // Release the reference frame in reference map. | 291 if (cm->new_fb_idx > 0 && cm->frame_bufs[cm->new_fb_idx].ref_count > 0) |
| 340 if ((mask & 1) && old_idx >= 0) { | 292 cm->frame_bufs[cm->new_fb_idx].ref_count--; |
| 341 decrease_ref_count(old_idx, frame_bufs, pool); | |
| 342 } | |
| 343 ++ref_index; | |
| 344 } | |
| 345 | 293 |
| 346 // Current thread releases the holding of reference frame. | |
| 347 for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) { | |
| 348 const int old_idx = cm->ref_frame_map[ref_index]; | |
| 349 decrease_ref_count(old_idx, frame_bufs, pool); | |
| 350 } | |
| 351 pbi->hold_ref_buf = 0; | |
| 352 } | |
| 353 // Release current frame. | |
| 354 decrease_ref_count(cm->new_fb_idx, frame_bufs, pool); | |
| 355 unlock_buffer_pool(pool); | |
| 356 | |
| 357 vp9_clear_system_state(); | |
| 358 return -1; | 294 return -1; |
| 359 } | 295 } |
| 360 | 296 |
| 361 cm->error.setjmp = 1; | 297 cm->error.setjmp = 1; |
| 298 |
| 362 vp9_decode_frame(pbi, source, source + size, psource); | 299 vp9_decode_frame(pbi, source, source + size, psource); |
| 363 | 300 |
| 364 swap_frame_buffers(pbi); | 301 swap_frame_buffers(pbi); |
| 365 | 302 |
| 366 vp9_clear_system_state(); | 303 vp9_clear_system_state(); |
| 367 | 304 |
| 305 cm->last_width = cm->width; |
| 306 cm->last_height = cm->height; |
| 307 |
| 368 if (!cm->show_existing_frame) { | 308 if (!cm->show_existing_frame) { |
| 369 cm->last_show_frame = cm->show_frame; | 309 cm->last_show_frame = cm->show_frame; |
| 370 cm->prev_frame = cm->cur_frame; | 310 cm->prev_frame = cm->cur_frame; |
| 371 if (cm->seg.enabled && !pbi->frame_parallel_decode) | |
| 372 vp9_swap_current_and_last_seg_map(cm); | |
| 373 } | 311 } |
| 374 | 312 |
| 375 // Update progress in frame parallel decode. | 313 if (cm->show_frame) |
| 376 if (pbi->frame_parallel_decode) { | 314 cm->current_video_frame++; |
| 377 // Need to lock the mutex here as another thread may | |
| 378 // be accessing this buffer. | |
| 379 VP9Worker *const worker = pbi->frame_worker_owner; | |
| 380 FrameWorkerData *const frame_worker_data = worker->data1; | |
| 381 vp9_frameworker_lock_stats(worker); | |
| 382 | |
| 383 if (cm->show_frame) { | |
| 384 cm->current_video_frame++; | |
| 385 } | |
| 386 frame_worker_data->frame_decoded = 1; | |
| 387 frame_worker_data->frame_context_ready = 1; | |
| 388 vp9_frameworker_signal_stats(worker); | |
| 389 vp9_frameworker_unlock_stats(worker); | |
| 390 } else { | |
| 391 cm->last_width = cm->width; | |
| 392 cm->last_height = cm->height; | |
| 393 if (cm->show_frame) { | |
| 394 cm->current_video_frame++; | |
| 395 } | |
| 396 } | |
| 397 | 315 |
| 398 cm->error.setjmp = 0; | 316 cm->error.setjmp = 0; |
| 399 return retcode; | 317 return retcode; |
| 400 } | 318 } |
| 401 | 319 |
| 402 int vp9_get_raw_frame(VP9Decoder *pbi, YV12_BUFFER_CONFIG *sd, | 320 int vp9_get_raw_frame(VP9Decoder *pbi, YV12_BUFFER_CONFIG *sd, |
| 403 vp9_ppflags_t *flags) { | 321 vp9_ppflags_t *flags) { |
| 404 VP9_COMMON *const cm = &pbi->common; | 322 VP9_COMMON *const cm = &pbi->common; |
| 405 int ret = -1; | 323 int ret = -1; |
| 406 #if !CONFIG_VP9_POSTPROC | 324 #if !CONFIG_VP9_POSTPROC |
| 407 (void)*flags; | 325 (void)*flags; |
| 408 #endif | 326 #endif |
| 409 | 327 |
| 410 if (pbi->ready_for_new_data == 1) | 328 if (pbi->ready_for_new_data == 1) |
| 411 return ret; | 329 return ret; |
| 412 | 330 |
| 413 pbi->ready_for_new_data = 1; | 331 pbi->ready_for_new_data = 1; |
| 414 | 332 |
| 415 /* no raw frame to show!!! */ | 333 /* no raw frame to show!!! */ |
| 416 if (!cm->show_frame) | 334 if (!cm->show_frame) |
| 417 return ret; | 335 return ret; |
| 418 | 336 |
| 419 pbi->ready_for_new_data = 1; | |
| 420 | |
| 421 #if CONFIG_VP9_POSTPROC | 337 #if CONFIG_VP9_POSTPROC |
| 422 if (!cm->show_existing_frame) { | 338 if (!cm->show_existing_frame) { |
| 423 ret = vp9_post_proc_frame(cm, sd, flags); | 339 ret = vp9_post_proc_frame(cm, sd, flags); |
| 424 } else { | 340 } else { |
| 425 *sd = *cm->frame_to_show; | 341 *sd = *cm->frame_to_show; |
| 426 ret = 0; | 342 ret = 0; |
| 427 } | 343 } |
| 428 #else | 344 #else |
| 429 *sd = *cm->frame_to_show; | 345 *sd = *cm->frame_to_show; |
| 430 ret = 0; | 346 ret = 0; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 | 405 |
| 490 for (j = 0; j < mag; ++j) | 406 for (j = 0; j < mag; ++j) |
| 491 this_sz |= (*x++) << (j * 8); | 407 this_sz |= (*x++) << (j * 8); |
| 492 sizes[i] = this_sz; | 408 sizes[i] = this_sz; |
| 493 } | 409 } |
| 494 *count = frames; | 410 *count = frames; |
| 495 } | 411 } |
| 496 } | 412 } |
| 497 return VPX_CODEC_OK; | 413 return VPX_CODEC_OK; |
| 498 } | 414 } |
| OLD | NEW |