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