2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
14 #include "./vpx_version.h"
16 #include "vpx/internal/vpx_codec_internal.h"
17 #include "vpx/vp8dx.h"
18 #include "vpx/vpx_decoder.h"
20 #include "vp9/common/vp9_frame_buffers.h"
22 #include "vp9/decoder/vp9_decoder.h"
23 #include "vp9/decoder/vp9_read_bit_buffer.h"
25 #include "vp9/vp9_iface_common.h"
27 #define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0)
29 typedef vpx_codec_stream_info_t vp9_stream_info_t;
31 struct vpx_codec_alg_priv {
32 vpx_codec_priv_t base;
33 vpx_codec_dec_cfg_t cfg;
35 struct VP9Decoder *pbi;
37 vp8_postproc_cfg_t postproc_cfg;
38 vpx_decrypt_cb decrypt_cb;
41 int invert_tile_order;
42 int frame_parallel_decode; // frame-based threading.
43 int last_show_frame; // Index of last output frame.
45 // External frame buffer info to save for VP9 common.
46 void *ext_priv; // Private data associated with the external frame buffers.
47 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb;
48 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb;
51 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx,
52 vpx_codec_priv_enc_mr_cfg_t *data) {
53 // This function only allocates space for the vpx_codec_alg_priv_t
54 // structure. More memory may be required at the time the stream
55 // information becomes known.
59 vpx_codec_alg_priv_t *alg_priv = vpx_memalign(32, sizeof(*alg_priv));
61 return VPX_CODEC_MEM_ERROR;
65 ctx->priv = (vpx_codec_priv_t *)alg_priv;
66 ctx->priv->sz = sizeof(*ctx->priv);
67 ctx->priv->iface = ctx->iface;
68 ctx->priv->alg_priv = alg_priv;
69 ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si);
70 ctx->priv->init_flags = ctx->init_flags;
71 ctx->priv->alg_priv->frame_parallel_decode =
72 (ctx->init_flags & VPX_CODEC_USE_FRAME_THREADING);
74 // Disable frame parallel decoding for now.
75 ctx->priv->alg_priv->frame_parallel_decode = 0;
77 if (ctx->config.dec) {
78 // Update the reference to the config structure to an internal copy.
79 ctx->priv->alg_priv->cfg = *ctx->config.dec;
80 ctx->config.dec = &ctx->priv->alg_priv->cfg;
87 static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) {
89 vp9_decoder_remove(ctx->pbi);
98 static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data,
100 vpx_codec_stream_info_t *si,
101 vpx_decrypt_cb decrypt_cb,
102 void *decrypt_state) {
103 uint8_t clear_buffer[9];
106 return VPX_CODEC_UNSUP_BITSTREAM;
108 if (data + data_sz <= data)
109 return VPX_CODEC_INVALID_PARAM;
115 data_sz = MIN(sizeof(clear_buffer), data_sz);
116 decrypt_cb(decrypt_state, data, clear_buffer, data_sz);
121 struct vp9_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL };
122 const int frame_marker = vp9_rb_read_literal(&rb, 2);
123 const int version = vp9_rb_read_bit(&rb);
124 (void) vp9_rb_read_bit(&rb); // unused version bit
126 if (frame_marker != VP9_FRAME_MARKER)
127 return VPX_CODEC_UNSUP_BITSTREAM;
128 if (version > 1) return VPX_CODEC_UNSUP_BITSTREAM;
130 if (vp9_rb_read_bit(&rb)) { // show an existing frame
134 si->is_kf = !vp9_rb_read_bit(&rb);
139 rb.bit_offset += 1; // show frame
140 rb.bit_offset += 1; // error resilient
142 if (vp9_rb_read_literal(&rb, 8) != VP9_SYNC_CODE_0 ||
143 vp9_rb_read_literal(&rb, 8) != VP9_SYNC_CODE_1 ||
144 vp9_rb_read_literal(&rb, 8) != VP9_SYNC_CODE_2) {
145 return VPX_CODEC_UNSUP_BITSTREAM;
148 colorspace = vp9_rb_read_literal(&rb, 3);
149 if (colorspace != sRGB) {
150 rb.bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range
152 rb.bit_offset += 2; // subsampling x/y
153 rb.bit_offset += 1; // has extra plane
157 rb.bit_offset += 1; // has extra plane
159 // RGB is only available in version 1
160 return VPX_CODEC_UNSUP_BITSTREAM;
164 // TODO(jzern): these are available on non-keyframes in intra only mode.
165 si->w = vp9_rb_read_literal(&rb, 16) + 1;
166 si->h = vp9_rb_read_literal(&rb, 16) + 1;
173 static vpx_codec_err_t decoder_peek_si(const uint8_t *data,
174 unsigned int data_sz,
175 vpx_codec_stream_info_t *si) {
176 return decoder_peek_si_internal(data, data_sz, si, NULL, NULL);
179 static vpx_codec_err_t decoder_get_si(vpx_codec_alg_priv_t *ctx,
180 vpx_codec_stream_info_t *si) {
181 const size_t sz = (si->sz >= sizeof(vp9_stream_info_t))
182 ? sizeof(vp9_stream_info_t)
183 : sizeof(vpx_codec_stream_info_t);
184 memcpy(si, &ctx->si, sz);
185 si->sz = (unsigned int)sz;
190 static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx,
191 const struct vpx_internal_error_info *error) {
192 if (error->error_code)
193 ctx->base.err_detail = error->has_detail ? error->detail : NULL;
195 return error->error_code;
198 static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) {
199 VP9_COMMON *const cm = &ctx->pbi->common;
203 if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) {
204 cm->get_fb_cb = ctx->get_ext_fb_cb;
205 cm->release_fb_cb = ctx->release_ext_fb_cb;
206 cm->cb_priv = ctx->ext_priv;
208 cm->get_fb_cb = vp9_get_frame_buffer;
209 cm->release_fb_cb = vp9_release_frame_buffer;
211 if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers))
212 vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
213 "Failed to initialize internal frame buffers");
215 cm->cb_priv = &cm->int_frame_buffers;
219 static void set_default_ppflags(vp8_postproc_cfg_t *cfg) {
220 cfg->post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
221 cfg->deblocking_level = 4;
222 cfg->noise_level = 0;
225 static void set_ppflags(const vpx_codec_alg_priv_t *ctx,
226 vp9_ppflags_t *flags) {
227 flags->post_proc_flag =
228 ctx->postproc_cfg.post_proc_flag;
230 flags->deblocking_level = ctx->postproc_cfg.deblocking_level;
231 flags->noise_level = ctx->postproc_cfg.noise_level;
234 static void init_decoder(vpx_codec_alg_priv_t *ctx) {
235 ctx->pbi = vp9_decoder_create();
236 if (ctx->pbi == NULL)
239 ctx->pbi->max_threads = ctx->cfg.threads;
240 ctx->pbi->inv_tile_order = ctx->invert_tile_order;
241 ctx->pbi->frame_parallel_decode = ctx->frame_parallel_decode;
242 ctx->last_show_frame = -1;
244 // If postprocessing was enabled by the application and a
245 // configuration has not been provided, default it.
246 if (!ctx->postproc_cfg_set &&
247 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC))
248 set_default_ppflags(&ctx->postproc_cfg);
250 init_buffer_callbacks(ctx);
253 static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
254 const uint8_t **data, unsigned int data_sz,
255 void *user_priv, int64_t deadline) {
256 vp9_ppflags_t flags = {0};
257 VP9_COMMON *cm = NULL;
261 // Determine the stream parameters. Note that we rely on peek_si to
262 // validate that we have a buffer that does not wrap around the top
265 const vpx_codec_err_t res =
266 decoder_peek_si_internal(*data, data_sz, &ctx->si, ctx->decrypt_cb,
268 if (res != VPX_CODEC_OK)
272 return VPX_CODEC_ERROR;
275 // Initialize the decoder instance on the first frame
276 if (ctx->pbi == NULL) {
278 if (ctx->pbi == NULL)
279 return VPX_CODEC_ERROR;
282 // Set these even if already initialized. The caller may have changed the
283 // decrypt config between frames.
284 ctx->pbi->decrypt_cb = ctx->decrypt_cb;
285 ctx->pbi->decrypt_state = ctx->decrypt_state;
287 cm = &ctx->pbi->common;
289 if (vp9_receive_compressed_data(ctx->pbi, data_sz, data))
290 return update_error_state(ctx, &cm->error);
292 if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)
293 set_ppflags(ctx, &flags);
298 static INLINE uint8_t read_marker(vpx_decrypt_cb decrypt_cb,
300 const uint8_t *data) {
303 decrypt_cb(decrypt_state, data, &marker, 1);
309 static void parse_superframe_index(const uint8_t *data, size_t data_sz,
310 uint32_t sizes[8], int *count,
311 vpx_decrypt_cb decrypt_cb,
312 void *decrypt_state) {
316 marker = read_marker(decrypt_cb, decrypt_state, data + data_sz - 1);
319 if ((marker & 0xe0) == 0xc0) {
320 const uint32_t frames = (marker & 0x7) + 1;
321 const uint32_t mag = ((marker >> 3) & 0x3) + 1;
322 const size_t index_sz = 2 + mag * frames;
324 if (data_sz >= index_sz) {
325 uint8_t marker2 = read_marker(decrypt_cb, decrypt_state,
326 data + data_sz - index_sz);
328 if (marker == marker2) {
329 // Found a valid superframe index.
331 const uint8_t *x = &data[data_sz - index_sz + 1];
333 // Frames has a maximum of 8 and mag has a maximum of 4.
334 uint8_t clear_buffer[32];
335 assert(sizeof(clear_buffer) >= frames * mag);
337 decrypt_cb(decrypt_state, x, clear_buffer, frames * mag);
341 for (i = 0; i < frames; ++i) {
342 uint32_t this_sz = 0;
344 for (j = 0; j < mag; ++j)
345 this_sz |= (*x++) << (j * 8);
355 static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx,
356 const uint8_t *data, unsigned int data_sz,
357 void *user_priv, long deadline) {
358 const uint8_t *data_start = data;
359 const uint8_t * const data_end = data + data_sz;
361 uint32_t frame_sizes[8];
364 if (data == NULL || data_sz == 0)
365 return VPX_CODEC_INVALID_PARAM;
367 parse_superframe_index(data, data_sz, frame_sizes, &frame_count,
368 ctx->decrypt_cb, ctx->decrypt_state);
370 if (ctx->frame_parallel_decode) {
371 // Decode in frame parallel mode. When decoding in this mode, the frame
372 // passed to the decoder must be either a normal frame or a superframe with
373 // superframe index so the decoder could get each frame's start position
374 // in the superframe.
375 if (frame_count > 0) {
378 for (i = 0; i < frame_count; ++i) {
379 const uint8_t *data_start_copy = data_start;
380 const uint32_t frame_size = frame_sizes[i];
382 if (data_start < data
383 || frame_size > (uint32_t) (data_end - data_start)) {
384 ctx->base.err_detail = "Invalid frame size in index";
385 return VPX_CODEC_CORRUPT_FRAME;
388 res = decode_one(ctx, &data_start_copy, frame_size, user_priv,
390 if (res != VPX_CODEC_OK)
393 data_start += frame_size;
396 res = decode_one(ctx, &data_start, data_sz, user_priv, deadline);
397 if (res != VPX_CODEC_OK)
400 // Extra data detected after the frame.
401 if (data_start < data_end - 1) {
402 ctx->base.err_detail = "Fail to decode frame in parallel mode";
403 return VPX_CODEC_INCAPABLE;
407 // Decode in serial mode.
408 if (frame_count > 0) {
411 for (i = 0; i < frame_count; ++i) {
412 const uint8_t *data_start_copy = data_start;
413 const uint32_t frame_size = frame_sizes[i];
415 if (data_start < data
416 || frame_size > (uint32_t) (data_end - data_start)) {
417 ctx->base.err_detail = "Invalid frame size in index";
418 return VPX_CODEC_CORRUPT_FRAME;
421 res = decode_one(ctx, &data_start_copy, frame_size, user_priv,
423 if (res != VPX_CODEC_OK)
426 data_start += frame_size;
429 while (data_start < data_end) {
430 const uint32_t frame_size = (uint32_t) (data_end - data_start);
431 const vpx_codec_err_t res = decode_one(ctx, &data_start, frame_size,
432 user_priv, deadline);
433 if (res != VPX_CODEC_OK)
436 // Account for suboptimal termination by the encoder.
437 while (data_start < data_end) {
438 const uint8_t marker = read_marker(ctx->decrypt_cb,
439 ctx->decrypt_state, data_start);
451 static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx,
452 vpx_codec_iter_t *iter) {
453 vpx_image_t *img = NULL;
455 // iter acts as a flip flop, so an image is only returned on the first
456 // call to get_frame.
457 if (*iter == NULL && ctx->pbi != NULL) {
458 YV12_BUFFER_CONFIG sd;
459 vp9_ppflags_t flags = {0, 0, 0};
461 if (vp9_get_raw_frame(ctx->pbi, &sd, &flags) == 0) {
462 VP9_COMMON *cm = &ctx->pbi->common;
463 yuvconfig2image(&ctx->img, &sd, NULL);
464 ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
467 // Decrease reference count of last output frame in frame parallel mode.
468 if (ctx->frame_parallel_decode && ctx->last_show_frame >= 0) {
469 --cm->frame_bufs[ctx->last_show_frame].ref_count;
470 if (cm->frame_bufs[ctx->last_show_frame].ref_count == 0) {
471 cm->release_fb_cb(cm->cb_priv,
472 &cm->frame_bufs[ctx->last_show_frame].raw_frame_buffer);
475 ctx->last_show_frame = ctx->pbi->common.new_fb_idx;
482 static vpx_codec_err_t decoder_set_fb_fn(
483 vpx_codec_alg_priv_t *ctx,
484 vpx_get_frame_buffer_cb_fn_t cb_get,
485 vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
486 if (cb_get == NULL || cb_release == NULL) {
487 return VPX_CODEC_INVALID_PARAM;
488 } else if (ctx->pbi == NULL) {
489 // If the decoder has already been initialized, do not accept changes to
490 // the frame buffer functions.
491 ctx->get_ext_fb_cb = cb_get;
492 ctx->release_ext_fb_cb = cb_release;
493 ctx->ext_priv = cb_priv;
497 return VPX_CODEC_ERROR;
500 static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx,
502 vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *);
505 vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data;
506 YV12_BUFFER_CONFIG sd;
508 image2yuvconfig(&frame->img, &sd);
509 return vp9_set_reference_dec(&ctx->pbi->common,
510 (VP9_REFFRAME)frame->frame_type, &sd);
512 return VPX_CODEC_INVALID_PARAM;
516 static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx,
518 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
521 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
522 YV12_BUFFER_CONFIG sd;
524 image2yuvconfig(&frame->img, &sd);
526 return vp9_copy_reference_dec(ctx->pbi,
527 (VP9_REFFRAME)frame->frame_type, &sd);
529 return VPX_CODEC_INVALID_PARAM;
533 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx,
535 vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *);
538 YV12_BUFFER_CONFIG* fb;
540 vp9_get_reference_dec(ctx->pbi, data->idx, &fb);
541 yuvconfig2image(&data->img, fb, NULL);
544 return VPX_CODEC_INVALID_PARAM;
548 static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx,
550 #if CONFIG_VP9_POSTPROC
551 vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
554 ctx->postproc_cfg_set = 1;
555 ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data);
558 return VPX_CODEC_INVALID_PARAM;
563 return VPX_CODEC_INCAPABLE;
567 static vpx_codec_err_t ctrl_set_dbg_options(vpx_codec_alg_priv_t *ctx,
571 return VPX_CODEC_INCAPABLE;
574 static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
576 int *const update_info = va_arg(args, int *);
580 *update_info = ctx->pbi->refresh_frame_flags;
582 return VPX_CODEC_ERROR;
585 return VPX_CODEC_INVALID_PARAM;
590 static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
592 int *corrupted = va_arg(args, int *);
596 *corrupted = ctx->pbi->common.frame_to_show->corrupted;
598 return VPX_CODEC_ERROR;
601 return VPX_CODEC_INVALID_PARAM;
605 static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx,
607 int *const display_size = va_arg(args, int *);
611 const VP9_COMMON *const cm = &ctx->pbi->common;
612 display_size[0] = cm->display_width;
613 display_size[1] = cm->display_height;
615 return VPX_CODEC_ERROR;
619 return VPX_CODEC_INVALID_PARAM;
623 static vpx_codec_err_t ctrl_set_invert_tile_order(vpx_codec_alg_priv_t *ctx,
625 ctx->invert_tile_order = va_arg(args, int);
629 static vpx_codec_err_t ctrl_set_decryptor(vpx_codec_alg_priv_t *ctx,
631 vpx_decrypt_init *init = va_arg(args, vpx_decrypt_init *);
632 ctx->decrypt_cb = init ? init->decrypt_cb : NULL;
633 ctx->decrypt_state = init ? init->decrypt_state : NULL;
637 static vpx_codec_ctrl_fn_map_t decoder_ctrl_maps[] = {
638 {VP8_COPY_REFERENCE, ctrl_copy_reference},
641 {VP8_SET_REFERENCE, ctrl_set_reference},
642 {VP8_SET_POSTPROC, ctrl_set_postproc},
643 {VP8_SET_DBG_COLOR_REF_FRAME, ctrl_set_dbg_options},
644 {VP8_SET_DBG_COLOR_MB_MODES, ctrl_set_dbg_options},
645 {VP8_SET_DBG_COLOR_B_MODES, ctrl_set_dbg_options},
646 {VP8_SET_DBG_DISPLAY_MV, ctrl_set_dbg_options},
647 {VP9_INVERT_TILE_DECODE_ORDER, ctrl_set_invert_tile_order},
648 {VPXD_SET_DECRYPTOR, ctrl_set_decryptor},
651 {VP8D_GET_LAST_REF_UPDATES, ctrl_get_last_ref_updates},
652 {VP8D_GET_FRAME_CORRUPTED, ctrl_get_frame_corrupted},
653 {VP9_GET_REFERENCE, ctrl_get_reference},
654 {VP9D_GET_DISPLAY_SIZE, ctrl_get_display_size},
659 #ifndef VERSION_STRING
660 #define VERSION_STRING
662 CODEC_INTERFACE(vpx_codec_vp9_dx) = {
663 "WebM Project VP9 Decoder" VERSION_STRING,
664 VPX_CODEC_INTERNAL_ABI_VERSION,
665 VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC |
666 VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER, // vpx_codec_caps_t
667 decoder_init, // vpx_codec_init_fn_t
668 decoder_destroy, // vpx_codec_destroy_fn_t
669 decoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t
670 NOT_IMPLEMENTED, // vpx_codec_get_mmap_fn_t
671 NOT_IMPLEMENTED, // vpx_codec_set_mmap_fn_t
673 decoder_peek_si, // vpx_codec_peek_si_fn_t
674 decoder_get_si, // vpx_codec_get_si_fn_t
675 decoder_decode, // vpx_codec_decode_fn_t
676 decoder_get_frame, // vpx_codec_frame_get_fn_t
677 decoder_set_fb_fn, // vpx_codec_set_fb_fn_t
680 NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t
681 NOT_IMPLEMENTED, // vpx_codec_encode_fn_t
682 NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t
683 NOT_IMPLEMENTED, // vpx_codec_enc_config_set_fn_t
684 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t
685 NOT_IMPLEMENTED, // vpx_codec_get_preview_frame_fn_t
686 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t