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 28 matching lines...) Expand all Loading... |
39 #if CONFIG_POSTPROC_VISUALIZER | 39 #if CONFIG_POSTPROC_VISUALIZER |
40 unsigned int dbg_postproc_flag; | 40 unsigned int dbg_postproc_flag; |
41 int dbg_color_ref_frame_flag; | 41 int dbg_color_ref_frame_flag; |
42 int dbg_color_mb_modes_flag; | 42 int dbg_color_mb_modes_flag; |
43 int dbg_color_b_modes_flag; | 43 int dbg_color_b_modes_flag; |
44 int dbg_display_mv_flag; | 44 int dbg_display_mv_flag; |
45 #endif | 45 #endif |
46 vpx_decrypt_cb decrypt_cb; | 46 vpx_decrypt_cb decrypt_cb; |
47 void *decrypt_state; | 47 void *decrypt_state; |
48 vpx_image_t img; | 48 vpx_image_t img; |
49 int img_setup; | |
50 int img_avail; | 49 int img_avail; |
51 int invert_tile_order; | 50 int invert_tile_order; |
52 | 51 |
53 // External frame buffer info to save for VP9 common. | 52 // External frame buffer info to save for VP9 common. |
54 void *ext_priv; // Private data associated with the external frame buffers. | 53 void *ext_priv; // Private data associated with the external frame buffers. |
55 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; | 54 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; |
56 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; | 55 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; |
57 }; | 56 }; |
58 | 57 |
59 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, | 58 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 flags->noise_level = ctx->postproc_cfg.noise_level; | 237 flags->noise_level = ctx->postproc_cfg.noise_level; |
239 #if CONFIG_POSTPROC_VISUALIZER | 238 #if CONFIG_POSTPROC_VISUALIZER |
240 flags->display_ref_frame_flag = ctx->dbg_color_ref_frame_flag; | 239 flags->display_ref_frame_flag = ctx->dbg_color_ref_frame_flag; |
241 flags->display_mb_modes_flag = ctx->dbg_color_mb_modes_flag; | 240 flags->display_mb_modes_flag = ctx->dbg_color_mb_modes_flag; |
242 flags->display_b_modes_flag = ctx->dbg_color_b_modes_flag; | 241 flags->display_b_modes_flag = ctx->dbg_color_b_modes_flag; |
243 flags->display_mv_flag = ctx->dbg_display_mv_flag; | 242 flags->display_mv_flag = ctx->dbg_display_mv_flag; |
244 #endif | 243 #endif |
245 } | 244 } |
246 | 245 |
247 static void init_decoder(vpx_codec_alg_priv_t *ctx) { | 246 static void init_decoder(vpx_codec_alg_priv_t *ctx) { |
248 VP9DecoderConfig oxcf; | 247 ctx->pbi = vp9_decoder_create(); |
249 oxcf.width = ctx->si.w; | |
250 oxcf.height = ctx->si.h; | |
251 oxcf.version = 9; | |
252 oxcf.max_threads = ctx->cfg.threads; | |
253 oxcf.inv_tile_order = ctx->invert_tile_order; | |
254 | |
255 ctx->pbi = vp9_decoder_create(&oxcf); | |
256 if (ctx->pbi == NULL) | 248 if (ctx->pbi == NULL) |
257 return; | 249 return; |
258 | 250 |
| 251 ctx->pbi->max_threads = ctx->cfg.threads; |
| 252 ctx->pbi->inv_tile_order = ctx->invert_tile_order; |
| 253 |
259 vp9_initialize_dec(); | 254 vp9_initialize_dec(); |
260 | 255 |
261 // If postprocessing was enabled by the application and a | 256 // If postprocessing was enabled by the application and a |
262 // configuration has not been provided, default it. | 257 // configuration has not been provided, default it. |
263 if (!ctx->postproc_cfg_set && | 258 if (!ctx->postproc_cfg_set && |
264 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) | 259 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) |
265 set_default_ppflags(&ctx->postproc_cfg); | 260 set_default_ppflags(&ctx->postproc_cfg); |
266 | 261 |
267 init_buffer_callbacks(ctx); | 262 init_buffer_callbacks(ctx); |
268 } | 263 } |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 for (j = 0; j < mag; j++) | 363 for (j = 0; j < mag; j++) |
369 this_sz |= (*x++) << (j * 8); | 364 this_sz |= (*x++) << (j * 8); |
370 sizes[i] = this_sz; | 365 sizes[i] = this_sz; |
371 } | 366 } |
372 | 367 |
373 *count = frames; | 368 *count = frames; |
374 } | 369 } |
375 } | 370 } |
376 } | 371 } |
377 | 372 |
| 373 static vpx_codec_err_t decode_one_iter(vpx_codec_alg_priv_t *ctx, |
| 374 const uint8_t **data_start_ptr, |
| 375 const uint8_t *data_end, |
| 376 uint32_t frame_size, void *user_priv, |
| 377 long deadline) { |
| 378 const vpx_codec_err_t res = decode_one(ctx, data_start_ptr, frame_size, |
| 379 user_priv, deadline); |
| 380 if (res != VPX_CODEC_OK) |
| 381 return res; |
| 382 |
| 383 // Account for suboptimal termination by the encoder. |
| 384 while (*data_start_ptr < data_end) { |
| 385 const uint8_t marker = read_marker(ctx->decrypt_cb, ctx->decrypt_state, |
| 386 *data_start_ptr); |
| 387 if (marker) |
| 388 break; |
| 389 (*data_start_ptr)++; |
| 390 } |
| 391 |
| 392 return VPX_CODEC_OK; |
| 393 } |
| 394 |
378 static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, | 395 static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, |
379 const uint8_t *data, unsigned int data_sz, | 396 const uint8_t *data, unsigned int data_sz, |
380 void *user_priv, long deadline) { | 397 void *user_priv, long deadline) { |
381 const uint8_t *data_start = data; | 398 const uint8_t *data_start = data; |
382 const uint8_t *data_end = data + data_sz; | 399 const uint8_t *const data_end = data + data_sz; |
383 vpx_codec_err_t res = VPX_CODEC_OK; | 400 vpx_codec_err_t res; |
384 uint32_t sizes[8]; | 401 uint32_t frame_sizes[8]; |
385 int frames_this_pts, frame_count = 0; | 402 int frame_count; |
386 | 403 |
387 if (data == NULL || data_sz == 0) | 404 if (data == NULL || data_sz == 0) |
388 return VPX_CODEC_INVALID_PARAM; | 405 return VPX_CODEC_INVALID_PARAM; |
389 | 406 |
390 parse_superframe_index(data, data_sz, sizes, &frames_this_pts, | 407 parse_superframe_index(data, data_sz, frame_sizes, &frame_count, |
391 ctx->decrypt_cb, ctx->decrypt_state); | 408 ctx->decrypt_cb, ctx->decrypt_state); |
392 | 409 |
393 do { | 410 if (frame_count > 0) { |
394 if (data_sz) { | 411 int i; |
395 uint8_t marker = read_marker(ctx->decrypt_cb, ctx->decrypt_state, | |
396 data_start); | |
397 // Skip over the superframe index, if present | |
398 if ((marker & 0xe0) == 0xc0) { | |
399 const uint32_t frames = (marker & 0x7) + 1; | |
400 const uint32_t mag = ((marker >> 3) & 0x3) + 1; | |
401 const uint32_t index_sz = 2 + mag * frames; | |
402 | 412 |
403 if (data_sz >= index_sz) { | 413 for (i = 0; i < frame_count; ++i) { |
404 uint8_t marker2 = read_marker(ctx->decrypt_cb, ctx->decrypt_state, | 414 const uint32_t frame_size = frame_sizes[i]; |
405 data_start + index_sz - 1); | 415 if (data_start < data || |
406 if (marker2 == marker) { | 416 frame_size > (uint32_t)(data_end - data_start)) { |
407 data_start += index_sz; | |
408 data_sz -= index_sz; | |
409 if (data_start < data_end) | |
410 continue; | |
411 else | |
412 break; | |
413 } | |
414 } | |
415 } | |
416 } | |
417 | |
418 // Use the correct size for this frame, if an index is present. | |
419 if (frames_this_pts) { | |
420 uint32_t this_sz = sizes[frame_count]; | |
421 | |
422 if (data_sz < this_sz) { | |
423 ctx->base.err_detail = "Invalid frame size in index"; | 417 ctx->base.err_detail = "Invalid frame size in index"; |
424 return VPX_CODEC_CORRUPT_FRAME; | 418 return VPX_CODEC_CORRUPT_FRAME; |
425 } | 419 } |
426 | 420 |
427 data_sz = this_sz; | 421 res = decode_one_iter(ctx, &data_start, data_end, frame_size, |
428 frame_count++; | 422 user_priv, deadline); |
| 423 if (res != VPX_CODEC_OK) |
| 424 return res; |
429 } | 425 } |
| 426 } else { |
| 427 while (data_start < data_end) { |
| 428 res = decode_one_iter(ctx, &data_start, data_end, |
| 429 (uint32_t)(data_end - data_start), |
| 430 user_priv, deadline); |
| 431 if (res != VPX_CODEC_OK) |
| 432 return res; |
| 433 } |
| 434 } |
430 | 435 |
431 res = decode_one(ctx, &data_start, data_sz, user_priv, deadline); | 436 return VPX_CODEC_OK; |
432 assert(data_start >= data); | |
433 assert(data_start <= data_end); | |
434 | |
435 // Early exit if there was a decode error | |
436 if (res) | |
437 break; | |
438 | |
439 // Account for suboptimal termination by the encoder. | |
440 while (data_start < data_end) { | |
441 uint8_t marker3 = read_marker(ctx->decrypt_cb, ctx->decrypt_state, | |
442 data_start); | |
443 if (marker3) | |
444 break; | |
445 data_start++; | |
446 } | |
447 | |
448 data_sz = (unsigned int)(data_end - data_start); | |
449 } while (data_start < data_end); | |
450 | |
451 return res; | |
452 } | 437 } |
453 | 438 |
454 static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, | 439 static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, |
455 vpx_codec_iter_t *iter) { | 440 vpx_codec_iter_t *iter) { |
456 vpx_image_t *img = NULL; | 441 vpx_image_t *img = NULL; |
457 | 442 |
458 if (ctx->img_avail) { | 443 if (ctx->img_avail) { |
459 // iter acts as a flip flop, so an image is only returned on the first | 444 // iter acts as a flip flop, so an image is only returned on the first |
460 // call to get_frame. | 445 // call to get_frame. |
461 if (!(*iter)) { | 446 if (!(*iter)) { |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 }, | 664 }, |
680 { // NOLINT | 665 { // NOLINT |
681 NOT_IMPLEMENTED, | 666 NOT_IMPLEMENTED, |
682 NOT_IMPLEMENTED, | 667 NOT_IMPLEMENTED, |
683 NOT_IMPLEMENTED, | 668 NOT_IMPLEMENTED, |
684 NOT_IMPLEMENTED, | 669 NOT_IMPLEMENTED, |
685 NOT_IMPLEMENTED, | 670 NOT_IMPLEMENTED, |
686 NOT_IMPLEMENTED | 671 NOT_IMPLEMENTED |
687 } | 672 } |
688 }; | 673 }; |
OLD | NEW |