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 | 11 |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 #include <string.h> | 13 #include <string.h> |
14 #include "vpx/vpx_decoder.h" | 14 #include "vpx/vpx_decoder.h" |
15 #include "vpx/vp8dx.h" | 15 #include "vpx/vp8dx.h" |
16 #include "vpx/internal/vpx_codec_internal.h" | 16 #include "vpx/internal/vpx_codec_internal.h" |
17 #include "./vpx_version.h" | 17 #include "./vpx_version.h" |
| 18 #include "vp9/common/vp9_frame_buffers.h" |
18 #include "vp9/decoder/vp9_onyxd.h" | 19 #include "vp9/decoder/vp9_onyxd.h" |
19 #include "vp9/decoder/vp9_onyxd_int.h" | 20 #include "vp9/decoder/vp9_onyxd_int.h" |
20 #include "vp9/decoder/vp9_read_bit_buffer.h" | 21 #include "vp9/decoder/vp9_read_bit_buffer.h" |
21 #include "vp9/vp9_iface_common.h" | 22 #include "vp9/vp9_iface_common.h" |
22 | 23 |
23 #define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) | 24 #define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) |
24 typedef vpx_codec_stream_info_t vp9_stream_info_t; | 25 typedef vpx_codec_stream_info_t vp9_stream_info_t; |
25 | 26 |
26 /* Structures for handling memory allocations */ | 27 /* Structures for handling memory allocations */ |
27 typedef enum { | 28 typedef enum { |
(...skipping 24 matching lines...) Expand all Loading... |
52 unsigned int dbg_postproc_flag; | 53 unsigned int dbg_postproc_flag; |
53 int dbg_color_ref_frame_flag; | 54 int dbg_color_ref_frame_flag; |
54 int dbg_color_mb_modes_flag; | 55 int dbg_color_mb_modes_flag; |
55 int dbg_color_b_modes_flag; | 56 int dbg_color_b_modes_flag; |
56 int dbg_display_mv_flag; | 57 int dbg_display_mv_flag; |
57 #endif | 58 #endif |
58 vpx_image_t img; | 59 vpx_image_t img; |
59 int img_setup; | 60 int img_setup; |
60 int img_avail; | 61 int img_avail; |
61 int invert_tile_order; | 62 int invert_tile_order; |
| 63 |
| 64 // External frame buffer info to save for VP9 common. |
| 65 void *ext_priv; // Private data associated with the external frame buffers. |
| 66 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; |
| 67 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; |
62 }; | 68 }; |
63 | 69 |
64 static unsigned long priv_sz(const vpx_codec_dec_cfg_t *si, | 70 static unsigned long priv_sz(const vpx_codec_dec_cfg_t *si, |
65 vpx_codec_flags_t flags) { | 71 vpx_codec_flags_t flags) { |
66 /* Although this declaration is constant, we can't use it in the requested | 72 /* Although this declaration is constant, we can't use it in the requested |
67 * segments list because we want to define the requested segments list | 73 * segments list because we want to define the requested segments list |
68 * before defining the private type (so that the number of memory maps is | 74 * before defining the private type (so that the number of memory maps is |
69 * known) | 75 * known) |
70 */ | 76 */ |
71 (void)si; | 77 (void)si; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 vpx_codec_stream_info_t *si) { | 147 vpx_codec_stream_info_t *si) { |
142 if (data_sz <= 8) return VPX_CODEC_UNSUP_BITSTREAM; | 148 if (data_sz <= 8) return VPX_CODEC_UNSUP_BITSTREAM; |
143 if (data + data_sz <= data) return VPX_CODEC_INVALID_PARAM; | 149 if (data + data_sz <= data) return VPX_CODEC_INVALID_PARAM; |
144 | 150 |
145 si->is_kf = 0; | 151 si->is_kf = 0; |
146 si->w = si->h = 0; | 152 si->w = si->h = 0; |
147 | 153 |
148 { | 154 { |
149 struct vp9_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL }; | 155 struct vp9_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL }; |
150 const int frame_marker = vp9_rb_read_literal(&rb, 2); | 156 const int frame_marker = vp9_rb_read_literal(&rb, 2); |
151 const int version = vp9_rb_read_bit(&rb) | (vp9_rb_read_bit(&rb) << 1); | 157 const int version = vp9_rb_read_bit(&rb); |
| 158 (void) vp9_rb_read_bit(&rb); // unused version bit |
| 159 |
152 if (frame_marker != VP9_FRAME_MARKER) | 160 if (frame_marker != VP9_FRAME_MARKER) |
153 return VPX_CODEC_UNSUP_BITSTREAM; | 161 return VPX_CODEC_UNSUP_BITSTREAM; |
154 #if CONFIG_NON420 | 162 #if CONFIG_NON420 |
155 if (version > 1) return VPX_CODEC_UNSUP_BITSTREAM; | 163 if (version > 1) return VPX_CODEC_UNSUP_BITSTREAM; |
156 #else | 164 #else |
157 if (version != 0) return VPX_CODEC_UNSUP_BITSTREAM; | 165 if (version != 0) return VPX_CODEC_UNSUP_BITSTREAM; |
158 #endif | 166 #endif |
159 | 167 |
160 if (vp9_rb_read_bit(&rb)) { // show an existing frame | 168 if (vp9_rb_read_bit(&rb)) { // show an existing frame |
161 return VPX_CODEC_OK; | 169 return VPX_CODEC_OK; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 | 207 |
200 return VPX_CODEC_OK; | 208 return VPX_CODEC_OK; |
201 } | 209 } |
202 | 210 |
203 static vpx_codec_err_t vp9_get_si(vpx_codec_alg_priv_t *ctx, | 211 static vpx_codec_err_t vp9_get_si(vpx_codec_alg_priv_t *ctx, |
204 vpx_codec_stream_info_t *si) { | 212 vpx_codec_stream_info_t *si) { |
205 const size_t sz = (si->sz >= sizeof(vp9_stream_info_t)) | 213 const size_t sz = (si->sz >= sizeof(vp9_stream_info_t)) |
206 ? sizeof(vp9_stream_info_t) | 214 ? sizeof(vp9_stream_info_t) |
207 : sizeof(vpx_codec_stream_info_t); | 215 : sizeof(vpx_codec_stream_info_t); |
208 memcpy(si, &ctx->si, sz); | 216 memcpy(si, &ctx->si, sz); |
209 si->sz = (unsigned int)sz; | 217 si->sz = sz; |
210 | 218 |
211 return VPX_CODEC_OK; | 219 return VPX_CODEC_OK; |
212 } | 220 } |
213 | 221 |
214 | 222 |
215 static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx, | 223 static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx, |
216 const struct vpx_internal_error_info *error) { | 224 const struct vpx_internal_error_info *error) { |
217 if (error->error_code) | 225 if (error->error_code) |
218 ctx->base.err_detail = error->has_detail ? error->detail : NULL; | 226 ctx->base.err_detail = error->has_detail ? error->detail : NULL; |
219 | 227 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 | 292 |
285 // If postprocessing was enabled by the application and a | 293 // If postprocessing was enabled by the application and a |
286 // configuration has not been provided, default it. | 294 // configuration has not been provided, default it. |
287 if (!ctx->postproc_cfg_set && | 295 if (!ctx->postproc_cfg_set && |
288 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) { | 296 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) { |
289 ctx->postproc_cfg.post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK; | 297 ctx->postproc_cfg.post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK; |
290 ctx->postproc_cfg.deblocking_level = 4; | 298 ctx->postproc_cfg.deblocking_level = 4; |
291 ctx->postproc_cfg.noise_level = 0; | 299 ctx->postproc_cfg.noise_level = 0; |
292 } | 300 } |
293 | 301 |
294 if (!optr) | 302 if (!optr) { |
295 res = VPX_CODEC_ERROR; | 303 res = VPX_CODEC_ERROR; |
296 else | 304 } else { |
| 305 VP9D_COMP *const pbi = (VP9D_COMP*)optr; |
| 306 VP9_COMMON *const cm = &pbi->common; |
| 307 |
| 308 // Set index to not initialized. |
| 309 cm->new_fb_idx = -1; |
| 310 |
| 311 if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) { |
| 312 cm->get_fb_cb = ctx->get_ext_fb_cb; |
| 313 cm->release_fb_cb = ctx->release_ext_fb_cb; |
| 314 cm->cb_priv = ctx->ext_priv; |
| 315 } else { |
| 316 cm->get_fb_cb = vp9_get_frame_buffer; |
| 317 cm->release_fb_cb = vp9_release_frame_buffer; |
| 318 |
| 319 if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers)) |
| 320 vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, |
| 321 "Failed to initialize internal frame buffers"); |
| 322 cm->cb_priv = &cm->int_frame_buffers; |
| 323 } |
| 324 |
297 ctx->pbi = optr; | 325 ctx->pbi = optr; |
| 326 } |
298 } | 327 } |
299 | 328 |
300 ctx->decoder_init = 1; | 329 ctx->decoder_init = 1; |
301 } | 330 } |
302 | 331 |
303 if (!res && ctx->pbi) { | 332 if (!res && ctx->pbi) { |
304 YV12_BUFFER_CONFIG sd; | 333 YV12_BUFFER_CONFIG sd; |
305 int64_t time_stamp = 0, time_end_stamp = 0; | 334 int64_t time_stamp = 0, time_end_stamp = 0; |
306 vp9_ppflags_t flags = {0}; | 335 vp9_ppflags_t flags = {0}; |
307 | 336 |
(...skipping 17 matching lines...) Expand all Loading... |
325 #endif | 354 #endif |
326 } | 355 } |
327 | 356 |
328 if (vp9_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) { | 357 if (vp9_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) { |
329 VP9D_COMP *pbi = (VP9D_COMP*)ctx->pbi; | 358 VP9D_COMP *pbi = (VP9D_COMP*)ctx->pbi; |
330 res = update_error_state(ctx, &pbi->common.error); | 359 res = update_error_state(ctx, &pbi->common.error); |
331 } | 360 } |
332 | 361 |
333 if (!res && 0 == vp9_get_raw_frame(ctx->pbi, &sd, &time_stamp, | 362 if (!res && 0 == vp9_get_raw_frame(ctx->pbi, &sd, &time_stamp, |
334 &time_end_stamp, &flags)) { | 363 &time_end_stamp, &flags)) { |
| 364 VP9D_COMP *const pbi = (VP9D_COMP*)ctx->pbi; |
| 365 VP9_COMMON *const cm = &pbi->common; |
335 yuvconfig2image(&ctx->img, &sd, user_priv); | 366 yuvconfig2image(&ctx->img, &sd, user_priv); |
| 367 |
| 368 ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; |
336 ctx->img_avail = 1; | 369 ctx->img_avail = 1; |
337 } | 370 } |
338 } | 371 } |
339 | 372 |
340 return res; | 373 return res; |
341 } | 374 } |
342 | 375 |
343 static void parse_superframe_index(const uint8_t *data, size_t data_sz, | 376 static void parse_superframe_index(const uint8_t *data, size_t data_sz, |
344 uint32_t sizes[8], int *count) { | 377 uint32_t sizes[8], int *count) { |
345 uint8_t marker; | 378 uint8_t marker; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 if (!(*iter)) { | 478 if (!(*iter)) { |
446 img = &ctx->img; | 479 img = &ctx->img; |
447 *iter = img; | 480 *iter = img; |
448 } | 481 } |
449 } | 482 } |
450 ctx->img_avail = 0; | 483 ctx->img_avail = 0; |
451 | 484 |
452 return img; | 485 return img; |
453 } | 486 } |
454 | 487 |
| 488 static vpx_codec_err_t vp9_set_fb_fn( |
| 489 vpx_codec_alg_priv_t *ctx, |
| 490 vpx_get_frame_buffer_cb_fn_t cb_get, |
| 491 vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) { |
| 492 if (cb_get == NULL || cb_release == NULL) { |
| 493 return VPX_CODEC_INVALID_PARAM; |
| 494 } else if (ctx->pbi == NULL) { |
| 495 // If the decoder has already been initialized, do not accept changes to |
| 496 // the frame buffer functions. |
| 497 ctx->get_ext_fb_cb = cb_get; |
| 498 ctx->release_ext_fb_cb = cb_release; |
| 499 ctx->ext_priv = cb_priv; |
| 500 return VPX_CODEC_OK; |
| 501 } |
| 502 |
| 503 return VPX_CODEC_ERROR; |
| 504 } |
| 505 |
455 static vpx_codec_err_t vp9_xma_get_mmap(const vpx_codec_ctx_t *ctx, | 506 static vpx_codec_err_t vp9_xma_get_mmap(const vpx_codec_ctx_t *ctx, |
456 vpx_codec_mmap_t *mmap, | 507 vpx_codec_mmap_t *mmap, |
457 vpx_codec_iter_t *iter) { | 508 vpx_codec_iter_t *iter) { |
458 vpx_codec_err_t res; | 509 vpx_codec_err_t res; |
459 const mem_req_t *seg_iter = *iter; | 510 const mem_req_t *seg_iter = *iter; |
460 | 511 |
461 /* Get address of next segment request */ | 512 /* Get address of next segment request */ |
462 do { | 513 do { |
463 if (!seg_iter) | 514 if (!seg_iter) |
464 seg_iter = vp9_mem_req_segs; | 515 seg_iter = vp9_mem_req_segs; |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 { -1, NULL}, | 729 { -1, NULL}, |
679 }; | 730 }; |
680 | 731 |
681 | 732 |
682 #ifndef VERSION_STRING | 733 #ifndef VERSION_STRING |
683 #define VERSION_STRING | 734 #define VERSION_STRING |
684 #endif | 735 #endif |
685 CODEC_INTERFACE(vpx_codec_vp9_dx) = { | 736 CODEC_INTERFACE(vpx_codec_vp9_dx) = { |
686 "WebM Project VP9 Decoder" VERSION_STRING, | 737 "WebM Project VP9 Decoder" VERSION_STRING, |
687 VPX_CODEC_INTERNAL_ABI_VERSION, | 738 VPX_CODEC_INTERNAL_ABI_VERSION, |
688 VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC, | 739 VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC | |
| 740 VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER, |
689 /* vpx_codec_caps_t caps; */ | 741 /* vpx_codec_caps_t caps; */ |
690 vp9_init, /* vpx_codec_init_fn_t init; */ | 742 vp9_init, /* vpx_codec_init_fn_t init; */ |
691 vp9_destroy, /* vpx_codec_destroy_fn_t destroy; */ | 743 vp9_destroy, /* vpx_codec_destroy_fn_t destroy; */ |
692 ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */ | 744 ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */ |
693 vp9_xma_get_mmap, /* vpx_codec_get_mmap_fn_t get_mmap; */ | 745 vp9_xma_get_mmap, /* vpx_codec_get_mmap_fn_t get_mmap; */ |
694 vp9_xma_set_mmap, /* vpx_codec_set_mmap_fn_t set_mmap; */ | 746 vp9_xma_set_mmap, /* vpx_codec_set_mmap_fn_t set_mmap; */ |
695 { // NOLINT | 747 { // NOLINT |
696 vp9_peek_si, /* vpx_codec_peek_si_fn_t peek_si; */ | 748 vp9_peek_si, /* vpx_codec_peek_si_fn_t peek_si; */ |
697 vp9_get_si, /* vpx_codec_get_si_fn_t get_si; */ | 749 vp9_get_si, /* vpx_codec_get_si_fn_t get_si; */ |
698 vp9_decode, /* vpx_codec_decode_fn_t decode; */ | 750 vp9_decode, /* vpx_codec_decode_fn_t decode; */ |
699 vp9_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */ | 751 vp9_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */ |
| 752 vp9_set_fb_fn, /* vpx_codec_set_fb_fn_t set_fb_fn; */ |
700 }, | 753 }, |
701 { // NOLINT | 754 { // NOLINT |
702 /* encoder functions */ | 755 /* encoder functions */ |
703 NOT_IMPLEMENTED, | 756 NOT_IMPLEMENTED, |
704 NOT_IMPLEMENTED, | 757 NOT_IMPLEMENTED, |
705 NOT_IMPLEMENTED, | 758 NOT_IMPLEMENTED, |
706 NOT_IMPLEMENTED, | 759 NOT_IMPLEMENTED, |
707 NOT_IMPLEMENTED, | 760 NOT_IMPLEMENTED, |
708 NOT_IMPLEMENTED | 761 NOT_IMPLEMENTED |
709 } | 762 } |
710 }; | 763 }; |
OLD | NEW |