2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
15 #include "config/aom_config.h"
16 #include "config/aom_version.h"
18 #include "aom/internal/aom_codec_internal.h"
19 #include "aom/internal/aom_image_internal.h"
20 #include "aom/aomdx.h"
21 #include "aom/aom_decoder.h"
22 #include "aom_dsp/bitreader_buffer.h"
23 #include "aom_dsp/aom_dsp_common.h"
24 #include "aom_ports/mem_ops.h"
25 #include "aom_util/aom_thread.h"
27 #include "av1/common/alloccommon.h"
28 #include "av1/common/frame_buffers.h"
29 #include "av1/common/enums.h"
30 #include "av1/common/obu_util.h"
32 #include "av1/decoder/decoder.h"
33 #include "av1/decoder/decodeframe.h"
34 #include "av1/decoder/grain_synthesis.h"
35 #include "av1/decoder/obu.h"
37 #include "av1/av1_iface_common.h"
39 struct aom_codec_alg_priv
{
40 aom_codec_priv_t base
;
41 aom_codec_dec_cfg_t cfg
;
42 aom_codec_stream_info_t si
;
46 int invert_tile_order
;
47 RefCntBuffer
*last_show_frame
; // Last output frame buffer
53 unsigned int tile_mode
;
54 unsigned int ext_tile_debug
;
56 EXTERNAL_REFERENCES ext_refs
;
57 unsigned int is_annexb
;
59 int output_all_layers
;
61 AVxWorker
*frame_worker
;
63 aom_image_t image_with_grain
;
64 aom_codec_frame_buffer_t grain_image_frame_buffers
[MAX_NUM_SPATIAL_LAYERS
];
65 size_t num_grain_image_frame_buffers
;
66 int need_resync
; // wait for key/intra-only frame
67 // BufferPool that holds all reference frames. Shared by all the FrameWorkers.
68 BufferPool
*buffer_pool
;
70 // External frame buffer info to save for AV1 common.
71 void *ext_priv
; // Private data associated with the external frame buffers.
72 aom_get_frame_buffer_cb_fn_t get_ext_fb_cb
;
73 aom_release_frame_buffer_cb_fn_t release_ext_fb_cb
;
76 aom_inspect_cb inspect_cb
;
81 static aom_codec_err_t
decoder_init(aom_codec_ctx_t
*ctx
) {
82 // This function only allocates space for the aom_codec_alg_priv_t
83 // structure. More memory may be required at the time the stream
84 // information becomes known.
86 aom_codec_alg_priv_t
*const priv
=
87 (aom_codec_alg_priv_t
*)aom_calloc(1, sizeof(*priv
));
88 if (priv
== NULL
) return AOM_CODEC_MEM_ERROR
;
90 ctx
->priv
= (aom_codec_priv_t
*)priv
;
91 ctx
->priv
->init_flags
= ctx
->init_flags
;
94 // TODO(tdaede): this should not be exposed to the API
95 priv
->cfg
.allow_lowbitdepth
= !FORCE_HIGHBITDEPTH_DECODING
;
96 if (ctx
->config
.dec
) {
97 priv
->cfg
= *ctx
->config
.dec
;
98 ctx
->config
.dec
= &priv
->cfg
;
100 priv
->num_grain_image_frame_buffers
= 0;
101 // Turn row_mt on by default.
104 // Turn on normal tile coding mode by default.
105 // 0 is for normal tile coding mode, and 1 is for large scale tile coding
106 // mode(refer to lightfield example).
108 priv
->decode_tile_row
= -1;
109 priv
->decode_tile_col
= -1;
115 static aom_codec_err_t
decoder_destroy(aom_codec_alg_priv_t
*ctx
) {
116 if (ctx
->frame_worker
!= NULL
) {
117 AVxWorker
*const worker
= ctx
->frame_worker
;
118 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
119 AV1Decoder
*const pbi
= frame_worker_data
->pbi
;
120 aom_get_worker_interface()->end(worker
);
121 aom_free(pbi
->common
.tpl_mvs
);
122 pbi
->common
.tpl_mvs
= NULL
;
123 av1_remove_common(&frame_worker_data
->pbi
->common
);
124 av1_free_cdef_buffers(&pbi
->common
, &pbi
->cdef_worker
, &pbi
->cdef_sync
,
126 av1_free_cdef_sync(&pbi
->cdef_sync
);
127 #if !CONFIG_REALTIME_ONLY
128 av1_free_restoration_buffers(&pbi
->common
);
130 av1_decoder_remove(pbi
);
131 aom_free(frame_worker_data
);
132 #if CONFIG_MULTITHREAD
133 pthread_mutex_destroy(&ctx
->buffer_pool
->pool_mutex
);
137 if (ctx
->buffer_pool
) {
138 for (size_t i
= 0; i
< ctx
->num_grain_image_frame_buffers
; i
++) {
139 ctx
->buffer_pool
->release_fb_cb(ctx
->buffer_pool
->cb_priv
,
140 &ctx
->grain_image_frame_buffers
[i
]);
142 av1_free_ref_frame_buffers(ctx
->buffer_pool
);
143 av1_free_internal_frame_buffers(&ctx
->buffer_pool
->int_frame_buffers
);
146 aom_free(ctx
->frame_worker
);
147 aom_free(ctx
->buffer_pool
);
148 aom_img_free(&ctx
->img
);
153 static aom_codec_err_t
parse_timing_info(struct aom_read_bit_buffer
*rb
) {
154 const uint32_t num_units_in_display_tick
=
155 aom_rb_read_unsigned_literal(rb
, 32);
156 const uint32_t time_scale
= aom_rb_read_unsigned_literal(rb
, 32);
157 if (num_units_in_display_tick
== 0 || time_scale
== 0)
158 return AOM_CODEC_UNSUP_BITSTREAM
;
159 const uint8_t equal_picture_interval
= aom_rb_read_bit(rb
);
160 if (equal_picture_interval
) {
161 const uint32_t num_ticks_per_picture_minus_1
= aom_rb_read_uvlc(rb
);
162 if (num_ticks_per_picture_minus_1
== UINT32_MAX
) {
163 // num_ticks_per_picture_minus_1 cannot be (1 << 32) - 1.
164 return AOM_CODEC_UNSUP_BITSTREAM
;
170 static aom_codec_err_t
parse_decoder_model_info(
171 struct aom_read_bit_buffer
*rb
, int *buffer_delay_length_minus_1
) {
172 *buffer_delay_length_minus_1
= aom_rb_read_literal(rb
, 5);
173 const uint32_t num_units_in_decoding_tick
=
174 aom_rb_read_unsigned_literal(rb
, 32);
175 const uint8_t buffer_removal_time_length_minus_1
= aom_rb_read_literal(rb
, 5);
176 const uint8_t frame_presentation_time_length_minus_1
=
177 aom_rb_read_literal(rb
, 5);
178 (void)num_units_in_decoding_tick
;
179 (void)buffer_removal_time_length_minus_1
;
180 (void)frame_presentation_time_length_minus_1
;
184 static aom_codec_err_t
parse_op_parameters_info(
185 struct aom_read_bit_buffer
*rb
, int buffer_delay_length_minus_1
) {
186 const int n
= buffer_delay_length_minus_1
+ 1;
187 const uint32_t decoder_buffer_delay
= aom_rb_read_unsigned_literal(rb
, n
);
188 const uint32_t encoder_buffer_delay
= aom_rb_read_unsigned_literal(rb
, n
);
189 const uint8_t low_delay_mode_flag
= aom_rb_read_bit(rb
);
190 (void)decoder_buffer_delay
;
191 (void)encoder_buffer_delay
;
192 (void)low_delay_mode_flag
;
196 // Parses the operating points (including operating_point_idc, seq_level_idx,
197 // and seq_tier) and then sets si->number_spatial_layers and
198 // si->number_temporal_layers based on operating_point_idc[0].
199 static aom_codec_err_t
parse_operating_points(struct aom_read_bit_buffer
*rb
,
200 int is_reduced_header
,
201 aom_codec_stream_info_t
*si
) {
202 int operating_point_idc0
= 0;
203 if (is_reduced_header
) {
204 aom_rb_read_literal(rb
, LEVEL_BITS
); // level
206 uint8_t decoder_model_info_present_flag
= 0;
207 int buffer_delay_length_minus_1
= 0;
208 aom_codec_err_t status
;
209 const uint8_t timing_info_present_flag
= aom_rb_read_bit(rb
);
210 if (timing_info_present_flag
) {
211 if ((status
= parse_timing_info(rb
)) != AOM_CODEC_OK
) return status
;
212 decoder_model_info_present_flag
= aom_rb_read_bit(rb
);
213 if (decoder_model_info_present_flag
) {
214 if ((status
= parse_decoder_model_info(
215 rb
, &buffer_delay_length_minus_1
)) != AOM_CODEC_OK
)
219 const uint8_t initial_display_delay_present_flag
= aom_rb_read_bit(rb
);
220 const uint8_t operating_points_cnt_minus_1
=
221 aom_rb_read_literal(rb
, OP_POINTS_CNT_MINUS_1_BITS
);
222 for (int i
= 0; i
< operating_points_cnt_minus_1
+ 1; i
++) {
223 int operating_point_idc
;
224 operating_point_idc
= aom_rb_read_literal(rb
, OP_POINTS_IDC_BITS
);
225 if (i
== 0) operating_point_idc0
= operating_point_idc
;
226 int seq_level_idx
= aom_rb_read_literal(rb
, LEVEL_BITS
); // level
227 if (seq_level_idx
> 7) aom_rb_read_bit(rb
); // tier
228 if (decoder_model_info_present_flag
) {
229 const uint8_t decoder_model_present_for_this_op
= aom_rb_read_bit(rb
);
230 if (decoder_model_present_for_this_op
) {
231 if ((status
= parse_op_parameters_info(
232 rb
, buffer_delay_length_minus_1
)) != AOM_CODEC_OK
)
236 if (initial_display_delay_present_flag
) {
237 const uint8_t initial_display_delay_present_for_this_op
=
239 if (initial_display_delay_present_for_this_op
)
240 aom_rb_read_literal(rb
, 4); // initial_display_delay_minus_1
245 if (aom_get_num_layers_from_operating_point_idc(
246 operating_point_idc0
, &si
->number_spatial_layers
,
247 &si
->number_temporal_layers
) != AOM_CODEC_OK
) {
248 return AOM_CODEC_ERROR
;
254 static aom_codec_err_t
decoder_peek_si_internal(const uint8_t *data
,
256 aom_codec_stream_info_t
*si
,
257 int *is_intra_only
) {
258 int intra_only_flag
= 0;
259 int got_sequence_header
= 0;
260 int found_keyframe
= 0;
262 if (data
+ data_sz
<= data
|| data_sz
< 1) return AOM_CODEC_INVALID_PARAM
;
266 si
->is_kf
= 0; // is_kf indicates whether the current packet contains a RAP
268 ObuHeader obu_header
;
269 memset(&obu_header
, 0, sizeof(obu_header
));
270 size_t payload_size
= 0;
271 size_t bytes_read
= 0;
272 uint8_t reduced_still_picture_hdr
= 0;
273 aom_codec_err_t status
= aom_read_obu_header_and_size(
274 data
, data_sz
, si
->is_annexb
, &obu_header
, &payload_size
, &bytes_read
);
275 if (status
!= AOM_CODEC_OK
) return status
;
277 // If the first OBU is a temporal delimiter, skip over it and look at the next
278 // OBU in the bitstream
279 if (obu_header
.type
== OBU_TEMPORAL_DELIMITER
) {
280 // Skip any associated payload (there shouldn't be one, but just in case)
281 if (data_sz
< bytes_read
+ payload_size
) return AOM_CODEC_CORRUPT_FRAME
;
282 data
+= bytes_read
+ payload_size
;
283 data_sz
-= bytes_read
+ payload_size
;
285 status
= aom_read_obu_header_and_size(
286 data
, data_sz
, si
->is_annexb
, &obu_header
, &payload_size
, &bytes_read
);
287 if (status
!= AOM_CODEC_OK
) return status
;
291 data_sz
-= bytes_read
;
292 if (data_sz
< payload_size
) return AOM_CODEC_CORRUPT_FRAME
;
293 // Check that the selected OBU is a sequence header
294 if (obu_header
.type
== OBU_SEQUENCE_HEADER
) {
295 // Sanity check on sequence header size
296 if (data_sz
< 2) return AOM_CODEC_CORRUPT_FRAME
;
297 // Read a few values from the sequence header payload
298 struct aom_read_bit_buffer rb
= { data
, data
+ data_sz
, 0, NULL
, NULL
};
300 av1_read_profile(&rb
); // profile
301 const uint8_t still_picture
= aom_rb_read_bit(&rb
);
302 reduced_still_picture_hdr
= aom_rb_read_bit(&rb
);
304 if (!still_picture
&& reduced_still_picture_hdr
) {
305 return AOM_CODEC_UNSUP_BITSTREAM
;
308 if (parse_operating_points(&rb
, reduced_still_picture_hdr
, si
) !=
310 return AOM_CODEC_ERROR
;
313 int num_bits_width
= aom_rb_read_literal(&rb
, 4) + 1;
314 int num_bits_height
= aom_rb_read_literal(&rb
, 4) + 1;
315 int max_frame_width
= aom_rb_read_literal(&rb
, num_bits_width
) + 1;
316 int max_frame_height
= aom_rb_read_literal(&rb
, num_bits_height
) + 1;
317 si
->w
= max_frame_width
;
318 si
->h
= max_frame_height
;
319 got_sequence_header
= 1;
320 } else if (obu_header
.type
== OBU_FRAME_HEADER
||
321 obu_header
.type
== OBU_FRAME
) {
322 if (got_sequence_header
&& reduced_still_picture_hdr
) {
326 // make sure we have enough bits to get the frame type out
327 if (data_sz
< 1) return AOM_CODEC_CORRUPT_FRAME
;
328 struct aom_read_bit_buffer rb
= { data
, data
+ data_sz
, 0, NULL
, NULL
};
329 const int show_existing_frame
= aom_rb_read_bit(&rb
);
330 if (!show_existing_frame
) {
331 const FRAME_TYPE frame_type
= (FRAME_TYPE
)aom_rb_read_literal(&rb
, 2);
332 if (frame_type
== KEY_FRAME
) {
334 break; // Stop here as no further OBUs will change the outcome.
335 } else if (frame_type
== INTRA_ONLY_FRAME
) {
341 // skip past any unread OBU header data
342 data
+= payload_size
;
343 data_sz
-= payload_size
;
344 if (data_sz
== 0) break; // exit if we're out of OBUs
345 status
= aom_read_obu_header_and_size(
346 data
, data_sz
, si
->is_annexb
, &obu_header
, &payload_size
, &bytes_read
);
347 if (status
!= AOM_CODEC_OK
) return status
;
349 if (got_sequence_header
&& found_keyframe
) si
->is_kf
= 1;
350 if (is_intra_only
!= NULL
) *is_intra_only
= intra_only_flag
;
354 static aom_codec_err_t
decoder_peek_si(const uint8_t *data
, size_t data_sz
,
355 aom_codec_stream_info_t
*si
) {
356 return decoder_peek_si_internal(data
, data_sz
, si
, NULL
);
359 static aom_codec_err_t
decoder_get_si(aom_codec_alg_priv_t
*ctx
,
360 aom_codec_stream_info_t
*si
) {
361 memcpy(si
, &ctx
->si
, sizeof(*si
));
366 static void set_error_detail(aom_codec_alg_priv_t
*ctx
,
367 const char *const error
) {
368 ctx
->base
.err_detail
= error
;
371 static aom_codec_err_t
update_error_state(
372 aom_codec_alg_priv_t
*ctx
, const struct aom_internal_error_info
*error
) {
373 if (error
->error_code
)
374 set_error_detail(ctx
, error
->has_detail
? error
->detail
: NULL
);
376 return error
->error_code
;
379 static void init_buffer_callbacks(aom_codec_alg_priv_t
*ctx
) {
380 AVxWorker
*const worker
= ctx
->frame_worker
;
381 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
382 AV1Decoder
*const pbi
= frame_worker_data
->pbi
;
383 AV1_COMMON
*const cm
= &pbi
->common
;
384 BufferPool
*const pool
= cm
->buffer_pool
;
386 cm
->cur_frame
= NULL
;
387 cm
->features
.byte_alignment
= ctx
->byte_alignment
;
388 pbi
->skip_loop_filter
= ctx
->skip_loop_filter
;
389 pbi
->skip_film_grain
= ctx
->skip_film_grain
;
391 if (ctx
->get_ext_fb_cb
!= NULL
&& ctx
->release_ext_fb_cb
!= NULL
) {
392 pool
->get_fb_cb
= ctx
->get_ext_fb_cb
;
393 pool
->release_fb_cb
= ctx
->release_ext_fb_cb
;
394 pool
->cb_priv
= ctx
->ext_priv
;
396 pool
->get_fb_cb
= av1_get_frame_buffer
;
397 pool
->release_fb_cb
= av1_release_frame_buffer
;
399 if (av1_alloc_internal_frame_buffers(&pool
->int_frame_buffers
))
400 aom_internal_error(&pbi
->error
, AOM_CODEC_MEM_ERROR
,
401 "Failed to initialize internal frame buffers");
403 pool
->cb_priv
= &pool
->int_frame_buffers
;
407 static int frame_worker_hook(void *arg1
, void *arg2
) {
408 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)arg1
;
409 const uint8_t *data
= frame_worker_data
->data
;
412 int result
= av1_receive_compressed_data(frame_worker_data
->pbi
,
413 frame_worker_data
->data_size
, &data
);
414 frame_worker_data
->data_end
= data
;
417 // Check decode result in serial decode.
418 frame_worker_data
->pbi
->need_resync
= 1;
423 static aom_codec_err_t
init_decoder(aom_codec_alg_priv_t
*ctx
) {
424 const AVxWorkerInterface
*const winterface
= aom_get_worker_interface();
426 ctx
->last_show_frame
= NULL
;
427 ctx
->need_resync
= 1;
430 ctx
->buffer_pool
= (BufferPool
*)aom_calloc(1, sizeof(BufferPool
));
431 if (ctx
->buffer_pool
== NULL
) return AOM_CODEC_MEM_ERROR
;
433 #if CONFIG_MULTITHREAD
434 if (pthread_mutex_init(&ctx
->buffer_pool
->pool_mutex
, NULL
)) {
435 set_error_detail(ctx
, "Failed to allocate buffer pool mutex");
436 return AOM_CODEC_MEM_ERROR
;
440 ctx
->frame_worker
= (AVxWorker
*)aom_malloc(sizeof(*ctx
->frame_worker
));
441 if (ctx
->frame_worker
== NULL
) {
442 set_error_detail(ctx
, "Failed to allocate frame_worker");
443 return AOM_CODEC_MEM_ERROR
;
446 AVxWorker
*const worker
= ctx
->frame_worker
;
447 FrameWorkerData
*frame_worker_data
= NULL
;
448 winterface
->init(worker
);
449 worker
->thread_name
= "aom frameworker";
450 worker
->data1
= aom_memalign(32, sizeof(FrameWorkerData
));
451 if (worker
->data1
== NULL
) {
452 set_error_detail(ctx
, "Failed to allocate frame_worker_data");
453 return AOM_CODEC_MEM_ERROR
;
455 frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
456 frame_worker_data
->pbi
= av1_decoder_create(ctx
->buffer_pool
);
457 if (frame_worker_data
->pbi
== NULL
) {
458 set_error_detail(ctx
, "Failed to allocate frame_worker_data");
459 return AOM_CODEC_MEM_ERROR
;
461 frame_worker_data
->frame_context_ready
= 0;
462 frame_worker_data
->received_frame
= 0;
463 frame_worker_data
->pbi
->allow_lowbitdepth
= ctx
->cfg
.allow_lowbitdepth
;
465 // If decoding in serial mode, FrameWorker thread could create tile worker
466 // thread or loopfilter thread.
467 frame_worker_data
->pbi
->max_threads
= ctx
->cfg
.threads
;
468 frame_worker_data
->pbi
->inv_tile_order
= ctx
->invert_tile_order
;
469 frame_worker_data
->pbi
->common
.tiles
.large_scale
= ctx
->tile_mode
;
470 frame_worker_data
->pbi
->is_annexb
= ctx
->is_annexb
;
471 frame_worker_data
->pbi
->dec_tile_row
= ctx
->decode_tile_row
;
472 frame_worker_data
->pbi
->dec_tile_col
= ctx
->decode_tile_col
;
473 frame_worker_data
->pbi
->operating_point
= ctx
->operating_point
;
474 frame_worker_data
->pbi
->output_all_layers
= ctx
->output_all_layers
;
475 frame_worker_data
->pbi
->ext_tile_debug
= ctx
->ext_tile_debug
;
476 frame_worker_data
->pbi
->row_mt
= ctx
->row_mt
;
477 frame_worker_data
->pbi
->is_fwd_kf_present
= 0;
478 frame_worker_data
->pbi
->is_arf_frame_present
= 0;
479 worker
->hook
= frame_worker_hook
;
481 init_buffer_callbacks(ctx
);
486 static INLINE
void check_resync(aom_codec_alg_priv_t
*const ctx
,
487 const AV1Decoder
*const pbi
) {
488 // Clear resync flag if worker got a key frame or intra only frame.
489 if (ctx
->need_resync
== 1 && pbi
->need_resync
== 0 &&
490 frame_is_intra_only(&pbi
->common
))
491 ctx
->need_resync
= 0;
494 static aom_codec_err_t
decode_one(aom_codec_alg_priv_t
*ctx
,
495 const uint8_t **data
, size_t data_sz
,
497 const AVxWorkerInterface
*const winterface
= aom_get_worker_interface();
499 // Determine the stream parameters. Note that we rely on peek_si to
500 // validate that we have a buffer that does not wrap around the top
503 int is_intra_only
= 0;
504 ctx
->si
.is_annexb
= ctx
->is_annexb
;
505 const aom_codec_err_t res
=
506 decoder_peek_si_internal(*data
, data_sz
, &ctx
->si
, &is_intra_only
);
507 if (res
!= AOM_CODEC_OK
) return res
;
509 if (!ctx
->si
.is_kf
&& !is_intra_only
) return AOM_CODEC_ERROR
;
512 AVxWorker
*const worker
= ctx
->frame_worker
;
513 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
514 frame_worker_data
->data
= *data
;
515 frame_worker_data
->data_size
= data_sz
;
516 frame_worker_data
->user_priv
= user_priv
;
517 frame_worker_data
->received_frame
= 1;
519 frame_worker_data
->pbi
->common
.tiles
.large_scale
= ctx
->tile_mode
;
520 frame_worker_data
->pbi
->dec_tile_row
= ctx
->decode_tile_row
;
521 frame_worker_data
->pbi
->dec_tile_col
= ctx
->decode_tile_col
;
522 frame_worker_data
->pbi
->ext_tile_debug
= ctx
->ext_tile_debug
;
523 frame_worker_data
->pbi
->row_mt
= ctx
->row_mt
;
524 frame_worker_data
->pbi
->ext_refs
= ctx
->ext_refs
;
526 frame_worker_data
->pbi
->is_annexb
= ctx
->is_annexb
;
528 worker
->had_error
= 0;
529 winterface
->execute(worker
);
531 // Update data pointer after decode.
532 *data
= frame_worker_data
->data_end
;
534 if (worker
->had_error
)
535 return update_error_state(ctx
, &frame_worker_data
->pbi
->error
);
537 check_resync(ctx
, frame_worker_data
->pbi
);
542 static void release_pending_output_frames(aom_codec_alg_priv_t
*ctx
) {
543 // Release any pending output frames from the previous decoder_decode or
544 // decoder_inspect call. We need to do this even if the decoder is being
545 // flushed or the input arguments are invalid.
546 if (ctx
->frame_worker
) {
547 BufferPool
*const pool
= ctx
->buffer_pool
;
548 lock_buffer_pool(pool
);
549 AVxWorker
*const worker
= ctx
->frame_worker
;
550 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
551 struct AV1Decoder
*pbi
= frame_worker_data
->pbi
;
552 for (size_t j
= 0; j
< pbi
->num_output_frames
; j
++) {
553 decrease_ref_count(pbi
->output_frames
[j
], pool
);
555 pbi
->num_output_frames
= 0;
556 unlock_buffer_pool(pool
);
557 for (size_t j
= 0; j
< ctx
->num_grain_image_frame_buffers
; j
++) {
558 pool
->release_fb_cb(pool
->cb_priv
, &ctx
->grain_image_frame_buffers
[j
]);
559 ctx
->grain_image_frame_buffers
[j
].data
= NULL
;
560 ctx
->grain_image_frame_buffers
[j
].size
= 0;
561 ctx
->grain_image_frame_buffers
[j
].priv
= NULL
;
563 ctx
->num_grain_image_frame_buffers
= 0;
567 // This function enables the inspector to inspect non visible frames.
568 static aom_codec_err_t
decoder_inspect(aom_codec_alg_priv_t
*ctx
,
569 const uint8_t *data
, size_t data_sz
,
571 aom_codec_err_t res
= AOM_CODEC_OK
;
573 release_pending_output_frames(ctx
);
576 /* NULL data ptr allowed if data_sz is 0 too */
577 if (data
== NULL
&& data_sz
== 0) {
581 if (data
== NULL
|| data_sz
== 0) return AOM_CODEC_INVALID_PARAM
;
583 // Reset flushed when receiving a valid frame.
586 const uint8_t *data_start
= data
;
587 const uint8_t *data_end
= data
+ data_sz
;
590 if (ctx
->is_annexb
) {
591 // read the size of this temporal unit
592 size_t length_of_size
;
593 uint64_t temporal_unit_size
;
594 if (aom_uleb_decode(data_start
, data_sz
, &temporal_unit_size
,
595 &length_of_size
) != 0) {
596 return AOM_CODEC_CORRUPT_FRAME
;
598 data_start
+= length_of_size
;
599 if (temporal_unit_size
> (size_t)(data_end
- data_start
))
600 return AOM_CODEC_CORRUPT_FRAME
;
601 data_end
= data_start
+ temporal_unit_size
;
603 // read the size of this frame unit
604 if (aom_uleb_decode(data_start
, (size_t)(data_end
- data_start
),
605 &frame_size
, &length_of_size
) != 0) {
606 return AOM_CODEC_CORRUPT_FRAME
;
608 data_start
+= length_of_size
;
609 if (frame_size
> (size_t)(data_end
- data_start
))
610 return AOM_CODEC_CORRUPT_FRAME
;
612 frame_size
= (uint64_t)(data_end
- data_start
);
615 if (ctx
->frame_worker
== NULL
) {
616 res
= init_decoder(ctx
);
617 if (res
!= AOM_CODEC_OK
) return res
;
619 FrameWorkerData
*const frame_worker_data
=
620 (FrameWorkerData
*)ctx
->frame_worker
->data1
;
621 AV1Decoder
*const pbi
= frame_worker_data
->pbi
;
622 AV1_COMMON
*const cm
= &pbi
->common
;
623 #if CONFIG_INSPECTION
624 frame_worker_data
->pbi
->inspect_cb
= ctx
->inspect_cb
;
625 frame_worker_data
->pbi
->inspect_ctx
= ctx
->inspect_ctx
;
627 res
= av1_receive_compressed_data(frame_worker_data
->pbi
, (size_t)frame_size
,
629 check_resync(ctx
, frame_worker_data
->pbi
);
631 if (ctx
->frame_worker
->had_error
)
632 return update_error_state(ctx
, &frame_worker_data
->pbi
->error
);
634 // Allow extra zero bytes after the frame end
635 while (data_start
< data_end
) {
636 const uint8_t marker
= data_start
[0];
641 Av1DecodeReturn
*data2
= (Av1DecodeReturn
*)user_priv
;
644 for (int i
= 0; i
< REF_FRAMES
; ++i
)
645 if (cm
->ref_frame_map
[i
] == cm
->cur_frame
) data2
->idx
= i
;
647 data2
->buf
= data_start
;
648 data2
->show_existing
= cm
->show_existing_frame
;
652 static aom_codec_err_t
decoder_decode(aom_codec_alg_priv_t
*ctx
,
653 const uint8_t *data
, size_t data_sz
,
655 aom_codec_err_t res
= AOM_CODEC_OK
;
657 #if CONFIG_INSPECTION
658 if (user_priv
!= 0) {
659 return decoder_inspect(ctx
, data
, data_sz
, user_priv
);
663 release_pending_output_frames(ctx
);
666 /* NULL data ptr allowed if data_sz is 0 too */
667 if (data
== NULL
&& data_sz
== 0) {
671 if (data
== NULL
|| data_sz
== 0) return AOM_CODEC_INVALID_PARAM
;
673 // Reset flushed when receiving a valid frame.
676 // Initialize the decoder worker on the first frame.
677 if (ctx
->frame_worker
== NULL
) {
678 res
= init_decoder(ctx
);
679 if (res
!= AOM_CODEC_OK
) return res
;
682 const uint8_t *data_start
= data
;
683 const uint8_t *data_end
= data
+ data_sz
;
685 if (ctx
->is_annexb
) {
686 // read the size of this temporal unit
687 size_t length_of_size
;
688 uint64_t temporal_unit_size
;
689 if (aom_uleb_decode(data_start
, data_sz
, &temporal_unit_size
,
690 &length_of_size
) != 0) {
691 return AOM_CODEC_CORRUPT_FRAME
;
693 data_start
+= length_of_size
;
694 if (temporal_unit_size
> (size_t)(data_end
- data_start
))
695 return AOM_CODEC_CORRUPT_FRAME
;
696 data_end
= data_start
+ temporal_unit_size
;
699 // Decode in serial mode.
700 while (data_start
< data_end
) {
702 if (ctx
->is_annexb
) {
703 // read the size of this frame unit
704 size_t length_of_size
;
705 if (aom_uleb_decode(data_start
, (size_t)(data_end
- data_start
),
706 &frame_size
, &length_of_size
) != 0) {
707 return AOM_CODEC_CORRUPT_FRAME
;
709 data_start
+= length_of_size
;
710 if (frame_size
> (size_t)(data_end
- data_start
))
711 return AOM_CODEC_CORRUPT_FRAME
;
713 frame_size
= (uint64_t)(data_end
- data_start
);
716 res
= decode_one(ctx
, &data_start
, (size_t)frame_size
, user_priv
);
717 if (res
!= AOM_CODEC_OK
) return res
;
719 // Allow extra zero bytes after the frame end
720 while (data_start
< data_end
) {
721 const uint8_t marker
= data_start
[0];
732 aom_codec_frame_buffer_t
*fb
;
735 static void *AllocWithGetFrameBufferCb(void *priv
, size_t size
) {
736 AllocCbParam
*param
= (AllocCbParam
*)priv
;
737 if (param
->pool
->get_fb_cb(param
->pool
->cb_priv
, size
, param
->fb
) < 0)
739 if (param
->fb
->data
== NULL
|| param
->fb
->size
< size
) return NULL
;
740 return param
->fb
->data
;
743 // If grain_params->apply_grain is false, returns img. Otherwise, adds film
744 // grain to img, saves the result in grain_img, and returns grain_img.
745 static aom_image_t
*add_grain_if_needed(aom_codec_alg_priv_t
*ctx
,
747 aom_image_t
*grain_img
,
748 aom_film_grain_t
*grain_params
) {
749 if (!grain_params
->apply_grain
) return img
;
751 const int w_even
= ALIGN_POWER_OF_TWO(img
->d_w
, 1);
752 const int h_even
= ALIGN_POWER_OF_TWO(img
->d_h
, 1);
754 BufferPool
*const pool
= ctx
->buffer_pool
;
755 aom_codec_frame_buffer_t
*fb
=
756 &ctx
->grain_image_frame_buffers
[ctx
->num_grain_image_frame_buffers
];
760 if (!aom_img_alloc_with_cb(grain_img
, img
->fmt
, w_even
, h_even
, 16,
761 AllocWithGetFrameBufferCb
, ¶m
)) {
765 grain_img
->user_priv
= img
->user_priv
;
766 grain_img
->fb_priv
= fb
->priv
;
767 if (av1_add_film_grain(grain_params
, img
, grain_img
)) {
768 pool
->release_fb_cb(pool
->cb_priv
, fb
);
772 ctx
->num_grain_image_frame_buffers
++;
776 // Copies and clears the metadata from AV1Decoder.
777 static void move_decoder_metadata_to_img(AV1Decoder
*pbi
, aom_image_t
*img
) {
778 if (pbi
->metadata
&& img
) {
779 assert(!img
->metadata
);
780 img
->metadata
= pbi
->metadata
;
781 pbi
->metadata
= NULL
;
785 static aom_image_t
*decoder_get_frame(aom_codec_alg_priv_t
*ctx
,
786 aom_codec_iter_t
*iter
) {
787 aom_image_t
*img
= NULL
;
793 // To avoid having to allocate any extra storage, treat 'iter' as
794 // simply a pointer to an integer index
795 uintptr_t *index
= (uintptr_t *)iter
;
797 if (ctx
->frame_worker
!= NULL
) {
798 const AVxWorkerInterface
*const winterface
= aom_get_worker_interface();
799 AVxWorker
*const worker
= ctx
->frame_worker
;
800 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
801 AV1Decoder
*const pbi
= frame_worker_data
->pbi
;
802 AV1_COMMON
*const cm
= &pbi
->common
;
803 CommonTileParams
*const tiles
= &cm
->tiles
;
804 // Wait for the frame from worker thread.
805 if (winterface
->sync(worker
)) {
806 // Check if worker has received any frames.
807 if (frame_worker_data
->received_frame
== 1) {
808 frame_worker_data
->received_frame
= 0;
809 check_resync(ctx
, frame_worker_data
->pbi
);
811 YV12_BUFFER_CONFIG
*sd
;
812 aom_film_grain_t
*grain_params
;
813 if (av1_get_raw_frame(frame_worker_data
->pbi
, *index
, &sd
,
814 &grain_params
) == 0) {
815 RefCntBuffer
*const output_frame_buf
= pbi
->output_frames
[*index
];
816 ctx
->last_show_frame
= output_frame_buf
;
817 if (ctx
->need_resync
) return NULL
;
818 aom_img_remove_metadata(&ctx
->img
);
819 yuvconfig2image(&ctx
->img
, sd
, frame_worker_data
->user_priv
);
820 move_decoder_metadata_to_img(pbi
, &ctx
->img
);
822 if (!pbi
->ext_tile_debug
&& tiles
->large_scale
) {
823 *index
+= 1; // Advance the iterator to point to the next image
824 aom_img_remove_metadata(&ctx
->img
);
825 yuvconfig2image(&ctx
->img
, &pbi
->tile_list_outbuf
, NULL
);
826 move_decoder_metadata_to_img(pbi
, &ctx
->img
);
831 const int num_planes
= av1_num_planes(cm
);
832 if (pbi
->ext_tile_debug
&& tiles
->single_tile_decoding
&&
833 pbi
->dec_tile_row
>= 0) {
834 int tile_width
, tile_height
;
835 av1_get_uniform_tile_size(cm
, &tile_width
, &tile_height
);
836 const int tile_row
= AOMMIN(pbi
->dec_tile_row
, tiles
->rows
- 1);
837 const int mi_row
= tile_row
* tile_height
;
838 const int ssy
= ctx
->img
.y_chroma_shift
;
840 ctx
->img
.planes
[0] += mi_row
* MI_SIZE
* ctx
->img
.stride
[0];
841 if (num_planes
> 1) {
842 for (plane
= 1; plane
< MAX_MB_PLANE
; ++plane
) {
843 ctx
->img
.planes
[plane
] +=
844 mi_row
* (MI_SIZE
>> ssy
) * ctx
->img
.stride
[plane
];
848 AOMMIN(tile_height
, cm
->mi_params
.mi_rows
- mi_row
) * MI_SIZE
;
851 if (pbi
->ext_tile_debug
&& tiles
->single_tile_decoding
&&
852 pbi
->dec_tile_col
>= 0) {
853 int tile_width
, tile_height
;
854 av1_get_uniform_tile_size(cm
, &tile_width
, &tile_height
);
855 const int tile_col
= AOMMIN(pbi
->dec_tile_col
, tiles
->cols
- 1);
856 const int mi_col
= tile_col
* tile_width
;
857 const int ssx
= ctx
->img
.x_chroma_shift
;
858 const int is_hbd
= (ctx
->img
.fmt
& AOM_IMG_FMT_HIGHBITDEPTH
) ? 1 : 0;
860 ctx
->img
.planes
[0] += mi_col
* MI_SIZE
* (1 + is_hbd
);
861 if (num_planes
> 1) {
862 for (plane
= 1; plane
< MAX_MB_PLANE
; ++plane
) {
863 ctx
->img
.planes
[plane
] +=
864 mi_col
* (MI_SIZE
>> ssx
) * (1 + is_hbd
);
868 AOMMIN(tile_width
, cm
->mi_params
.mi_cols
- mi_col
) * MI_SIZE
;
871 ctx
->img
.fb_priv
= output_frame_buf
->raw_frame_buffer
.priv
;
873 img
->temporal_id
= output_frame_buf
->temporal_id
;
874 img
->spatial_id
= output_frame_buf
->spatial_id
;
875 if (pbi
->skip_film_grain
) grain_params
->apply_grain
= 0;
877 add_grain_if_needed(ctx
, img
, &ctx
->image_with_grain
, grain_params
);
879 aom_internal_error(&pbi
->error
, AOM_CODEC_CORRUPT_FRAME
,
880 "Grain systhesis failed\n");
882 *index
+= 1; // Advance the iterator to point to the next image
886 // Decoding failed. Release the worker thread.
887 frame_worker_data
->received_frame
= 0;
888 ctx
->need_resync
= 1;
889 if (ctx
->flushed
!= 1) return NULL
;
895 static aom_codec_err_t
decoder_set_fb_fn(
896 aom_codec_alg_priv_t
*ctx
, aom_get_frame_buffer_cb_fn_t cb_get
,
897 aom_release_frame_buffer_cb_fn_t cb_release
, void *cb_priv
) {
898 if (cb_get
== NULL
|| cb_release
== NULL
) {
899 return AOM_CODEC_INVALID_PARAM
;
900 } else if (ctx
->frame_worker
== NULL
) {
901 // If the decoder has already been initialized, do not accept changes to
902 // the frame buffer functions.
903 ctx
->get_ext_fb_cb
= cb_get
;
904 ctx
->release_ext_fb_cb
= cb_release
;
905 ctx
->ext_priv
= cb_priv
;
909 return AOM_CODEC_ERROR
;
912 static aom_codec_err_t
ctrl_set_reference(aom_codec_alg_priv_t
*ctx
,
914 av1_ref_frame_t
*const data
= va_arg(args
, av1_ref_frame_t
*);
917 av1_ref_frame_t
*const frame
= data
;
918 YV12_BUFFER_CONFIG sd
;
919 AVxWorker
*const worker
= ctx
->frame_worker
;
920 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
921 image2yuvconfig(&frame
->img
, &sd
);
922 return av1_set_reference_dec(&frame_worker_data
->pbi
->common
, frame
->idx
,
923 frame
->use_external_ref
, &sd
);
925 return AOM_CODEC_INVALID_PARAM
;
929 static aom_codec_err_t
ctrl_copy_reference(aom_codec_alg_priv_t
*ctx
,
931 const av1_ref_frame_t
*const frame
= va_arg(args
, av1_ref_frame_t
*);
933 YV12_BUFFER_CONFIG sd
;
934 AVxWorker
*const worker
= ctx
->frame_worker
;
935 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
936 image2yuvconfig(&frame
->img
, &sd
);
937 return av1_copy_reference_dec(frame_worker_data
->pbi
, frame
->idx
, &sd
);
939 return AOM_CODEC_INVALID_PARAM
;
943 static aom_codec_err_t
ctrl_get_reference(aom_codec_alg_priv_t
*ctx
,
945 av1_ref_frame_t
*data
= va_arg(args
, av1_ref_frame_t
*);
947 YV12_BUFFER_CONFIG
*fb
;
948 AVxWorker
*const worker
= ctx
->frame_worker
;
949 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
950 fb
= get_ref_frame(&frame_worker_data
->pbi
->common
, data
->idx
);
951 if (fb
== NULL
) return AOM_CODEC_ERROR
;
952 yuvconfig2image(&data
->img
, fb
, NULL
);
955 return AOM_CODEC_INVALID_PARAM
;
959 static aom_codec_err_t
ctrl_get_new_frame_image(aom_codec_alg_priv_t
*ctx
,
961 aom_image_t
*new_img
= va_arg(args
, aom_image_t
*);
963 YV12_BUFFER_CONFIG new_frame
;
964 AVxWorker
*const worker
= ctx
->frame_worker
;
965 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
967 if (av1_get_frame_to_show(frame_worker_data
->pbi
, &new_frame
) == 0) {
968 yuvconfig2image(new_img
, &new_frame
, NULL
);
971 return AOM_CODEC_ERROR
;
974 return AOM_CODEC_INVALID_PARAM
;
978 static aom_codec_err_t
ctrl_copy_new_frame_image(aom_codec_alg_priv_t
*ctx
,
980 aom_image_t
*img
= va_arg(args
, aom_image_t
*);
982 YV12_BUFFER_CONFIG new_frame
;
983 AVxWorker
*const worker
= ctx
->frame_worker
;
984 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
986 if (av1_get_frame_to_show(frame_worker_data
->pbi
, &new_frame
) == 0) {
987 YV12_BUFFER_CONFIG sd
;
988 image2yuvconfig(img
, &sd
);
989 return av1_copy_new_frame_dec(&frame_worker_data
->pbi
->common
, &new_frame
,
992 return AOM_CODEC_ERROR
;
995 return AOM_CODEC_INVALID_PARAM
;
999 static aom_codec_err_t
ctrl_get_last_ref_updates(aom_codec_alg_priv_t
*ctx
,
1001 int *const update_info
= va_arg(args
, int *);
1004 if (ctx
->frame_worker
) {
1005 AVxWorker
*const worker
= ctx
->frame_worker
;
1006 FrameWorkerData
*const frame_worker_data
=
1007 (FrameWorkerData
*)worker
->data1
;
1009 frame_worker_data
->pbi
->common
.current_frame
.refresh_frame_flags
;
1010 return AOM_CODEC_OK
;
1012 return AOM_CODEC_ERROR
;
1016 return AOM_CODEC_INVALID_PARAM
;
1019 static aom_codec_err_t
ctrl_get_last_quantizer(aom_codec_alg_priv_t
*ctx
,
1021 int *const arg
= va_arg(args
, int *);
1022 if (arg
== NULL
) return AOM_CODEC_INVALID_PARAM
;
1023 if (ctx
->frame_worker
== NULL
) return AOM_CODEC_ERROR
;
1024 *arg
= ((FrameWorkerData
*)ctx
->frame_worker
->data1
)
1025 ->pbi
->common
.quant_params
.base_qindex
;
1026 return AOM_CODEC_OK
;
1029 static aom_codec_err_t
ctrl_get_fwd_kf_value(aom_codec_alg_priv_t
*ctx
,
1031 int *const arg
= va_arg(args
, int *);
1032 if (arg
== NULL
) return AOM_CODEC_INVALID_PARAM
;
1033 if (ctx
->frame_worker
== NULL
) return AOM_CODEC_ERROR
;
1034 *arg
= ((FrameWorkerData
*)ctx
->frame_worker
->data1
)->pbi
->is_fwd_kf_present
;
1035 return AOM_CODEC_OK
;
1038 static aom_codec_err_t
ctrl_get_altref_present(aom_codec_alg_priv_t
*ctx
,
1040 int *const arg
= va_arg(args
, int *);
1041 if (arg
== NULL
) return AOM_CODEC_INVALID_PARAM
;
1042 if (ctx
->frame_worker
== NULL
) return AOM_CODEC_ERROR
;
1044 ((FrameWorkerData
*)ctx
->frame_worker
->data1
)->pbi
->is_arf_frame_present
;
1045 return AOM_CODEC_OK
;
1048 static aom_codec_err_t
ctrl_get_frame_flags(aom_codec_alg_priv_t
*ctx
,
1050 int *const arg
= va_arg(args
, int *);
1051 if (arg
== NULL
) return AOM_CODEC_INVALID_PARAM
;
1052 if (ctx
->frame_worker
== NULL
) return AOM_CODEC_ERROR
;
1053 AV1Decoder
*pbi
= ((FrameWorkerData
*)ctx
->frame_worker
->data1
)->pbi
;
1055 switch (pbi
->common
.current_frame
.frame_type
) {
1057 *arg
|= AOM_FRAME_IS_KEY
;
1058 *arg
|= AOM_FRAME_IS_INTRAONLY
;
1059 if (!pbi
->common
.show_frame
) {
1060 *arg
|= AOM_FRAME_IS_DELAYED_RANDOM_ACCESS_POINT
;
1063 case INTRA_ONLY_FRAME
: *arg
|= AOM_FRAME_IS_INTRAONLY
; break;
1064 case S_FRAME
: *arg
|= AOM_FRAME_IS_SWITCH
; break;
1066 if (pbi
->common
.features
.error_resilient_mode
) {
1067 *arg
|= AOM_FRAME_IS_ERROR_RESILIENT
;
1069 return AOM_CODEC_OK
;
1072 static aom_codec_err_t
ctrl_get_tile_info(aom_codec_alg_priv_t
*ctx
,
1074 aom_tile_info
*const tile_info
= va_arg(args
, aom_tile_info
*);
1077 if (ctx
->frame_worker
) {
1078 AVxWorker
*const worker
= ctx
->frame_worker
;
1079 FrameWorkerData
*const frame_worker_data
=
1080 (FrameWorkerData
*)worker
->data1
;
1081 const AV1Decoder
*pbi
= frame_worker_data
->pbi
;
1082 const CommonTileParams
*tiles
= &pbi
->common
.tiles
;
1084 int tile_rows
= tiles
->rows
;
1085 int tile_cols
= tiles
->cols
;
1087 if (tiles
->uniform_spacing
) {
1088 tile_info
->tile_rows
= 1 << tiles
->log2_rows
;
1089 tile_info
->tile_columns
= 1 << tiles
->log2_cols
;
1091 tile_info
->tile_rows
= tile_rows
;
1092 tile_info
->tile_columns
= tile_cols
;
1095 for (int tile_col
= 1; tile_col
<= tile_cols
; tile_col
++) {
1096 tile_info
->tile_widths
[tile_col
- 1] =
1097 tiles
->col_start_sb
[tile_col
] - tiles
->col_start_sb
[tile_col
- 1];
1100 for (int tile_row
= 1; tile_row
<= tile_rows
; tile_row
++) {
1101 tile_info
->tile_heights
[tile_row
- 1] =
1102 tiles
->row_start_sb
[tile_row
] - tiles
->row_start_sb
[tile_row
- 1];
1104 tile_info
->num_tile_groups
= pbi
->num_tile_groups
;
1105 return AOM_CODEC_OK
;
1107 return AOM_CODEC_ERROR
;
1111 return AOM_CODEC_INVALID_PARAM
;
1114 static aom_codec_err_t
ctrl_get_screen_content_tools_info(
1115 aom_codec_alg_priv_t
*ctx
, va_list args
) {
1116 aom_screen_content_tools_info
*const sc_info
=
1117 va_arg(args
, aom_screen_content_tools_info
*);
1119 if (ctx
->frame_worker
) {
1120 AVxWorker
*const worker
= ctx
->frame_worker
;
1121 FrameWorkerData
*const frame_worker_data
=
1122 (FrameWorkerData
*)worker
->data1
;
1123 const AV1Decoder
*pbi
= frame_worker_data
->pbi
;
1124 sc_info
->allow_screen_content_tools
=
1125 pbi
->common
.features
.allow_screen_content_tools
;
1126 sc_info
->allow_intrabc
= pbi
->common
.features
.allow_intrabc
;
1127 sc_info
->force_integer_mv
=
1128 (int)pbi
->common
.features
.cur_frame_force_integer_mv
;
1129 return AOM_CODEC_OK
;
1131 return AOM_CODEC_ERROR
;
1134 return AOM_CODEC_INVALID_PARAM
;
1137 static aom_codec_err_t
ctrl_get_still_picture(aom_codec_alg_priv_t
*ctx
,
1139 aom_still_picture_info
*const still_picture_info
=
1140 va_arg(args
, aom_still_picture_info
*);
1141 if (still_picture_info
) {
1142 if (ctx
->frame_worker
) {
1143 AVxWorker
*const worker
= ctx
->frame_worker
;
1144 FrameWorkerData
*const frame_worker_data
=
1145 (FrameWorkerData
*)worker
->data1
;
1146 const AV1Decoder
*pbi
= frame_worker_data
->pbi
;
1147 still_picture_info
->is_still_picture
= (int)pbi
->seq_params
.still_picture
;
1148 still_picture_info
->is_reduced_still_picture_hdr
=
1149 (int)(pbi
->seq_params
.reduced_still_picture_hdr
);
1150 return AOM_CODEC_OK
;
1152 return AOM_CODEC_ERROR
;
1155 return AOM_CODEC_INVALID_PARAM
;
1158 static aom_codec_err_t
ctrl_get_sb_size(aom_codec_alg_priv_t
*ctx
,
1160 aom_superblock_size_t
*const sb_size
= va_arg(args
, aom_superblock_size_t
*);
1162 if (ctx
->frame_worker
) {
1163 AVxWorker
*const worker
= ctx
->frame_worker
;
1164 FrameWorkerData
*const frame_worker_data
=
1165 (FrameWorkerData
*)worker
->data1
;
1166 const AV1Decoder
*pbi
= frame_worker_data
->pbi
;
1167 if (pbi
->seq_params
.sb_size
== BLOCK_128X128
) {
1168 *sb_size
= AOM_SUPERBLOCK_SIZE_128X128
;
1170 *sb_size
= AOM_SUPERBLOCK_SIZE_64X64
;
1172 return AOM_CODEC_OK
;
1174 return AOM_CODEC_ERROR
;
1177 return AOM_CODEC_INVALID_PARAM
;
1180 static aom_codec_err_t
ctrl_get_show_existing_frame_flag(
1181 aom_codec_alg_priv_t
*ctx
, va_list args
) {
1182 int *const arg
= va_arg(args
, int *);
1183 if (arg
== NULL
) return AOM_CODEC_INVALID_PARAM
;
1184 if (ctx
->frame_worker
== NULL
) return AOM_CODEC_ERROR
;
1185 *arg
= ((FrameWorkerData
*)ctx
->frame_worker
->data1
)
1186 ->pbi
->common
.show_existing_frame
;
1187 return AOM_CODEC_OK
;
1190 static aom_codec_err_t
ctrl_get_s_frame_info(aom_codec_alg_priv_t
*ctx
,
1192 aom_s_frame_info
*const s_frame_info
= va_arg(args
, aom_s_frame_info
*);
1194 if (ctx
->frame_worker
) {
1195 AVxWorker
*const worker
= ctx
->frame_worker
;
1196 FrameWorkerData
*const frame_worker_data
=
1197 (FrameWorkerData
*)worker
->data1
;
1198 const AV1Decoder
*pbi
= frame_worker_data
->pbi
;
1199 s_frame_info
->is_s_frame
= pbi
->sframe_info
.is_s_frame
;
1200 s_frame_info
->is_s_frame_at_altref
=
1201 pbi
->sframe_info
.is_s_frame_at_altref
;
1202 return AOM_CODEC_OK
;
1204 return AOM_CODEC_ERROR
;
1207 return AOM_CODEC_INVALID_PARAM
;
1210 static aom_codec_err_t
ctrl_get_frame_corrupted(aom_codec_alg_priv_t
*ctx
,
1212 int *corrupted
= va_arg(args
, int *);
1215 if (ctx
->frame_worker
) {
1216 AVxWorker
*const worker
= ctx
->frame_worker
;
1217 FrameWorkerData
*const frame_worker_data
=
1218 (FrameWorkerData
*)worker
->data1
;
1219 AV1Decoder
*const pbi
= frame_worker_data
->pbi
;
1220 if (pbi
->seen_frame_header
&& pbi
->num_output_frames
== 0)
1221 return AOM_CODEC_ERROR
;
1222 if (ctx
->last_show_frame
!= NULL
)
1223 *corrupted
= ctx
->last_show_frame
->buf
.corrupted
;
1224 return AOM_CODEC_OK
;
1226 return AOM_CODEC_ERROR
;
1230 return AOM_CODEC_INVALID_PARAM
;
1233 static aom_codec_err_t
ctrl_get_frame_size(aom_codec_alg_priv_t
*ctx
,
1235 int *const frame_size
= va_arg(args
, int *);
1238 if (ctx
->frame_worker
) {
1239 AVxWorker
*const worker
= ctx
->frame_worker
;
1240 FrameWorkerData
*const frame_worker_data
=
1241 (FrameWorkerData
*)worker
->data1
;
1242 const AV1_COMMON
*const cm
= &frame_worker_data
->pbi
->common
;
1243 frame_size
[0] = cm
->width
;
1244 frame_size
[1] = cm
->height
;
1245 return AOM_CODEC_OK
;
1247 return AOM_CODEC_ERROR
;
1251 return AOM_CODEC_INVALID_PARAM
;
1254 static aom_codec_err_t
ctrl_get_frame_header_info(aom_codec_alg_priv_t
*ctx
,
1256 aom_tile_data
*const frame_header_info
= va_arg(args
, aom_tile_data
*);
1258 if (frame_header_info
) {
1259 if (ctx
->frame_worker
) {
1260 AVxWorker
*const worker
= ctx
->frame_worker
;
1261 FrameWorkerData
*const frame_worker_data
=
1262 (FrameWorkerData
*)worker
->data1
;
1263 const AV1Decoder
*pbi
= frame_worker_data
->pbi
;
1264 frame_header_info
->coded_tile_data_size
= pbi
->obu_size_hdr
.size
;
1265 frame_header_info
->coded_tile_data
= pbi
->obu_size_hdr
.data
;
1266 frame_header_info
->extra_size
= pbi
->frame_header_size
;
1267 return AOM_CODEC_OK
;
1269 return AOM_CODEC_ERROR
;
1273 return AOM_CODEC_INVALID_PARAM
;
1276 static aom_codec_err_t
ctrl_get_tile_data(aom_codec_alg_priv_t
*ctx
,
1278 aom_tile_data
*const tile_data
= va_arg(args
, aom_tile_data
*);
1281 if (ctx
->frame_worker
) {
1282 AVxWorker
*const worker
= ctx
->frame_worker
;
1283 FrameWorkerData
*const frame_worker_data
=
1284 (FrameWorkerData
*)worker
->data1
;
1285 const AV1Decoder
*pbi
= frame_worker_data
->pbi
;
1286 tile_data
->coded_tile_data_size
=
1287 pbi
->tile_buffers
[pbi
->dec_tile_row
][pbi
->dec_tile_col
].size
;
1288 tile_data
->coded_tile_data
=
1289 pbi
->tile_buffers
[pbi
->dec_tile_row
][pbi
->dec_tile_col
].data
;
1290 return AOM_CODEC_OK
;
1292 return AOM_CODEC_ERROR
;
1296 return AOM_CODEC_INVALID_PARAM
;
1299 static aom_codec_err_t
ctrl_set_ext_ref_ptr(aom_codec_alg_priv_t
*ctx
,
1301 av1_ext_ref_frame_t
*const data
= va_arg(args
, av1_ext_ref_frame_t
*);
1304 av1_ext_ref_frame_t
*const ext_frames
= data
;
1305 ctx
->ext_refs
.num
= ext_frames
->num
;
1306 for (int i
= 0; i
< ctx
->ext_refs
.num
; i
++) {
1307 image2yuvconfig(ext_frames
->img
++, &ctx
->ext_refs
.refs
[i
]);
1309 return AOM_CODEC_OK
;
1311 return AOM_CODEC_INVALID_PARAM
;
1315 static aom_codec_err_t
ctrl_get_render_size(aom_codec_alg_priv_t
*ctx
,
1317 int *const render_size
= va_arg(args
, int *);
1320 if (ctx
->frame_worker
) {
1321 AVxWorker
*const worker
= ctx
->frame_worker
;
1322 FrameWorkerData
*const frame_worker_data
=
1323 (FrameWorkerData
*)worker
->data1
;
1324 const AV1_COMMON
*const cm
= &frame_worker_data
->pbi
->common
;
1325 render_size
[0] = cm
->render_width
;
1326 render_size
[1] = cm
->render_height
;
1327 return AOM_CODEC_OK
;
1329 return AOM_CODEC_ERROR
;
1333 return AOM_CODEC_INVALID_PARAM
;
1336 static aom_codec_err_t
ctrl_get_bit_depth(aom_codec_alg_priv_t
*ctx
,
1338 unsigned int *const bit_depth
= va_arg(args
, unsigned int *);
1339 AVxWorker
*const worker
= ctx
->frame_worker
;
1343 FrameWorkerData
*const frame_worker_data
=
1344 (FrameWorkerData
*)worker
->data1
;
1345 const AV1_COMMON
*const cm
= &frame_worker_data
->pbi
->common
;
1346 *bit_depth
= cm
->seq_params
->bit_depth
;
1347 return AOM_CODEC_OK
;
1349 return AOM_CODEC_ERROR
;
1353 return AOM_CODEC_INVALID_PARAM
;
1356 static aom_img_fmt_t
get_img_format(int subsampling_x
, int subsampling_y
,
1357 int use_highbitdepth
) {
1358 aom_img_fmt_t fmt
= 0;
1360 if (subsampling_x
== 0 && subsampling_y
== 0)
1361 fmt
= AOM_IMG_FMT_I444
;
1362 else if (subsampling_x
== 1 && subsampling_y
== 0)
1363 fmt
= AOM_IMG_FMT_I422
;
1364 else if (subsampling_x
== 1 && subsampling_y
== 1)
1365 fmt
= AOM_IMG_FMT_I420
;
1367 if (use_highbitdepth
) fmt
|= AOM_IMG_FMT_HIGHBITDEPTH
;
1371 static aom_codec_err_t
ctrl_get_img_format(aom_codec_alg_priv_t
*ctx
,
1373 aom_img_fmt_t
*const img_fmt
= va_arg(args
, aom_img_fmt_t
*);
1374 AVxWorker
*const worker
= ctx
->frame_worker
;
1378 FrameWorkerData
*const frame_worker_data
=
1379 (FrameWorkerData
*)worker
->data1
;
1380 const AV1_COMMON
*const cm
= &frame_worker_data
->pbi
->common
;
1382 *img_fmt
= get_img_format(cm
->seq_params
->subsampling_x
,
1383 cm
->seq_params
->subsampling_y
,
1384 cm
->seq_params
->use_highbitdepth
);
1385 return AOM_CODEC_OK
;
1387 return AOM_CODEC_ERROR
;
1391 return AOM_CODEC_INVALID_PARAM
;
1394 static aom_codec_err_t
ctrl_get_tile_size(aom_codec_alg_priv_t
*ctx
,
1396 unsigned int *const tile_size
= va_arg(args
, unsigned int *);
1397 AVxWorker
*const worker
= ctx
->frame_worker
;
1401 FrameWorkerData
*const frame_worker_data
=
1402 (FrameWorkerData
*)worker
->data1
;
1403 const AV1_COMMON
*const cm
= &frame_worker_data
->pbi
->common
;
1404 int tile_width
, tile_height
;
1405 av1_get_uniform_tile_size(cm
, &tile_width
, &tile_height
);
1406 *tile_size
= ((tile_width
* MI_SIZE
) << 16) + tile_height
* MI_SIZE
;
1407 return AOM_CODEC_OK
;
1409 return AOM_CODEC_ERROR
;
1412 return AOM_CODEC_INVALID_PARAM
;
1415 static aom_codec_err_t
ctrl_get_tile_count(aom_codec_alg_priv_t
*ctx
,
1417 unsigned int *const tile_count
= va_arg(args
, unsigned int *);
1420 AVxWorker
*const worker
= ctx
->frame_worker
;
1422 FrameWorkerData
*const frame_worker_data
=
1423 (FrameWorkerData
*)worker
->data1
;
1424 *tile_count
= frame_worker_data
->pbi
->tile_count_minus_1
+ 1;
1425 return AOM_CODEC_OK
;
1427 return AOM_CODEC_ERROR
;
1430 return AOM_CODEC_INVALID_PARAM
;
1433 static aom_codec_err_t
ctrl_get_base_q_idx(aom_codec_alg_priv_t
*ctx
,
1435 int *const arg
= va_arg(args
, int *);
1436 if (arg
== NULL
) return AOM_CODEC_INVALID_PARAM
;
1437 if (ctx
->frame_worker
== NULL
) return AOM_CODEC_ERROR
;
1438 FrameWorkerData
*const frame_worker_data
=
1439 (FrameWorkerData
*)ctx
->frame_worker
->data1
;
1440 *arg
= frame_worker_data
->pbi
->common
.quant_params
.base_qindex
;
1441 return AOM_CODEC_OK
;
1444 static aom_codec_err_t
ctrl_get_show_frame_flag(aom_codec_alg_priv_t
*ctx
,
1446 int *const arg
= va_arg(args
, int *);
1447 if (arg
== NULL
) return AOM_CODEC_INVALID_PARAM
;
1448 if (ctx
->frame_worker
== NULL
) return AOM_CODEC_ERROR
;
1449 FrameWorkerData
*const frame_worker_data
=
1450 (FrameWorkerData
*)ctx
->frame_worker
->data1
;
1451 *arg
= frame_worker_data
->pbi
->common
.show_frame
;
1452 return AOM_CODEC_OK
;
1455 static aom_codec_err_t
ctrl_get_order_hint(aom_codec_alg_priv_t
*ctx
,
1457 unsigned int *const arg
= va_arg(args
, unsigned int *);
1458 if (arg
== NULL
) return AOM_CODEC_INVALID_PARAM
;
1459 if (ctx
->frame_worker
== NULL
) return AOM_CODEC_ERROR
;
1460 FrameWorkerData
*const frame_worker_data
=
1461 (FrameWorkerData
*)ctx
->frame_worker
->data1
;
1462 *arg
= frame_worker_data
->pbi
->common
.current_frame
.order_hint
;
1463 return AOM_CODEC_OK
;
1466 static aom_codec_err_t
ctrl_get_mi_info(aom_codec_alg_priv_t
*ctx
,
1468 int mi_row
= va_arg(args
, int);
1469 int mi_col
= va_arg(args
, int);
1470 MB_MODE_INFO
*mi
= va_arg(args
, MB_MODE_INFO
*);
1471 if (mi
== NULL
) return AOM_CODEC_INVALID_PARAM
;
1472 if (ctx
->frame_worker
== NULL
) return AOM_CODEC_ERROR
;
1473 FrameWorkerData
*const frame_worker_data
=
1474 (FrameWorkerData
*)ctx
->frame_worker
->data1
;
1475 if (frame_worker_data
== NULL
) return AOM_CODEC_ERROR
;
1477 AV1_COMMON
*cm
= &frame_worker_data
->pbi
->common
;
1478 const int mi_rows
= cm
->mi_params
.mi_rows
;
1479 const int mi_cols
= cm
->mi_params
.mi_cols
;
1480 const int mi_stride
= cm
->mi_params
.mi_stride
;
1481 const int offset
= mi_row
* mi_stride
+ mi_col
;
1483 if (mi_row
< 0 || mi_row
>= mi_rows
|| mi_col
< 0 || mi_col
>= mi_cols
) {
1484 return AOM_CODEC_INVALID_PARAM
;
1487 memcpy(mi
, cm
->mi_params
.mi_grid_base
[offset
], sizeof(*mi
));
1489 return AOM_CODEC_OK
;
1492 static aom_codec_err_t
ctrl_set_invert_tile_order(aom_codec_alg_priv_t
*ctx
,
1494 ctx
->invert_tile_order
= va_arg(args
, int);
1495 return AOM_CODEC_OK
;
1498 static aom_codec_err_t
ctrl_set_byte_alignment(aom_codec_alg_priv_t
*ctx
,
1500 const int legacy_byte_alignment
= 0;
1501 const int min_byte_alignment
= 32;
1502 const int max_byte_alignment
= 1024;
1503 const int byte_alignment
= va_arg(args
, int);
1505 if (byte_alignment
!= legacy_byte_alignment
&&
1506 (byte_alignment
< min_byte_alignment
||
1507 byte_alignment
> max_byte_alignment
||
1508 (byte_alignment
& (byte_alignment
- 1)) != 0))
1509 return AOM_CODEC_INVALID_PARAM
;
1511 ctx
->byte_alignment
= byte_alignment
;
1512 if (ctx
->frame_worker
) {
1513 AVxWorker
*const worker
= ctx
->frame_worker
;
1514 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
1515 frame_worker_data
->pbi
->common
.features
.byte_alignment
= byte_alignment
;
1517 return AOM_CODEC_OK
;
1520 static aom_codec_err_t
ctrl_set_skip_loop_filter(aom_codec_alg_priv_t
*ctx
,
1522 ctx
->skip_loop_filter
= va_arg(args
, int);
1524 if (ctx
->frame_worker
) {
1525 AVxWorker
*const worker
= ctx
->frame_worker
;
1526 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
1527 frame_worker_data
->pbi
->skip_loop_filter
= ctx
->skip_loop_filter
;
1530 return AOM_CODEC_OK
;
1533 static aom_codec_err_t
ctrl_set_skip_film_grain(aom_codec_alg_priv_t
*ctx
,
1535 ctx
->skip_film_grain
= va_arg(args
, int);
1537 if (ctx
->frame_worker
) {
1538 AVxWorker
*const worker
= ctx
->frame_worker
;
1539 FrameWorkerData
*const frame_worker_data
= (FrameWorkerData
*)worker
->data1
;
1540 frame_worker_data
->pbi
->skip_film_grain
= ctx
->skip_film_grain
;
1543 return AOM_CODEC_OK
;
1546 static aom_codec_err_t
ctrl_get_accounting(aom_codec_alg_priv_t
*ctx
,
1548 #if !CONFIG_ACCOUNTING
1551 return AOM_CODEC_INCAPABLE
;
1553 Accounting
**acct
= va_arg(args
, Accounting
**);
1556 if (ctx
->frame_worker
) {
1557 AVxWorker
*const worker
= ctx
->frame_worker
;
1558 FrameWorkerData
*const frame_worker_data
=
1559 (FrameWorkerData
*)worker
->data1
;
1560 AV1Decoder
*pbi
= frame_worker_data
->pbi
;
1561 *acct
= &pbi
->accounting
;
1562 return AOM_CODEC_OK
;
1564 return AOM_CODEC_ERROR
;
1568 return AOM_CODEC_INVALID_PARAM
;
1572 static aom_codec_err_t
ctrl_set_decode_tile_row(aom_codec_alg_priv_t
*ctx
,
1574 ctx
->decode_tile_row
= va_arg(args
, int);
1575 return AOM_CODEC_OK
;
1578 static aom_codec_err_t
ctrl_set_decode_tile_col(aom_codec_alg_priv_t
*ctx
,
1580 ctx
->decode_tile_col
= va_arg(args
, int);
1581 return AOM_CODEC_OK
;
1584 static aom_codec_err_t
ctrl_set_tile_mode(aom_codec_alg_priv_t
*ctx
,
1586 ctx
->tile_mode
= va_arg(args
, unsigned int);
1587 return AOM_CODEC_OK
;
1590 static aom_codec_err_t
ctrl_set_is_annexb(aom_codec_alg_priv_t
*ctx
,
1592 ctx
->is_annexb
= va_arg(args
, unsigned int);
1593 return AOM_CODEC_OK
;
1596 static aom_codec_err_t
ctrl_set_operating_point(aom_codec_alg_priv_t
*ctx
,
1598 ctx
->operating_point
= va_arg(args
, int);
1599 return AOM_CODEC_OK
;
1602 static aom_codec_err_t
ctrl_set_output_all_layers(aom_codec_alg_priv_t
*ctx
,
1604 ctx
->output_all_layers
= va_arg(args
, int);
1605 return AOM_CODEC_OK
;
1608 static aom_codec_err_t
ctrl_set_inspection_callback(aom_codec_alg_priv_t
*ctx
,
1610 #if !CONFIG_INSPECTION
1613 return AOM_CODEC_INCAPABLE
;
1615 aom_inspect_init
*init
= va_arg(args
, aom_inspect_init
*);
1616 ctx
->inspect_cb
= init
->inspect_cb
;
1617 ctx
->inspect_ctx
= init
->inspect_ctx
;
1618 return AOM_CODEC_OK
;
1622 static aom_codec_err_t
ctrl_ext_tile_debug(aom_codec_alg_priv_t
*ctx
,
1624 ctx
->ext_tile_debug
= va_arg(args
, int);
1625 return AOM_CODEC_OK
;
1628 static aom_codec_err_t
ctrl_set_row_mt(aom_codec_alg_priv_t
*ctx
,
1630 ctx
->row_mt
= va_arg(args
, unsigned int);
1631 return AOM_CODEC_OK
;
1634 static aom_codec_ctrl_fn_map_t decoder_ctrl_maps
[] = {
1635 { AV1_COPY_REFERENCE
, ctrl_copy_reference
},
1638 { AV1_SET_REFERENCE
, ctrl_set_reference
},
1639 { AV1_INVERT_TILE_DECODE_ORDER
, ctrl_set_invert_tile_order
},
1640 { AV1_SET_BYTE_ALIGNMENT
, ctrl_set_byte_alignment
},
1641 { AV1_SET_SKIP_LOOP_FILTER
, ctrl_set_skip_loop_filter
},
1642 { AV1_SET_DECODE_TILE_ROW
, ctrl_set_decode_tile_row
},
1643 { AV1_SET_DECODE_TILE_COL
, ctrl_set_decode_tile_col
},
1644 { AV1_SET_TILE_MODE
, ctrl_set_tile_mode
},
1645 { AV1D_SET_IS_ANNEXB
, ctrl_set_is_annexb
},
1646 { AV1D_SET_OPERATING_POINT
, ctrl_set_operating_point
},
1647 { AV1D_SET_OUTPUT_ALL_LAYERS
, ctrl_set_output_all_layers
},
1648 { AV1_SET_INSPECTION_CALLBACK
, ctrl_set_inspection_callback
},
1649 { AV1D_EXT_TILE_DEBUG
, ctrl_ext_tile_debug
},
1650 { AV1D_SET_ROW_MT
, ctrl_set_row_mt
},
1651 { AV1D_SET_EXT_REF_PTR
, ctrl_set_ext_ref_ptr
},
1652 { AV1D_SET_SKIP_FILM_GRAIN
, ctrl_set_skip_film_grain
},
1655 { AOMD_GET_FRAME_CORRUPTED
, ctrl_get_frame_corrupted
},
1656 { AOMD_GET_LAST_QUANTIZER
, ctrl_get_last_quantizer
},
1657 { AOMD_GET_LAST_REF_UPDATES
, ctrl_get_last_ref_updates
},
1658 { AV1D_GET_BIT_DEPTH
, ctrl_get_bit_depth
},
1659 { AV1D_GET_IMG_FORMAT
, ctrl_get_img_format
},
1660 { AV1D_GET_TILE_SIZE
, ctrl_get_tile_size
},
1661 { AV1D_GET_TILE_COUNT
, ctrl_get_tile_count
},
1662 { AV1D_GET_DISPLAY_SIZE
, ctrl_get_render_size
},
1663 { AV1D_GET_FRAME_SIZE
, ctrl_get_frame_size
},
1664 { AV1_GET_ACCOUNTING
, ctrl_get_accounting
},
1665 { AV1_GET_NEW_FRAME_IMAGE
, ctrl_get_new_frame_image
},
1666 { AV1_COPY_NEW_FRAME_IMAGE
, ctrl_copy_new_frame_image
},
1667 { AV1_GET_REFERENCE
, ctrl_get_reference
},
1668 { AV1D_GET_FRAME_HEADER_INFO
, ctrl_get_frame_header_info
},
1669 { AV1D_GET_TILE_DATA
, ctrl_get_tile_data
},
1670 { AOMD_GET_FWD_KF_PRESENT
, ctrl_get_fwd_kf_value
},
1671 { AOMD_GET_ALTREF_PRESENT
, ctrl_get_altref_present
},
1672 { AOMD_GET_FRAME_FLAGS
, ctrl_get_frame_flags
},
1673 { AOMD_GET_TILE_INFO
, ctrl_get_tile_info
},
1674 { AOMD_GET_SCREEN_CONTENT_TOOLS_INFO
, ctrl_get_screen_content_tools_info
},
1675 { AOMD_GET_STILL_PICTURE
, ctrl_get_still_picture
},
1676 { AOMD_GET_SB_SIZE
, ctrl_get_sb_size
},
1677 { AOMD_GET_SHOW_EXISTING_FRAME_FLAG
, ctrl_get_show_existing_frame_flag
},
1678 { AOMD_GET_S_FRAME_INFO
, ctrl_get_s_frame_info
},
1679 { AOMD_GET_SHOW_FRAME_FLAG
, ctrl_get_show_frame_flag
},
1680 { AOMD_GET_BASE_Q_IDX
, ctrl_get_base_q_idx
},
1681 { AOMD_GET_ORDER_HINT
, ctrl_get_order_hint
},
1682 { AV1D_GET_MI_INFO
, ctrl_get_mi_info
},
1686 // This data structure and function are exported in aom/aomdx.h
1687 #ifndef VERSION_STRING
1688 #define VERSION_STRING
1690 aom_codec_iface_t aom_codec_av1_dx_algo
= {
1691 "AOMedia Project AV1 Decoder" VERSION_STRING
,
1692 AOM_CODEC_INTERNAL_ABI_VERSION
,
1693 AOM_CODEC_CAP_DECODER
|
1694 AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER
, // aom_codec_caps_t
1695 decoder_init
, // aom_codec_init_fn_t
1696 decoder_destroy
, // aom_codec_destroy_fn_t
1697 decoder_ctrl_maps
, // aom_codec_ctrl_fn_map_t
1700 decoder_peek_si
, // aom_codec_peek_si_fn_t
1701 decoder_get_si
, // aom_codec_get_si_fn_t
1702 decoder_decode
, // aom_codec_decode_fn_t
1703 decoder_get_frame
, // aom_codec_get_frame_fn_t
1704 decoder_set_fb_fn
, // aom_codec_set_fb_fn_t
1709 NULL
, // aom_codec_enc_cfg_t
1710 NULL
, // aom_codec_encode_fn_t
1711 NULL
, // aom_codec_get_cx_data_fn_t
1712 NULL
, // aom_codec_enc_config_set_fn_t
1713 NULL
, // aom_codec_get_global_headers_fn_t
1714 NULL
// aom_codec_get_preview_frame_fn_t
1716 NULL
// aom_codec_set_option_fn_t
1719 // Decoder interface for inspecting frame data. It uses decoder_inspect instead
1720 // of decoder_decode so it only decodes one frame at a time, whether the frame
1722 aom_codec_iface_t aom_codec_av1_inspect_algo
= {
1723 "AOMedia Project AV1 Decoder Inspector" VERSION_STRING
,
1724 AOM_CODEC_INTERNAL_ABI_VERSION
,
1725 AOM_CODEC_CAP_DECODER
|
1726 AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER
, // aom_codec_caps_t
1727 decoder_init
, // aom_codec_init_fn_t
1728 decoder_destroy
, // aom_codec_destroy_fn_t
1729 decoder_ctrl_maps
, // aom_codec_ctrl_fn_map_t
1732 decoder_peek_si
, // aom_codec_peek_si_fn_t
1733 decoder_get_si
, // aom_codec_get_si_fn_t
1734 decoder_inspect
, // aom_codec_decode_fn_t
1735 decoder_get_frame
, // aom_codec_get_frame_fn_t
1736 decoder_set_fb_fn
, // aom_codec_set_fb_fn_t
1741 NULL
, // aom_codec_enc_cfg_t
1742 NULL
, // aom_codec_encode_fn_t
1743 NULL
, // aom_codec_get_cx_data_fn_t
1744 NULL
, // aom_codec_enc_config_set_fn_t
1745 NULL
, // aom_codec_get_global_headers_fn_t
1746 NULL
// aom_codec_get_preview_frame_fn_t
1748 NULL
// aom_codec_set_option_fn_t
1751 aom_codec_iface_t
*aom_codec_av1_dx(void) { return &aom_codec_av1_dx_algo
; }