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 "./vp8_rtcd.h"
15 #include "./vpx_dsp_rtcd.h"
16 #include "./vpx_scale_rtcd.h"
17 #include "vpx/vpx_decoder.h"
18 #include "vpx/vp8dx.h"
19 #include "vpx/internal/vpx_codec_internal.h"
20 #include "vpx_version.h"
21 #include "common/alloccommon.h"
22 #include "common/common.h"
23 #include "common/onyxd.h"
24 #include "decoder/onyxd_int.h"
25 #include "vpx_dsp/vpx_dsp_common.h"
26 #include "vpx_mem/vpx_mem.h"
27 #if CONFIG_ERROR_CONCEALMENT
28 #include "decoder/error_concealment.h"
30 #include "decoder/decoderthreading.h"
32 #define VP8_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0)
33 #define VP8_CAP_ERROR_CONCEALMENT (CONFIG_ERROR_CONCEALMENT ? \
34 VPX_CODEC_CAP_ERROR_CONCEALMENT : 0)
36 typedef vpx_codec_stream_info_t vp8_stream_info_t
;
38 /* Structures for handling memory allocations */
41 VP8_SEG_ALG_PRIV
= 256,
44 #define NELEMENTS(x) ((int)(sizeof(x)/sizeof(x[0])))
46 struct vpx_codec_alg_priv
48 vpx_codec_priv_t base
;
49 vpx_codec_dec_cfg_t cfg
;
53 vp8_postproc_cfg_t postproc_cfg
;
54 #if CONFIG_POSTPROC_VISUALIZER
55 unsigned int dbg_postproc_flag
;
56 int dbg_color_ref_frame_flag
;
57 int dbg_color_mb_modes_flag
;
58 int dbg_color_b_modes_flag
;
59 int dbg_display_mv_flag
;
61 vpx_decrypt_cb decrypt_cb
;
65 struct frame_buffers yv12_frame_buffers
;
67 FRAGMENT_DATA fragments
;
70 static void vp8_init_ctx(vpx_codec_ctx_t
*ctx
)
72 vpx_codec_alg_priv_t
*priv
=
73 (vpx_codec_alg_priv_t
*)vpx_calloc(1, sizeof(*priv
));
75 ctx
->priv
= (vpx_codec_priv_t
*)priv
;
76 ctx
->priv
->init_flags
= ctx
->init_flags
;
78 priv
->si
.sz
= sizeof(priv
->si
);
79 priv
->decrypt_cb
= NULL
;
80 priv
->decrypt_state
= NULL
;
84 /* Update the reference to the config structure to an internal copy. */
85 priv
->cfg
= *ctx
->config
.dec
;
86 ctx
->config
.dec
= &priv
->cfg
;
90 static vpx_codec_err_t
vp8_init(vpx_codec_ctx_t
*ctx
,
91 vpx_codec_priv_enc_mr_cfg_t
*data
)
93 vpx_codec_err_t res
= VPX_CODEC_OK
;
94 vpx_codec_alg_priv_t
*priv
= NULL
;
101 /* This function only allocates space for the vpx_codec_alg_priv_t
102 * structure. More memory may be required at the time the stream
103 * information becomes known.
107 priv
= (vpx_codec_alg_priv_t
*)ctx
->priv
;
109 /* initialize number of fragments to zero */
110 priv
->fragments
.count
= 0;
111 /* is input fragments enabled? */
112 priv
->fragments
.enabled
=
113 (priv
->base
.init_flags
& VPX_CODEC_USE_INPUT_FRAGMENTS
);
115 /*post processing level initialized to do nothing */
117 priv
= (vpx_codec_alg_priv_t
*)ctx
->priv
;
120 priv
->yv12_frame_buffers
.use_frame_threads
=
121 (ctx
->priv
->init_flags
& VPX_CODEC_USE_FRAME_THREADING
);
123 /* for now, disable frame threading */
124 priv
->yv12_frame_buffers
.use_frame_threads
= 0;
126 if (priv
->yv12_frame_buffers
.use_frame_threads
&&
127 ((ctx
->priv
->init_flags
& VPX_CODEC_USE_ERROR_CONCEALMENT
) ||
128 (ctx
->priv
->init_flags
& VPX_CODEC_USE_INPUT_FRAGMENTS
))) {
129 /* row-based threading, error concealment, and input fragments will
130 * not be supported when using frame-based threading */
131 res
= VPX_CODEC_INVALID_PARAM
;
137 static vpx_codec_err_t
vp8_destroy(vpx_codec_alg_priv_t
*ctx
)
139 vp8_remove_decoder_instances(&ctx
->yv12_frame_buffers
);
146 static vpx_codec_err_t
vp8_peek_si_internal(const uint8_t *data
,
147 unsigned int data_sz
,
148 vpx_codec_stream_info_t
*si
,
149 vpx_decrypt_cb decrypt_cb
,
152 vpx_codec_err_t res
= VPX_CODEC_OK
;
154 if(data
+ data_sz
<= data
)
156 res
= VPX_CODEC_INVALID_PARAM
;
160 /* Parse uncompresssed part of key frame header.
161 * 3 bytes:- including version, frame type and an offset
162 * 3 bytes:- sync code (0x9d, 0x01, 0x2a)
163 * 4 bytes:- including image width and height in the lowest 14 bits
164 * of each 2-byte value.
166 uint8_t clear_buffer
[10];
167 const uint8_t *clear
= data
;
170 int n
= VPXMIN(sizeof(clear_buffer
), data_sz
);
171 decrypt_cb(decrypt_state
, data
, clear_buffer
, n
);
172 clear
= clear_buffer
;
176 if (data_sz
>= 10 && !(clear
[0] & 0x01)) /* I-Frame */
180 /* vet via sync code */
181 if (clear
[3] != 0x9d || clear
[4] != 0x01 || clear
[5] != 0x2a)
182 return VPX_CODEC_UNSUP_BITSTREAM
;
184 si
->w
= (clear
[6] | (clear
[7] << 8)) & 0x3fff;
185 si
->h
= (clear
[8] | (clear
[9] << 8)) & 0x3fff;
187 /*printf("w=%d, h=%d\n", si->w, si->h);*/
188 if (!(si
->h
| si
->w
))
189 res
= VPX_CODEC_UNSUP_BITSTREAM
;
193 res
= VPX_CODEC_UNSUP_BITSTREAM
;
200 static vpx_codec_err_t
vp8_peek_si(const uint8_t *data
,
201 unsigned int data_sz
,
202 vpx_codec_stream_info_t
*si
) {
203 return vp8_peek_si_internal(data
, data_sz
, si
, NULL
, NULL
);
206 static vpx_codec_err_t
vp8_get_si(vpx_codec_alg_priv_t
*ctx
,
207 vpx_codec_stream_info_t
*si
)
212 if (si
->sz
>= sizeof(vp8_stream_info_t
))
213 sz
= sizeof(vp8_stream_info_t
);
215 sz
= sizeof(vpx_codec_stream_info_t
);
217 memcpy(si
, &ctx
->si
, sz
);
224 static vpx_codec_err_t
225 update_error_state(vpx_codec_alg_priv_t
*ctx
,
226 const struct vpx_internal_error_info
*error
)
230 if ((res
= error
->error_code
))
231 ctx
->base
.err_detail
= error
->has_detail
238 static void yuvconfig2image(vpx_image_t
*img
,
239 const YV12_BUFFER_CONFIG
*yv12
,
242 /** vpx_img_wrap() doesn't allow specifying independent strides for
243 * the Y, U, and V planes, nor other alignment adjustments that
244 * might be representable by a YV12_BUFFER_CONFIG, so we just
245 * initialize all the fields.*/
246 img
->fmt
= VPX_IMG_FMT_I420
;
247 img
->w
= yv12
->y_stride
;
248 img
->h
= (yv12
->y_height
+ 2 * VP8BORDERINPIXELS
+ 15) & ~15;
249 img
->d_w
= img
->r_w
= yv12
->y_width
;
250 img
->d_h
= img
->r_h
= yv12
->y_height
;
251 img
->x_chroma_shift
= 1;
252 img
->y_chroma_shift
= 1;
253 img
->planes
[VPX_PLANE_Y
] = yv12
->y_buffer
;
254 img
->planes
[VPX_PLANE_U
] = yv12
->u_buffer
;
255 img
->planes
[VPX_PLANE_V
] = yv12
->v_buffer
;
256 img
->planes
[VPX_PLANE_ALPHA
] = NULL
;
257 img
->stride
[VPX_PLANE_Y
] = yv12
->y_stride
;
258 img
->stride
[VPX_PLANE_U
] = yv12
->uv_stride
;
259 img
->stride
[VPX_PLANE_V
] = yv12
->uv_stride
;
260 img
->stride
[VPX_PLANE_ALPHA
] = yv12
->y_stride
;
263 img
->user_priv
= user_priv
;
264 img
->img_data
= yv12
->buffer_alloc
;
265 img
->img_data_owner
= 0;
266 img
->self_allocd
= 0;
270 update_fragments(vpx_codec_alg_priv_t
*ctx
,
272 unsigned int data_sz
,
273 vpx_codec_err_t
*res
)
277 if (ctx
->fragments
.count
== 0)
279 /* New frame, reset fragment pointers and sizes */
280 memset((void*)ctx
->fragments
.ptrs
, 0, sizeof(ctx
->fragments
.ptrs
));
281 memset(ctx
->fragments
.sizes
, 0, sizeof(ctx
->fragments
.sizes
));
283 if (ctx
->fragments
.enabled
&& !(data
== NULL
&& data_sz
== 0))
285 /* Store a pointer to this fragment and return. We haven't
286 * received the complete frame yet, so we will wait with decoding.
288 ctx
->fragments
.ptrs
[ctx
->fragments
.count
] = data
;
289 ctx
->fragments
.sizes
[ctx
->fragments
.count
] = data_sz
;
290 ctx
->fragments
.count
++;
291 if (ctx
->fragments
.count
> (1 << EIGHT_PARTITION
) + 1)
293 ctx
->fragments
.count
= 0;
294 *res
= VPX_CODEC_INVALID_PARAM
;
300 if (!ctx
->fragments
.enabled
&& (data
== NULL
&& data_sz
== 0))
305 if (!ctx
->fragments
.enabled
)
307 ctx
->fragments
.ptrs
[0] = data
;
308 ctx
->fragments
.sizes
[0] = data_sz
;
309 ctx
->fragments
.count
= 1;
315 static vpx_codec_err_t
vp8_decode(vpx_codec_alg_priv_t
*ctx
,
317 unsigned int data_sz
,
321 vpx_codec_err_t res
= VPX_CODEC_OK
;
322 unsigned int resolution_change
= 0;
325 if (!ctx
->fragments
.enabled
&& (data
== NULL
&& data_sz
== 0))
330 /* Update the input fragment data */
331 if(update_fragments(ctx
, data
, data_sz
, &res
) <= 0)
334 /* Determine the stream parameters. Note that we rely on peek_si to
335 * validate that we have a buffer that does not wrap around the top
341 res
= vp8_peek_si_internal(ctx
->fragments
.ptrs
[0], ctx
->fragments
.sizes
[0],
342 &ctx
->si
, ctx
->decrypt_cb
, ctx
->decrypt_state
);
344 if((res
== VPX_CODEC_UNSUP_BITSTREAM
) && !ctx
->si
.is_kf
)
346 /* the peek function returns an error for non keyframes, however for
347 * this case, it is not an error */
351 if(!ctx
->decoder_init
&& !ctx
->si
.is_kf
)
352 res
= VPX_CODEC_UNSUP_BITSTREAM
;
354 if ((ctx
->si
.h
!= h
) || (ctx
->si
.w
!= w
))
355 resolution_change
= 1;
357 /* Initialize the decoder instance on the first frame*/
358 if (!res
&& !ctx
->decoder_init
)
362 oxcf
.Width
= ctx
->si
.w
;
363 oxcf
.Height
= ctx
->si
.h
;
365 oxcf
.postprocess
= 0;
366 oxcf
.max_threads
= ctx
->cfg
.threads
;
367 oxcf
.error_concealment
=
368 (ctx
->base
.init_flags
& VPX_CODEC_USE_ERROR_CONCEALMENT
);
370 /* If postprocessing was enabled by the application and a
371 * configuration has not been provided, default it.
373 if (!ctx
->postproc_cfg_set
374 && (ctx
->base
.init_flags
& VPX_CODEC_USE_POSTPROC
)) {
375 ctx
->postproc_cfg
.post_proc_flag
=
376 VP8_DEBLOCK
| VP8_DEMACROBLOCK
| VP8_MFQE
;
377 ctx
->postproc_cfg
.deblocking_level
= 4;
378 ctx
->postproc_cfg
.noise_level
= 0;
381 res
= vp8_create_decoder_instances(&ctx
->yv12_frame_buffers
, &oxcf
);
382 ctx
->decoder_init
= 1;
385 /* Set these even if already initialized. The caller may have changed the
386 * decrypt config between frames.
388 if (ctx
->decoder_init
) {
389 ctx
->yv12_frame_buffers
.pbi
[0]->decrypt_cb
= ctx
->decrypt_cb
;
390 ctx
->yv12_frame_buffers
.pbi
[0]->decrypt_state
= ctx
->decrypt_state
;
395 VP8D_COMP
*pbi
= ctx
->yv12_frame_buffers
.pbi
[0];
396 if (resolution_change
)
398 VP8_COMMON
*const pc
= & pbi
->common
;
399 MACROBLOCKD
*const xd
= & pbi
->mb
;
400 #if CONFIG_MULTITHREAD
403 pc
->Width
= ctx
->si
.w
;
404 pc
->Height
= ctx
->si
.h
;
406 int prev_mb_rows
= pc
->mb_rows
;
408 if (setjmp(pbi
->common
.error
.jmp
))
410 pbi
->common
.error
.setjmp
= 0;
411 vp8_clear_system_state();
412 /* same return value as used in vp8dx_receive_compressed_data */
416 pbi
->common
.error
.setjmp
= 1;
421 vpx_internal_error(&pc
->error
, VPX_CODEC_CORRUPT_FRAME
,
422 "Invalid frame width");
428 vpx_internal_error(&pc
->error
, VPX_CODEC_CORRUPT_FRAME
,
429 "Invalid frame height");
432 if (vp8_alloc_frame_buffers(pc
, pc
->Width
, pc
->Height
))
433 vpx_internal_error(&pc
->error
, VPX_CODEC_MEM_ERROR
,
434 "Failed to allocate frame buffers");
436 xd
->pre
= pc
->yv12_fb
[pc
->lst_fb_idx
];
437 xd
->dst
= pc
->yv12_fb
[pc
->new_fb_idx
];
439 #if CONFIG_MULTITHREAD
440 for (i
= 0; i
< pbi
->allocated_decoding_thread_count
; i
++)
442 pbi
->mb_row_di
[i
].mbd
.dst
= pc
->yv12_fb
[pc
->new_fb_idx
];
443 vp8_build_block_doffsets(&pbi
->mb_row_di
[i
].mbd
);
446 vp8_build_block_doffsets(&pbi
->mb
);
448 /* allocate memory for last frame MODE_INFO array */
449 #if CONFIG_ERROR_CONCEALMENT
453 /* old prev_mip was released by vp8_de_alloc_frame_buffers()
454 * called in vp8_alloc_frame_buffers() */
455 pc
->prev_mip
= vpx_calloc(
456 (pc
->mb_cols
+ 1) * (pc
->mb_rows
+ 1),
461 vp8_de_alloc_frame_buffers(pc
);
462 vpx_internal_error(&pc
->error
, VPX_CODEC_MEM_ERROR
,
464 "last frame MODE_INFO array");
467 pc
->prev_mi
= pc
->prev_mip
+ pc
->mode_info_stride
+ 1;
469 if (vp8_alloc_overlap_lists(pbi
))
470 vpx_internal_error(&pc
->error
, VPX_CODEC_MEM_ERROR
,
471 "Failed to allocate overlap lists "
472 "for error concealment");
477 #if CONFIG_MULTITHREAD
478 if (pbi
->b_multithreaded_rd
)
479 vp8mt_alloc_temp_buffers(pbi
, pc
->Width
, prev_mb_rows
);
485 pbi
->common
.error
.setjmp
= 0;
487 /* required to get past the first get_free_fb() call */
488 pbi
->common
.fb_idx_ref_cnt
[0] = 0;
491 /* update the pbi fragment data */
492 pbi
->fragments
= ctx
->fragments
;
494 ctx
->user_priv
= user_priv
;
495 if (vp8dx_receive_compressed_data(pbi
, data_sz
, data
, deadline
))
497 res
= update_error_state(ctx
, &pbi
->common
.error
);
500 /* get ready for the next series of fragments */
501 ctx
->fragments
.count
= 0;
507 static vpx_image_t
*vp8_get_frame(vpx_codec_alg_priv_t
*ctx
,
508 vpx_codec_iter_t
*iter
)
510 vpx_image_t
*img
= NULL
;
512 /* iter acts as a flip flop, so an image is only returned on the first
515 if (!(*iter
) && ctx
->yv12_frame_buffers
.pbi
[0])
517 YV12_BUFFER_CONFIG sd
;
518 int64_t time_stamp
= 0, time_end_stamp
= 0;
519 vp8_ppflags_t flags
= {0};
521 if (ctx
->base
.init_flags
& VPX_CODEC_USE_POSTPROC
)
523 flags
.post_proc_flag
= ctx
->postproc_cfg
.post_proc_flag
524 #if CONFIG_POSTPROC_VISUALIZER
526 | ((ctx
->dbg_color_ref_frame_flag
!= 0) ? VP8D_DEBUG_CLR_FRM_REF_BLKS
: 0)
527 | ((ctx
->dbg_color_mb_modes_flag
!= 0) ? VP8D_DEBUG_CLR_BLK_MODES
: 0)
528 | ((ctx
->dbg_color_b_modes_flag
!= 0) ? VP8D_DEBUG_CLR_BLK_MODES
: 0)
529 | ((ctx
->dbg_display_mv_flag
!= 0) ? VP8D_DEBUG_DRAW_MV
: 0)
532 flags
.deblocking_level
= ctx
->postproc_cfg
.deblocking_level
;
533 flags
.noise_level
= ctx
->postproc_cfg
.noise_level
;
534 #if CONFIG_POSTPROC_VISUALIZER
535 flags
.display_ref_frame_flag
= ctx
->dbg_color_ref_frame_flag
;
536 flags
.display_mb_modes_flag
= ctx
->dbg_color_mb_modes_flag
;
537 flags
.display_b_modes_flag
= ctx
->dbg_color_b_modes_flag
;
538 flags
.display_mv_flag
= ctx
->dbg_display_mv_flag
;
542 if (0 == vp8dx_get_raw_frame(ctx
->yv12_frame_buffers
.pbi
[0], &sd
,
543 &time_stamp
, &time_end_stamp
, &flags
))
545 yuvconfig2image(&ctx
->img
, &sd
, ctx
->user_priv
);
555 static vpx_codec_err_t
image2yuvconfig(const vpx_image_t
*img
,
556 YV12_BUFFER_CONFIG
*yv12
)
558 const int y_w
= img
->d_w
;
559 const int y_h
= img
->d_h
;
560 const int uv_w
= (img
->d_w
+ 1) / 2;
561 const int uv_h
= (img
->d_h
+ 1) / 2;
562 vpx_codec_err_t res
= VPX_CODEC_OK
;
563 yv12
->y_buffer
= img
->planes
[VPX_PLANE_Y
];
564 yv12
->u_buffer
= img
->planes
[VPX_PLANE_U
];
565 yv12
->v_buffer
= img
->planes
[VPX_PLANE_V
];
567 yv12
->y_crop_width
= y_w
;
568 yv12
->y_crop_height
= y_h
;
570 yv12
->y_height
= y_h
;
571 yv12
->uv_crop_width
= uv_w
;
572 yv12
->uv_crop_height
= uv_h
;
573 yv12
->uv_width
= uv_w
;
574 yv12
->uv_height
= uv_h
;
576 yv12
->y_stride
= img
->stride
[VPX_PLANE_Y
];
577 yv12
->uv_stride
= img
->stride
[VPX_PLANE_U
];
579 yv12
->border
= (img
->stride
[VPX_PLANE_Y
] - img
->d_w
) / 2;
584 static vpx_codec_err_t
vp8_set_reference(vpx_codec_alg_priv_t
*ctx
,
588 vpx_ref_frame_t
*data
= va_arg(args
, vpx_ref_frame_t
*);
590 if (data
&& !ctx
->yv12_frame_buffers
.use_frame_threads
)
592 vpx_ref_frame_t
*frame
= (vpx_ref_frame_t
*)data
;
593 YV12_BUFFER_CONFIG sd
;
595 image2yuvconfig(&frame
->img
, &sd
);
597 return vp8dx_set_reference(ctx
->yv12_frame_buffers
.pbi
[0],
598 frame
->frame_type
, &sd
);
601 return VPX_CODEC_INVALID_PARAM
;
605 static vpx_codec_err_t
vp8_get_reference(vpx_codec_alg_priv_t
*ctx
,
609 vpx_ref_frame_t
*data
= va_arg(args
, vpx_ref_frame_t
*);
611 if (data
&& !ctx
->yv12_frame_buffers
.use_frame_threads
)
613 vpx_ref_frame_t
*frame
= (vpx_ref_frame_t
*)data
;
614 YV12_BUFFER_CONFIG sd
;
616 image2yuvconfig(&frame
->img
, &sd
);
618 return vp8dx_get_reference(ctx
->yv12_frame_buffers
.pbi
[0],
619 frame
->frame_type
, &sd
);
622 return VPX_CODEC_INVALID_PARAM
;
626 static vpx_codec_err_t
vp8_set_postproc(vpx_codec_alg_priv_t
*ctx
,
630 vp8_postproc_cfg_t
*data
= va_arg(args
, vp8_postproc_cfg_t
*);
634 ctx
->postproc_cfg_set
= 1;
635 ctx
->postproc_cfg
= *((vp8_postproc_cfg_t
*)data
);
639 return VPX_CODEC_INVALID_PARAM
;
644 return VPX_CODEC_INCAPABLE
;
649 static vpx_codec_err_t
vp8_set_dbg_color_ref_frame(vpx_codec_alg_priv_t
*ctx
,
651 #if CONFIG_POSTPROC_VISUALIZER && CONFIG_POSTPROC
652 ctx
->dbg_color_ref_frame_flag
= va_arg(args
, int);
657 return VPX_CODEC_INCAPABLE
;
661 static vpx_codec_err_t
vp8_set_dbg_color_mb_modes(vpx_codec_alg_priv_t
*ctx
,
663 #if CONFIG_POSTPROC_VISUALIZER && CONFIG_POSTPROC
664 ctx
->dbg_color_mb_modes_flag
= va_arg(args
, int);
669 return VPX_CODEC_INCAPABLE
;
673 static vpx_codec_err_t
vp8_set_dbg_color_b_modes(vpx_codec_alg_priv_t
*ctx
,
675 #if CONFIG_POSTPROC_VISUALIZER && CONFIG_POSTPROC
676 ctx
->dbg_color_b_modes_flag
= va_arg(args
, int);
681 return VPX_CODEC_INCAPABLE
;
685 static vpx_codec_err_t
vp8_set_dbg_display_mv(vpx_codec_alg_priv_t
*ctx
,
687 #if CONFIG_POSTPROC_VISUALIZER && CONFIG_POSTPROC
688 ctx
->dbg_display_mv_flag
= va_arg(args
, int);
693 return VPX_CODEC_INCAPABLE
;
697 static vpx_codec_err_t
vp8_get_last_ref_updates(vpx_codec_alg_priv_t
*ctx
,
700 int *update_info
= va_arg(args
, int *);
702 if (update_info
&& !ctx
->yv12_frame_buffers
.use_frame_threads
)
704 VP8D_COMP
*pbi
= (VP8D_COMP
*)ctx
->yv12_frame_buffers
.pbi
[0];
706 *update_info
= pbi
->common
.refresh_alt_ref_frame
* (int) VP8_ALTR_FRAME
707 + pbi
->common
.refresh_golden_frame
* (int) VP8_GOLD_FRAME
708 + pbi
->common
.refresh_last_frame
* (int) VP8_LAST_FRAME
;
713 return VPX_CODEC_INVALID_PARAM
;
716 extern int vp8dx_references_buffer( VP8_COMMON
*oci
, int ref_frame
);
717 static vpx_codec_err_t
vp8_get_last_ref_frame(vpx_codec_alg_priv_t
*ctx
,
720 int *ref_info
= va_arg(args
, int *);
722 if (ref_info
&& !ctx
->yv12_frame_buffers
.use_frame_threads
)
724 VP8D_COMP
*pbi
= (VP8D_COMP
*)ctx
->yv12_frame_buffers
.pbi
[0];
725 VP8_COMMON
*oci
= &pbi
->common
;
727 (vp8dx_references_buffer( oci
, ALTREF_FRAME
)?VP8_ALTR_FRAME
:0) |
728 (vp8dx_references_buffer( oci
, GOLDEN_FRAME
)?VP8_GOLD_FRAME
:0) |
729 (vp8dx_references_buffer( oci
, LAST_FRAME
)?VP8_LAST_FRAME
:0);
734 return VPX_CODEC_INVALID_PARAM
;
737 static vpx_codec_err_t
vp8_get_frame_corrupted(vpx_codec_alg_priv_t
*ctx
,
741 int *corrupted
= va_arg(args
, int *);
742 VP8D_COMP
*pbi
= (VP8D_COMP
*)ctx
->yv12_frame_buffers
.pbi
[0];
744 if (corrupted
&& pbi
)
746 const YV12_BUFFER_CONFIG
*const frame
= pbi
->common
.frame_to_show
;
747 if (frame
== NULL
) return VPX_CODEC_ERROR
;
748 *corrupted
= frame
->corrupted
;
752 return VPX_CODEC_INVALID_PARAM
;
756 static vpx_codec_err_t
vp8_set_decryptor(vpx_codec_alg_priv_t
*ctx
,
759 vpx_decrypt_init
*init
= va_arg(args
, vpx_decrypt_init
*);
763 ctx
->decrypt_cb
= init
->decrypt_cb
;
764 ctx
->decrypt_state
= init
->decrypt_state
;
768 ctx
->decrypt_cb
= NULL
;
769 ctx
->decrypt_state
= NULL
;
774 vpx_codec_ctrl_fn_map_t vp8_ctf_maps
[] =
776 {VP8_SET_REFERENCE
, vp8_set_reference
},
777 {VP8_COPY_REFERENCE
, vp8_get_reference
},
778 {VP8_SET_POSTPROC
, vp8_set_postproc
},
779 {VP8_SET_DBG_COLOR_REF_FRAME
, vp8_set_dbg_color_ref_frame
},
780 {VP8_SET_DBG_COLOR_MB_MODES
, vp8_set_dbg_color_mb_modes
},
781 {VP8_SET_DBG_COLOR_B_MODES
, vp8_set_dbg_color_b_modes
},
782 {VP8_SET_DBG_DISPLAY_MV
, vp8_set_dbg_display_mv
},
783 {VP8D_GET_LAST_REF_UPDATES
, vp8_get_last_ref_updates
},
784 {VP8D_GET_FRAME_CORRUPTED
, vp8_get_frame_corrupted
},
785 {VP8D_GET_LAST_REF_USED
, vp8_get_last_ref_frame
},
786 {VPXD_SET_DECRYPTOR
, vp8_set_decryptor
},
791 #ifndef VERSION_STRING
792 #define VERSION_STRING
794 CODEC_INTERFACE(vpx_codec_vp8_dx
) =
796 "WebM Project VP8 Decoder" VERSION_STRING
,
797 VPX_CODEC_INTERNAL_ABI_VERSION
,
798 VPX_CODEC_CAP_DECODER
| VP8_CAP_POSTPROC
| VP8_CAP_ERROR_CONCEALMENT
|
799 VPX_CODEC_CAP_INPUT_FRAGMENTS
,
800 /* vpx_codec_caps_t caps; */
801 vp8_init
, /* vpx_codec_init_fn_t init; */
802 vp8_destroy
, /* vpx_codec_destroy_fn_t destroy; */
803 vp8_ctf_maps
, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */
805 vp8_peek_si
, /* vpx_codec_peek_si_fn_t peek_si; */
806 vp8_get_si
, /* vpx_codec_get_si_fn_t get_si; */
807 vp8_decode
, /* vpx_codec_decode_fn_t decode; */
808 vp8_get_frame
, /* vpx_codec_frame_get_fn_t frame_get; */
811 { /* encoder functions */