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 |