| 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 22 matching lines...) Expand all Loading... |
| 33 vpx_codec_priv_t base; | 33 vpx_codec_priv_t base; |
| 34 vpx_codec_dec_cfg_t cfg; | 34 vpx_codec_dec_cfg_t cfg; |
| 35 vp9_stream_info_t si; | 35 vp9_stream_info_t si; |
| 36 struct VP9Decoder *pbi; | 36 struct VP9Decoder *pbi; |
| 37 int postproc_cfg_set; | 37 int postproc_cfg_set; |
| 38 vp8_postproc_cfg_t postproc_cfg; | 38 vp8_postproc_cfg_t postproc_cfg; |
| 39 vpx_decrypt_cb decrypt_cb; | 39 vpx_decrypt_cb decrypt_cb; |
| 40 void *decrypt_state; | 40 void *decrypt_state; |
| 41 vpx_image_t img; | 41 vpx_image_t img; |
| 42 int img_avail; | 42 int img_avail; |
| 43 int flushed; |
| 43 int invert_tile_order; | 44 int invert_tile_order; |
| 44 int frame_parallel_decode; // frame-based threading. | 45 int frame_parallel_decode; // frame-based threading. |
| 45 | 46 |
| 46 // External frame buffer info to save for VP9 common. | 47 // External frame buffer info to save for VP9 common. |
| 47 void *ext_priv; // Private data associated with the external frame buffers. | 48 void *ext_priv; // Private data associated with the external frame buffers. |
| 48 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; | 49 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; |
| 49 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; | 50 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; |
| 50 }; | 51 }; |
| 51 | 52 |
| 52 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, | 53 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, |
| 53 vpx_codec_priv_enc_mr_cfg_t *data) { | 54 vpx_codec_priv_enc_mr_cfg_t *data) { |
| 54 // This function only allocates space for the vpx_codec_alg_priv_t | 55 // This function only allocates space for the vpx_codec_alg_priv_t |
| 55 // structure. More memory may be required at the time the stream | 56 // structure. More memory may be required at the time the stream |
| 56 // information becomes known. | 57 // information becomes known. |
| 57 (void)data; | 58 (void)data; |
| 58 | 59 |
| 59 if (!ctx->priv) { | 60 if (!ctx->priv) { |
| 60 vpx_codec_alg_priv_t *alg_priv = vpx_memalign(32, sizeof(*alg_priv)); | 61 vpx_codec_alg_priv_t *alg_priv = vpx_memalign(32, sizeof(*alg_priv)); |
| 61 if (alg_priv == NULL) | 62 if (alg_priv == NULL) |
| 62 return VPX_CODEC_MEM_ERROR; | 63 return VPX_CODEC_MEM_ERROR; |
| 63 | 64 |
| 64 vp9_zero(*alg_priv); | 65 vp9_zero(*alg_priv); |
| 65 | 66 |
| 66 ctx->priv = (vpx_codec_priv_t *)alg_priv; | 67 ctx->priv = (vpx_codec_priv_t *)alg_priv; |
| 67 ctx->priv->sz = sizeof(*ctx->priv); | 68 ctx->priv->sz = sizeof(*ctx->priv); |
| 68 ctx->priv->iface = ctx->iface; | 69 ctx->priv->iface = ctx->iface; |
| 69 ctx->priv->alg_priv = alg_priv; | 70 ctx->priv->alg_priv = alg_priv; |
| 70 ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si); | 71 ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si); |
| 71 ctx->priv->init_flags = ctx->init_flags; | 72 ctx->priv->init_flags = ctx->init_flags; |
| 73 ctx->priv->alg_priv->flushed = 0; |
| 72 ctx->priv->alg_priv->frame_parallel_decode = | 74 ctx->priv->alg_priv->frame_parallel_decode = |
| 73 (ctx->init_flags & VPX_CODEC_USE_FRAME_THREADING); | 75 (ctx->init_flags & VPX_CODEC_USE_FRAME_THREADING); |
| 74 | 76 |
| 75 // Disable frame parallel decoding for now. | 77 // Disable frame parallel decoding for now. |
| 76 ctx->priv->alg_priv->frame_parallel_decode = 0; | 78 ctx->priv->alg_priv->frame_parallel_decode = 0; |
| 77 | 79 |
| 78 if (ctx->config.dec) { | 80 if (ctx->config.dec) { |
| 79 // Update the reference to the config structure to an internal copy. | 81 // Update the reference to the config structure to an internal copy. |
| 80 ctx->priv->alg_priv->cfg = *ctx->config.dec; | 82 ctx->priv->alg_priv->cfg = *ctx->config.dec; |
| 81 ctx->config.dec = &ctx->priv->alg_priv->cfg; | 83 ctx->config.dec = &ctx->priv->alg_priv->cfg; |
| 82 } | 84 } |
| 83 } | 85 } |
| 84 | 86 |
| 85 return VPX_CODEC_OK; | 87 return VPX_CODEC_OK; |
| 86 } | 88 } |
| 87 | 89 |
| 88 static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) { | 90 static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) { |
| 89 if (ctx->pbi) { | 91 if (ctx->pbi) { |
| 90 vp9_decoder_remove(ctx->pbi); | 92 vp9_decoder_remove(ctx->pbi); |
| 91 ctx->pbi = NULL; | 93 ctx->pbi = NULL; |
| 92 } | 94 } |
| 93 | 95 |
| 94 vpx_free(ctx); | 96 vpx_free(ctx); |
| 95 | 97 |
| 96 return VPX_CODEC_OK; | 98 return VPX_CODEC_OK; |
| 97 } | 99 } |
| 98 | 100 |
| 101 static int parse_bitdepth_colorspace_sampling( |
| 102 BITSTREAM_PROFILE profile, struct vp9_read_bit_buffer *rb) { |
| 103 const int sRGB = 7; |
| 104 int colorspace; |
| 105 if (profile >= PROFILE_2) |
| 106 rb->bit_offset += 1; // Bit-depth 10 or 12. |
| 107 colorspace = vp9_rb_read_literal(rb, 3); |
| 108 if (colorspace != sRGB) { |
| 109 rb->bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range. |
| 110 if (profile == PROFILE_1 || profile == PROFILE_3) { |
| 111 rb->bit_offset += 2; // subsampling x/y. |
| 112 rb->bit_offset += 1; // unused. |
| 113 } |
| 114 } else { |
| 115 if (profile == PROFILE_1 || profile == PROFILE_3) { |
| 116 rb->bit_offset += 1; // unused |
| 117 } else { |
| 118 // RGB is only available in version 1. |
| 119 return 0; |
| 120 } |
| 121 } |
| 122 return 1; |
| 123 } |
| 124 |
| 99 static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, | 125 static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, |
| 100 unsigned int data_sz, | 126 unsigned int data_sz, |
| 101 vpx_codec_stream_info_t *si, | 127 vpx_codec_stream_info_t *si, |
| 102 int *is_intra_only, | 128 int *is_intra_only, |
| 103 vpx_decrypt_cb decrypt_cb, | 129 vpx_decrypt_cb decrypt_cb, |
| 104 void *decrypt_state) { | 130 void *decrypt_state) { |
| 105 int intra_only_flag = 0; | 131 int intra_only_flag = 0; |
| 106 uint8_t clear_buffer[9]; | 132 uint8_t clear_buffer[9]; |
| 107 | 133 |
| 108 if (data + data_sz <= data) | 134 if (data + data_sz <= data) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 135 } | 161 } |
| 136 | 162 |
| 137 if (data_sz <= 8) | 163 if (data_sz <= 8) |
| 138 return VPX_CODEC_UNSUP_BITSTREAM; | 164 return VPX_CODEC_UNSUP_BITSTREAM; |
| 139 | 165 |
| 140 si->is_kf = !vp9_rb_read_bit(&rb); | 166 si->is_kf = !vp9_rb_read_bit(&rb); |
| 141 show_frame = vp9_rb_read_bit(&rb); | 167 show_frame = vp9_rb_read_bit(&rb); |
| 142 error_resilient = vp9_rb_read_bit(&rb); | 168 error_resilient = vp9_rb_read_bit(&rb); |
| 143 | 169 |
| 144 if (si->is_kf) { | 170 if (si->is_kf) { |
| 145 const int sRGB = 7; | |
| 146 int colorspace; | |
| 147 | |
| 148 if (!vp9_read_sync_code(&rb)) | 171 if (!vp9_read_sync_code(&rb)) |
| 149 return VPX_CODEC_UNSUP_BITSTREAM; | 172 return VPX_CODEC_UNSUP_BITSTREAM; |
| 150 | 173 |
| 151 if (profile > PROFILE_1) | 174 if (!parse_bitdepth_colorspace_sampling(profile, &rb)) |
| 152 rb.bit_offset += 1; // Bit-depth 10 or 12 | 175 return VPX_CODEC_UNSUP_BITSTREAM; |
| 153 colorspace = vp9_rb_read_literal(&rb, 3); | |
| 154 if (colorspace != sRGB) { | |
| 155 rb.bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range | |
| 156 if (profile == PROFILE_1 || profile == PROFILE_3) { | |
| 157 rb.bit_offset += 2; // subsampling x/y | |
| 158 rb.bit_offset += 1; // unused | |
| 159 } | |
| 160 } else { | |
| 161 if (profile == PROFILE_1 || profile == PROFILE_3) { | |
| 162 rb.bit_offset += 1; // unused | |
| 163 } else { | |
| 164 // RGB is only available in version 1 | |
| 165 return VPX_CODEC_UNSUP_BITSTREAM; | |
| 166 } | |
| 167 } | |
| 168 vp9_read_frame_size(&rb, (int *)&si->w, (int *)&si->h); | 176 vp9_read_frame_size(&rb, (int *)&si->w, (int *)&si->h); |
| 169 } else { | 177 } else { |
| 170 intra_only_flag = show_frame ? 0 : vp9_rb_read_bit(&rb); | 178 intra_only_flag = show_frame ? 0 : vp9_rb_read_bit(&rb); |
| 179 |
| 171 rb.bit_offset += error_resilient ? 0 : 2; // reset_frame_context | 180 rb.bit_offset += error_resilient ? 0 : 2; // reset_frame_context |
| 172 | 181 |
| 173 if (intra_only_flag) { | 182 if (intra_only_flag) { |
| 174 if (!vp9_read_sync_code(&rb)) | 183 if (!vp9_read_sync_code(&rb)) |
| 175 return VPX_CODEC_UNSUP_BITSTREAM; | 184 return VPX_CODEC_UNSUP_BITSTREAM; |
| 185 if (profile > PROFILE_0) { |
| 186 if (!parse_bitdepth_colorspace_sampling(profile, &rb)) |
| 187 return VPX_CODEC_UNSUP_BITSTREAM; |
| 188 } |
| 176 rb.bit_offset += REF_FRAMES; // refresh_frame_flags | 189 rb.bit_offset += REF_FRAMES; // refresh_frame_flags |
| 177 vp9_read_frame_size(&rb, (int *)&si->w, (int *)&si->h); | 190 vp9_read_frame_size(&rb, (int *)&si->w, (int *)&si->h); |
| 178 } | 191 } |
| 179 } | 192 } |
| 180 } | 193 } |
| 181 if (is_intra_only != NULL) | 194 if (is_intra_only != NULL) |
| 182 *is_intra_only = intra_only_flag; | 195 *is_intra_only = intra_only_flag; |
| 183 return VPX_CODEC_OK; | 196 return VPX_CODEC_OK; |
| 184 } | 197 } |
| 185 | 198 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 | 409 |
| 397 static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, | 410 static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, |
| 398 const uint8_t *data, unsigned int data_sz, | 411 const uint8_t *data, unsigned int data_sz, |
| 399 void *user_priv, long deadline) { | 412 void *user_priv, long deadline) { |
| 400 const uint8_t *data_start = data; | 413 const uint8_t *data_start = data; |
| 401 const uint8_t * const data_end = data + data_sz; | 414 const uint8_t * const data_end = data + data_sz; |
| 402 vpx_codec_err_t res; | 415 vpx_codec_err_t res; |
| 403 uint32_t frame_sizes[8]; | 416 uint32_t frame_sizes[8]; |
| 404 int frame_count; | 417 int frame_count; |
| 405 | 418 |
| 406 if (data == NULL || data_sz == 0) | 419 if (data == NULL && data_sz == 0) { |
| 407 return VPX_CODEC_INVALID_PARAM; | 420 ctx->flushed = 1; |
| 421 return VPX_CODEC_OK; |
| 422 } |
| 423 |
| 424 // Reset flushed when receiving a valid frame. |
| 425 ctx->flushed = 0; |
| 408 | 426 |
| 409 res = parse_superframe_index(data, data_sz, frame_sizes, &frame_count, | 427 res = parse_superframe_index(data, data_sz, frame_sizes, &frame_count, |
| 410 ctx->decrypt_cb, ctx->decrypt_state); | 428 ctx->decrypt_cb, ctx->decrypt_state); |
| 411 if (res != VPX_CODEC_OK) | 429 if (res != VPX_CODEC_OK) |
| 412 return res; | 430 return res; |
| 413 | 431 |
| 414 if (ctx->frame_parallel_decode) { | 432 if (ctx->frame_parallel_decode) { |
| 415 // Decode in frame parallel mode. When decoding in this mode, the frame | 433 // Decode in frame parallel mode. When decoding in this mode, the frame |
| 416 // passed to the decoder must be either a normal frame or a superframe with | 434 // passed to the decoder must be either a normal frame or a superframe with |
| 417 // superframe index so the decoder could get each frame's start position | 435 // superframe index so the decoder could get each frame's start position |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 } else { | 576 } else { |
| 559 return VPX_CODEC_INVALID_PARAM; | 577 return VPX_CODEC_INVALID_PARAM; |
| 560 } | 578 } |
| 561 } | 579 } |
| 562 | 580 |
| 563 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, | 581 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, |
| 564 va_list args) { | 582 va_list args) { |
| 565 vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *); | 583 vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *); |
| 566 | 584 |
| 567 if (data) { | 585 if (data) { |
| 568 YV12_BUFFER_CONFIG* fb; | 586 YV12_BUFFER_CONFIG* fb = get_ref_frame(&ctx->pbi->common, data->idx); |
| 587 if (fb == NULL) return VPX_CODEC_ERROR; |
| 569 | 588 |
| 570 vp9_get_reference_dec(ctx->pbi, data->idx, &fb); | |
| 571 yuvconfig2image(&data->img, fb, NULL); | 589 yuvconfig2image(&data->img, fb, NULL); |
| 572 return VPX_CODEC_OK; | 590 return VPX_CODEC_OK; |
| 573 } else { | 591 } else { |
| 574 return VPX_CODEC_INVALID_PARAM; | 592 return VPX_CODEC_INVALID_PARAM; |
| 575 } | 593 } |
| 576 } | 594 } |
| 577 | 595 |
| 578 static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx, | 596 static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx, |
| 579 va_list args) { | 597 va_list args) { |
| 580 #if CONFIG_VP9_POSTPROC | 598 #if CONFIG_VP9_POSTPROC |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 } else { | 632 } else { |
| 615 return VPX_CODEC_INVALID_PARAM; | 633 return VPX_CODEC_INVALID_PARAM; |
| 616 } | 634 } |
| 617 } | 635 } |
| 618 | 636 |
| 619 | 637 |
| 620 static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, | 638 static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, |
| 621 va_list args) { | 639 va_list args) { |
| 622 int *corrupted = va_arg(args, int *); | 640 int *corrupted = va_arg(args, int *); |
| 623 | 641 |
| 624 if (corrupted) { | 642 if (corrupted != NULL && ctx->pbi != NULL) { |
| 625 if (ctx->pbi) | 643 const YV12_BUFFER_CONFIG *const frame = ctx->pbi->common.frame_to_show; |
| 626 *corrupted = ctx->pbi->common.frame_to_show->corrupted; | 644 if (frame == NULL) return VPX_CODEC_ERROR; |
| 627 else | 645 *corrupted = frame->corrupted; |
| 628 return VPX_CODEC_ERROR; | |
| 629 return VPX_CODEC_OK; | 646 return VPX_CODEC_OK; |
| 630 } else { | 647 } else { |
| 631 return VPX_CODEC_INVALID_PARAM; | 648 return VPX_CODEC_INVALID_PARAM; |
| 632 } | 649 } |
| 633 } | 650 } |
| 634 | 651 |
| 635 static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx, | 652 static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx, |
| 636 va_list args) { | 653 va_list args) { |
| 637 int *const display_size = va_arg(args, int *); | 654 int *const display_size = va_arg(args, int *); |
| 638 | 655 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 #define VERSION_STRING | 707 #define VERSION_STRING |
| 691 #endif | 708 #endif |
| 692 CODEC_INTERFACE(vpx_codec_vp9_dx) = { | 709 CODEC_INTERFACE(vpx_codec_vp9_dx) = { |
| 693 "WebM Project VP9 Decoder" VERSION_STRING, | 710 "WebM Project VP9 Decoder" VERSION_STRING, |
| 694 VPX_CODEC_INTERNAL_ABI_VERSION, | 711 VPX_CODEC_INTERNAL_ABI_VERSION, |
| 695 VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC | | 712 VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC | |
| 696 VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER, // vpx_codec_caps_t | 713 VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER, // vpx_codec_caps_t |
| 697 decoder_init, // vpx_codec_init_fn_t | 714 decoder_init, // vpx_codec_init_fn_t |
| 698 decoder_destroy, // vpx_codec_destroy_fn_t | 715 decoder_destroy, // vpx_codec_destroy_fn_t |
| 699 decoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t | 716 decoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t |
| 700 NOT_IMPLEMENTED, // vpx_codec_get_mmap_fn_t | |
| 701 NOT_IMPLEMENTED, // vpx_codec_set_mmap_fn_t | |
| 702 { // NOLINT | 717 { // NOLINT |
| 703 decoder_peek_si, // vpx_codec_peek_si_fn_t | 718 decoder_peek_si, // vpx_codec_peek_si_fn_t |
| 704 decoder_get_si, // vpx_codec_get_si_fn_t | 719 decoder_get_si, // vpx_codec_get_si_fn_t |
| 705 decoder_decode, // vpx_codec_decode_fn_t | 720 decoder_decode, // vpx_codec_decode_fn_t |
| 706 decoder_get_frame, // vpx_codec_frame_get_fn_t | 721 decoder_get_frame, // vpx_codec_frame_get_fn_t |
| 707 decoder_set_fb_fn, // vpx_codec_set_fb_fn_t | 722 decoder_set_fb_fn, // vpx_codec_set_fb_fn_t |
| 708 }, | 723 }, |
| 709 { // NOLINT | 724 { // NOLINT |
| 725 0, |
| 710 NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t | 726 NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t |
| 711 NOT_IMPLEMENTED, // vpx_codec_encode_fn_t | 727 NOT_IMPLEMENTED, // vpx_codec_encode_fn_t |
| 712 NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t | 728 NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t |
| 713 NOT_IMPLEMENTED, // vpx_codec_enc_config_set_fn_t | 729 NOT_IMPLEMENTED, // vpx_codec_enc_config_set_fn_t |
| 714 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t | 730 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t |
| 715 NOT_IMPLEMENTED, // vpx_codec_get_preview_frame_fn_t | 731 NOT_IMPLEMENTED, // vpx_codec_get_preview_frame_fn_t |
| 716 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t | 732 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t |
| 717 } | 733 } |
| 718 }; | 734 }; |
| OLD | NEW |