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 "vp9/common/vp9_onyxc_int.h" | 15 #include "vp9/common/vp9_onyxc_int.h" |
16 #if CONFIG_VP9_POSTPROC | 16 #if CONFIG_VP9_POSTPROC |
17 #include "vp9/common/vp9_postproc.h" | 17 #include "vp9/common/vp9_postproc.h" |
18 #endif | 18 #endif |
19 #include "vp9/decoder/vp9_onyxd.h" | 19 #include "vp9/decoder/vp9_onyxd.h" |
20 #include "vp9/decoder/vp9_onyxd_int.h" | 20 #include "vp9/decoder/vp9_onyxd_int.h" |
21 #include "vpx_mem/vpx_mem.h" | 21 #include "vpx_mem/vpx_mem.h" |
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_quant_common.h" | 24 #include "vp9/common/vp9_quant_common.h" |
25 #include "vpx_scale/vpx_scale.h" | 25 #include "vpx_scale/vpx_scale.h" |
26 #include "vp9/common/vp9_systemdependent.h" | 26 #include "vp9/common/vp9_systemdependent.h" |
27 #include "vpx_ports/vpx_timer.h" | 27 #include "vpx_ports/vpx_timer.h" |
28 #include "vp9/decoder/vp9_decodeframe.h" | 28 #include "vp9/decoder/vp9_decodeframe.h" |
29 #include "vp9/decoder/vp9_detokenize.h" | 29 #include "vp9/decoder/vp9_detokenize.h" |
| 30 #include "vp9/decoder/vp9_dthread.h" |
30 #include "./vpx_scale_rtcd.h" | 31 #include "./vpx_scale_rtcd.h" |
31 | 32 |
32 #define WRITE_RECON_BUFFER 0 | 33 #define WRITE_RECON_BUFFER 0 |
33 #if WRITE_RECON_BUFFER == 1 | 34 #if WRITE_RECON_BUFFER == 1 |
34 static void recon_write_yuv_frame(const char *name, | 35 static void recon_write_yuv_frame(const char *name, |
35 const YV12_BUFFER_CONFIG *s, | 36 const YV12_BUFFER_CONFIG *s, |
36 int w, int _h) { | 37 int w, int _h) { |
37 FILE *yuv_file = fopen(name, "ab"); | 38 FILE *yuv_file = fopen(name, "ab"); |
38 const uint8_t *src = s->y_buffer; | 39 const uint8_t *src = s->y_buffer; |
39 int h = _h; | 40 int h = _h; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 vp9_remove_common(&pbi->common); | 171 vp9_remove_common(&pbi->common); |
171 vp9_worker_end(&pbi->lf_worker); | 172 vp9_worker_end(&pbi->lf_worker); |
172 vpx_free(pbi->lf_worker.data1); | 173 vpx_free(pbi->lf_worker.data1); |
173 for (i = 0; i < pbi->num_tile_workers; ++i) { | 174 for (i = 0; i < pbi->num_tile_workers; ++i) { |
174 VP9Worker *const worker = &pbi->tile_workers[i]; | 175 VP9Worker *const worker = &pbi->tile_workers[i]; |
175 vp9_worker_end(worker); | 176 vp9_worker_end(worker); |
176 vpx_free(worker->data1); | 177 vpx_free(worker->data1); |
177 vpx_free(worker->data2); | 178 vpx_free(worker->data2); |
178 } | 179 } |
179 vpx_free(pbi->tile_workers); | 180 vpx_free(pbi->tile_workers); |
| 181 |
| 182 if (pbi->num_tile_workers) { |
| 183 VP9_COMMON *const cm = &pbi->common; |
| 184 const int sb_rows = |
| 185 mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; |
| 186 VP9LfSync *const lf_sync = &pbi->lf_row_sync; |
| 187 |
| 188 vp9_loop_filter_dealloc(lf_sync, sb_rows); |
| 189 } |
| 190 |
180 vpx_free(pbi->mi_streams); | 191 vpx_free(pbi->mi_streams); |
181 vpx_free(pbi->above_context[0]); | 192 vpx_free(pbi->above_context[0]); |
182 vpx_free(pbi->above_seg_context); | 193 vpx_free(pbi->above_seg_context); |
183 vpx_free(pbi); | 194 vpx_free(pbi); |
184 } | 195 } |
185 | 196 |
186 static int equal_dimensions(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) { | 197 static int equal_dimensions(const YV12_BUFFER_CONFIG *a, |
| 198 const YV12_BUFFER_CONFIG *b) { |
187 return a->y_height == b->y_height && a->y_width == b->y_width && | 199 return a->y_height == b->y_height && a->y_width == b->y_width && |
188 a->uv_height == b->uv_height && a->uv_width == b->uv_width; | 200 a->uv_height == b->uv_height && a->uv_width == b->uv_width; |
189 } | 201 } |
190 | 202 |
191 vpx_codec_err_t vp9_copy_reference_dec(VP9D_PTR ptr, | 203 vpx_codec_err_t vp9_copy_reference_dec(VP9D_PTR ptr, |
192 VP9_REFFRAME ref_frame_flag, | 204 VP9_REFFRAME ref_frame_flag, |
193 YV12_BUFFER_CONFIG *sd) { | 205 YV12_BUFFER_CONFIG *sd) { |
194 VP9D_COMP *pbi = (VP9D_COMP *) ptr; | 206 VP9D_COMP *pbi = (VP9D_COMP *) ptr; |
195 VP9_COMMON *cm = &pbi->common; | 207 VP9_COMMON *cm = &pbi->common; |
196 | 208 |
197 /* TODO(jkoleszar): The decoder doesn't have any real knowledge of what the | 209 /* TODO(jkoleszar): The decoder doesn't have any real knowledge of what the |
198 * encoder is using the frame buffers for. This is just a stub to keep the | 210 * encoder is using the frame buffers for. This is just a stub to keep the |
199 * vpxenc --test-decode functionality working, and will be replaced in a | 211 * vpxenc --test-decode functionality working, and will be replaced in a |
200 * later commit that adds VP9-specific controls for this functionality. | 212 * later commit that adds VP9-specific controls for this functionality. |
201 */ | 213 */ |
202 if (ref_frame_flag == VP9_LAST_FLAG) { | 214 if (ref_frame_flag == VP9_LAST_FLAG) { |
203 YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[cm->ref_frame_map[0]]; | 215 const YV12_BUFFER_CONFIG *const cfg = |
| 216 &cm->frame_bufs[cm->ref_frame_map[0]].buf; |
204 if (!equal_dimensions(cfg, sd)) | 217 if (!equal_dimensions(cfg, sd)) |
205 vpx_internal_error(&cm->error, VPX_CODEC_ERROR, | 218 vpx_internal_error(&cm->error, VPX_CODEC_ERROR, |
206 "Incorrect buffer dimensions"); | 219 "Incorrect buffer dimensions"); |
207 else | 220 else |
208 vp8_yv12_copy_frame(cfg, sd); | 221 vp8_yv12_copy_frame(cfg, sd); |
209 } else { | 222 } else { |
210 vpx_internal_error(&cm->error, VPX_CODEC_ERROR, | 223 vpx_internal_error(&cm->error, VPX_CODEC_ERROR, |
211 "Invalid reference frame"); | 224 "Invalid reference frame"); |
212 } | 225 } |
213 | 226 |
(...skipping 25 matching lines...) Expand all Loading... |
239 } | 252 } |
240 | 253 |
241 if (!equal_dimensions(ref_buf->buf, sd)) { | 254 if (!equal_dimensions(ref_buf->buf, sd)) { |
242 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, | 255 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, |
243 "Incorrect buffer dimensions"); | 256 "Incorrect buffer dimensions"); |
244 } else { | 257 } else { |
245 int *ref_fb_ptr = &ref_buf->idx; | 258 int *ref_fb_ptr = &ref_buf->idx; |
246 | 259 |
247 // Find an empty frame buffer. | 260 // Find an empty frame buffer. |
248 const int free_fb = get_free_fb(cm); | 261 const int free_fb = get_free_fb(cm); |
249 // Decrease fb_idx_ref_cnt since it will be increased again in | 262 // Decrease ref_count since it will be increased again in |
250 // ref_cnt_fb() below. | 263 // ref_cnt_fb() below. |
251 cm->fb_idx_ref_cnt[free_fb]--; | 264 cm->frame_bufs[free_fb].ref_count--; |
252 | 265 |
253 // Manage the reference counters and copy image. | 266 // Manage the reference counters and copy image. |
254 ref_cnt_fb(cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb); | 267 ref_cnt_fb(cm->frame_bufs, ref_fb_ptr, free_fb); |
255 ref_buf->buf = &cm->yv12_fb[*ref_fb_ptr]; | 268 ref_buf->buf = &cm->frame_bufs[*ref_fb_ptr].buf; |
256 vp8_yv12_copy_frame(sd, ref_buf->buf); | 269 vp8_yv12_copy_frame(sd, ref_buf->buf); |
257 } | 270 } |
258 | 271 |
259 return pbi->common.error.error_code; | 272 return pbi->common.error.error_code; |
260 } | 273 } |
261 | 274 |
262 | 275 |
263 int vp9_get_reference_dec(VP9D_PTR ptr, int index, YV12_BUFFER_CONFIG **fb) { | 276 int vp9_get_reference_dec(VP9D_PTR ptr, int index, YV12_BUFFER_CONFIG **fb) { |
264 VP9D_COMP *pbi = (VP9D_COMP *) ptr; | 277 VP9D_COMP *pbi = (VP9D_COMP *) ptr; |
265 VP9_COMMON *cm = &pbi->common; | 278 VP9_COMMON *cm = &pbi->common; |
266 | 279 |
267 if (index < 0 || index >= REF_FRAMES) | 280 if (index < 0 || index >= REF_FRAMES) |
268 return -1; | 281 return -1; |
269 | 282 |
270 *fb = &cm->yv12_fb[cm->ref_frame_map[index]]; | 283 *fb = &cm->frame_bufs[cm->ref_frame_map[index]].buf; |
271 return 0; | 284 return 0; |
272 } | 285 } |
273 | 286 |
274 /* If any buffer updating is signaled it should be done here. */ | 287 /* If any buffer updating is signaled it should be done here. */ |
275 static void swap_frame_buffers(VP9D_COMP *pbi) { | 288 static void swap_frame_buffers(VP9D_COMP *pbi) { |
276 int ref_index = 0, mask; | 289 int ref_index = 0, mask; |
277 VP9_COMMON *const cm = &pbi->common; | 290 VP9_COMMON *const cm = &pbi->common; |
278 | 291 |
279 for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { | 292 for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { |
280 if (mask & 1) | 293 if (mask & 1) { |
281 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->ref_frame_map[ref_index], | 294 const int old_idx = cm->ref_frame_map[ref_index]; |
| 295 ref_cnt_fb(cm->frame_bufs, &cm->ref_frame_map[ref_index], |
282 cm->new_fb_idx); | 296 cm->new_fb_idx); |
| 297 if (old_idx >= 0 && cm->frame_bufs[old_idx].ref_count == 0) |
| 298 cm->release_fb_cb(cm->cb_priv, |
| 299 &cm->frame_bufs[old_idx].raw_frame_buffer); |
| 300 } |
283 ++ref_index; | 301 ++ref_index; |
284 } | 302 } |
285 | 303 |
286 cm->frame_to_show = get_frame_new_buffer(cm); | 304 cm->frame_to_show = get_frame_new_buffer(cm); |
287 cm->fb_idx_ref_cnt[cm->new_fb_idx]--; | 305 cm->frame_bufs[cm->new_fb_idx].ref_count--; |
288 | 306 |
289 // Invalidate these references until the next frame starts. | 307 // Invalidate these references until the next frame starts. |
290 for (ref_index = 0; ref_index < 3; ref_index++) | 308 for (ref_index = 0; ref_index < 3; ref_index++) |
291 cm->frame_refs[ref_index].idx = INT_MAX; | 309 cm->frame_refs[ref_index].idx = INT_MAX; |
292 } | 310 } |
293 | 311 |
294 int vp9_receive_compressed_data(VP9D_PTR ptr, | 312 int vp9_receive_compressed_data(VP9D_PTR ptr, |
295 size_t size, const uint8_t **psource, | 313 size_t size, const uint8_t **psource, |
296 int64_t time_stamp) { | 314 int64_t time_stamp) { |
297 VP9D_COMP *pbi = (VP9D_COMP *) ptr; | 315 VP9D_COMP *pbi = (VP9D_COMP *) ptr; |
(...skipping 19 matching lines...) Expand all Loading... |
317 * mark only the last buffer as corrupted. | 335 * mark only the last buffer as corrupted. |
318 * | 336 * |
319 * TODO(jkoleszar): Error concealment is undefined and non-normative | 337 * TODO(jkoleszar): Error concealment is undefined and non-normative |
320 * at this point, but if it becomes so, [0] may not always be the correct | 338 * at this point, but if it becomes so, [0] may not always be the correct |
321 * thing to do here. | 339 * thing to do here. |
322 */ | 340 */ |
323 if (cm->frame_refs[0].idx != INT_MAX) | 341 if (cm->frame_refs[0].idx != INT_MAX) |
324 cm->frame_refs[0].buf->corrupted = 1; | 342 cm->frame_refs[0].buf->corrupted = 1; |
325 } | 343 } |
326 | 344 |
| 345 // Check if the previous frame was a frame without any references to it. |
| 346 if (cm->new_fb_idx >= 0 && cm->frame_bufs[cm->new_fb_idx].ref_count == 0) |
| 347 cm->release_fb_cb(cm->cb_priv, |
| 348 &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer); |
327 cm->new_fb_idx = get_free_fb(cm); | 349 cm->new_fb_idx = get_free_fb(cm); |
328 | 350 |
329 if (setjmp(cm->error.jmp)) { | 351 if (setjmp(cm->error.jmp)) { |
330 cm->error.setjmp = 0; | 352 cm->error.setjmp = 0; |
331 | 353 |
332 /* We do not know if the missing frame(s) was supposed to update | 354 /* We do not know if the missing frame(s) was supposed to update |
333 * any of the reference buffers, but we act conservative and | 355 * any of the reference buffers, but we act conservative and |
334 * mark only the last buffer as corrupted. | 356 * mark only the last buffer as corrupted. |
335 * | 357 * |
336 * TODO(jkoleszar): Error concealment is undefined and non-normative | 358 * TODO(jkoleszar): Error concealment is undefined and non-normative |
337 * at this point, but if it becomes so, [0] may not always be the correct | 359 * at this point, but if it becomes so, [0] may not always be the correct |
338 * thing to do here. | 360 * thing to do here. |
339 */ | 361 */ |
340 if (cm->frame_refs[0].idx != INT_MAX) | 362 if (cm->frame_refs[0].idx != INT_MAX) |
341 cm->frame_refs[0].buf->corrupted = 1; | 363 cm->frame_refs[0].buf->corrupted = 1; |
342 | 364 |
343 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) | 365 if (cm->frame_bufs[cm->new_fb_idx].ref_count > 0) |
344 cm->fb_idx_ref_cnt[cm->new_fb_idx]--; | 366 cm->frame_bufs[cm->new_fb_idx].ref_count--; |
345 | 367 |
346 return -1; | 368 return -1; |
347 } | 369 } |
348 | 370 |
349 cm->error.setjmp = 1; | 371 cm->error.setjmp = 1; |
350 | 372 |
351 retcode = vp9_decode_frame(pbi, psource); | 373 retcode = vp9_decode_frame(pbi, psource); |
352 | 374 |
353 if (retcode < 0) { | 375 if (retcode < 0) { |
354 cm->error.error_code = VPX_CODEC_ERROR; | 376 cm->error.error_code = VPX_CODEC_ERROR; |
355 cm->error.setjmp = 0; | 377 cm->error.setjmp = 0; |
356 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) | 378 if (cm->frame_bufs[cm->new_fb_idx].ref_count > 0) |
357 cm->fb_idx_ref_cnt[cm->new_fb_idx]--; | 379 cm->frame_bufs[cm->new_fb_idx].ref_count--; |
358 return retcode; | 380 return retcode; |
359 } | 381 } |
360 | 382 |
361 swap_frame_buffers(pbi); | 383 swap_frame_buffers(pbi); |
362 | 384 |
363 #if WRITE_RECON_BUFFER == 2 | 385 #if WRITE_RECON_BUFFER == 2 |
364 if (cm->show_frame) | 386 if (cm->show_frame) |
365 write_dx_frame_to_file(cm->frame_to_show, | 387 write_dx_frame_to_file(cm->frame_to_show, |
366 cm->current_video_frame); | 388 cm->current_video_frame); |
367 else | 389 else |
368 write_dx_frame_to_file(cm->frame_to_show, | 390 write_dx_frame_to_file(cm->frame_to_show, |
369 cm->current_video_frame + 1000); | 391 cm->current_video_frame + 1000); |
370 #endif | 392 #endif |
371 | 393 |
372 if (!pbi->do_loopfilter_inline) { | 394 if (!pbi->do_loopfilter_inline) { |
373 vp9_loop_filter_frame(cm, &pbi->mb, pbi->common.lf.filter_level, 0, 0); | 395 // If multiple threads are used to decode tiles, then we use those threads |
| 396 // to do parallel loopfiltering. |
| 397 if (pbi->num_tile_workers) { |
| 398 vp9_loop_filter_frame_mt(pbi, cm, &pbi->mb, cm->lf.filter_level, 0, 0); |
| 399 } else { |
| 400 vp9_loop_filter_frame(cm, &pbi->mb, cm->lf.filter_level, 0, 0); |
| 401 } |
374 } | 402 } |
375 | 403 |
376 #if WRITE_RECON_BUFFER == 2 | 404 #if WRITE_RECON_BUFFER == 2 |
377 if (cm->show_frame) | 405 if (cm->show_frame) |
378 write_dx_frame_to_file(cm->frame_to_show, | 406 write_dx_frame_to_file(cm->frame_to_show, |
379 cm->current_video_frame + 2000); | 407 cm->current_video_frame + 2000); |
380 else | 408 else |
381 write_dx_frame_to_file(cm->frame_to_show, | 409 write_dx_frame_to_file(cm->frame_to_show, |
382 cm->current_video_frame + 3000); | 410 cm->current_video_frame + 3000); |
383 #endif | 411 #endif |
384 | 412 |
385 #if WRITE_RECON_BUFFER == 1 | 413 #if WRITE_RECON_BUFFER == 1 |
386 if (cm->show_frame) | 414 if (cm->show_frame) |
387 recon_write_yuv_frame("recon.yuv", cm->frame_to_show, | 415 recon_write_yuv_frame("recon.yuv", cm->frame_to_show, |
388 cm->width, cm->height); | 416 cm->width, cm->height); |
389 #endif | 417 #endif |
390 | 418 |
391 vp9_clear_system_state(); | 419 vp9_clear_system_state(); |
392 | 420 |
393 cm->last_show_frame = cm->show_frame; | 421 cm->last_width = cm->width; |
| 422 cm->last_height = cm->height; |
| 423 |
| 424 if (!cm->show_existing_frame) |
| 425 cm->last_show_frame = cm->show_frame; |
394 if (cm->show_frame) { | 426 if (cm->show_frame) { |
395 if (!cm->show_existing_frame) { | 427 if (!cm->show_existing_frame) { |
396 // current mip will be the prev_mip for the next frame | 428 // current mip will be the prev_mip for the next frame |
397 MODE_INFO *temp = cm->prev_mip; | 429 MODE_INFO *temp = cm->prev_mip; |
398 MODE_INFO **temp2 = cm->prev_mi_grid_base; | 430 MODE_INFO **temp2 = cm->prev_mi_grid_base; |
399 cm->prev_mip = cm->mip; | 431 cm->prev_mip = cm->mip; |
400 cm->mip = temp; | 432 cm->mip = temp; |
401 cm->prev_mi_grid_base = cm->mi_grid_base; | 433 cm->prev_mi_grid_base = cm->mi_grid_base; |
402 cm->mi_grid_base = temp2; | 434 cm->mi_grid_base = temp2; |
403 | 435 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 | 484 |
453 ret = 0; | 485 ret = 0; |
454 } else { | 486 } else { |
455 ret = -1; | 487 ret = -1; |
456 } | 488 } |
457 | 489 |
458 #endif /*!CONFIG_POSTPROC*/ | 490 #endif /*!CONFIG_POSTPROC*/ |
459 vp9_clear_system_state(); | 491 vp9_clear_system_state(); |
460 return ret; | 492 return ret; |
461 } | 493 } |
OLD | NEW |