| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "vp9/vp9_iface_common.h" | 25 #include "vp9/vp9_iface_common.h" |
| 26 | 26 |
| 27 #define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) | 27 #define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) |
| 28 | 28 |
| 29 typedef vpx_codec_stream_info_t vp9_stream_info_t; | 29 typedef vpx_codec_stream_info_t vp9_stream_info_t; |
| 30 | 30 |
| 31 struct vpx_codec_alg_priv { | 31 struct vpx_codec_alg_priv { |
| 32 vpx_codec_priv_t base; | 32 vpx_codec_priv_t base; |
| 33 vpx_codec_dec_cfg_t cfg; | 33 vpx_codec_dec_cfg_t cfg; |
| 34 vp9_stream_info_t si; | 34 vp9_stream_info_t si; |
| 35 struct VP9Decoder *pbi; | |
| 36 int postproc_cfg_set; | 35 int postproc_cfg_set; |
| 37 vp8_postproc_cfg_t postproc_cfg; | 36 vp8_postproc_cfg_t postproc_cfg; |
| 38 vpx_decrypt_cb decrypt_cb; | 37 vpx_decrypt_cb decrypt_cb; |
| 39 void *decrypt_state; | 38 void *decrypt_state; |
| 40 vpx_image_t img; | 39 vpx_image_t img; |
| 41 int invert_tile_order; | 40 int invert_tile_order; |
| 42 int frame_parallel_decode; // frame-based threading. | 41 int frame_parallel_decode; // frame-based threading. |
| 43 int last_show_frame; // Index of last output frame. | 42 int last_show_frame; // Index of last output frame. |
| 44 | 43 |
| 44 VP9Worker *frame_workers; |
| 45 int num_frame_workers; |
| 46 int next_submit_thread_id; |
| 47 int next_output_thread_id; |
| 48 |
| 45 // External frame buffer info to save for VP9 common. | 49 // External frame buffer info to save for VP9 common. |
| 46 void *ext_priv; // Private data associated with the external frame buffers. | 50 void *ext_priv; // Private data associated with the external frame buffers. |
| 47 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; | 51 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; |
| 48 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; | 52 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; |
| 49 }; | 53 }; |
| 50 | 54 |
| 51 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, | 55 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, |
| 52 vpx_codec_priv_enc_mr_cfg_t *data) { | 56 vpx_codec_priv_enc_mr_cfg_t *data) { |
| 53 // This function only allocates space for the vpx_codec_alg_priv_t | 57 // This function only allocates space for the vpx_codec_alg_priv_t |
| 54 // structure. More memory may be required at the time the stream | 58 // structure. More memory may be required at the time the stream |
| (...skipping 23 matching lines...) Expand all Loading... |
| 78 // Update the reference to the config structure to an internal copy. | 82 // Update the reference to the config structure to an internal copy. |
| 79 ctx->priv->alg_priv->cfg = *ctx->config.dec; | 83 ctx->priv->alg_priv->cfg = *ctx->config.dec; |
| 80 ctx->config.dec = &ctx->priv->alg_priv->cfg; | 84 ctx->config.dec = &ctx->priv->alg_priv->cfg; |
| 81 } | 85 } |
| 82 } | 86 } |
| 83 | 87 |
| 84 return VPX_CODEC_OK; | 88 return VPX_CODEC_OK; |
| 85 } | 89 } |
| 86 | 90 |
| 87 static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) { | 91 static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) { |
| 88 if (ctx->pbi) { | 92 if (ctx->frame_workers != NULL) { |
| 89 vp9_decoder_remove(ctx->pbi); | 93 int i; |
| 90 ctx->pbi = NULL; | 94 for (i = 0; i < ctx->num_frame_workers; ++i) { |
| 95 VP9Worker *const worker = &ctx->frame_workers[i]; |
| 96 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 97 vp9_decoder_remove(worker_data->pbi); |
| 98 vpx_free(worker_data); |
| 99 } |
| 91 } | 100 } |
| 92 | 101 |
| 102 vpx_free(ctx->frame_workers); |
| 93 vpx_free(ctx); | 103 vpx_free(ctx); |
| 94 | 104 |
| 95 return VPX_CODEC_OK; | 105 return VPX_CODEC_OK; |
| 96 } | 106 } |
| 97 | 107 |
| 98 static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, | 108 static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, |
| 99 unsigned int data_sz, | 109 unsigned int data_sz, |
| 100 vpx_codec_stream_info_t *si, | 110 vpx_codec_stream_info_t *si, |
| 101 vpx_decrypt_cb decrypt_cb, | 111 vpx_decrypt_cb decrypt_cb, |
| 102 void *decrypt_state) { | 112 void *decrypt_state) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 vpx_codec_stream_info_t *si) { | 190 vpx_codec_stream_info_t *si) { |
| 181 const size_t sz = (si->sz >= sizeof(vp9_stream_info_t)) | 191 const size_t sz = (si->sz >= sizeof(vp9_stream_info_t)) |
| 182 ? sizeof(vp9_stream_info_t) | 192 ? sizeof(vp9_stream_info_t) |
| 183 : sizeof(vpx_codec_stream_info_t); | 193 : sizeof(vpx_codec_stream_info_t); |
| 184 memcpy(si, &ctx->si, sz); | 194 memcpy(si, &ctx->si, sz); |
| 185 si->sz = (unsigned int)sz; | 195 si->sz = (unsigned int)sz; |
| 186 | 196 |
| 187 return VPX_CODEC_OK; | 197 return VPX_CODEC_OK; |
| 188 } | 198 } |
| 189 | 199 |
| 200 static void set_error_detail(vpx_codec_alg_priv_t *ctx, |
| 201 const char *const error) { |
| 202 ctx->base.err_detail = error; |
| 203 } |
| 204 |
| 190 static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx, | 205 static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx, |
| 191 const struct vpx_internal_error_info *error) { | 206 const struct vpx_internal_error_info *error) { |
| 192 if (error->error_code) | 207 if (error->error_code) |
| 193 ctx->base.err_detail = error->has_detail ? error->detail : NULL; | 208 set_error_detail(ctx, error->has_detail ? error->detail : NULL); |
| 194 | 209 |
| 195 return error->error_code; | 210 return error->error_code; |
| 196 } | 211 } |
| 197 | 212 |
| 198 static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) { | 213 static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) { |
| 199 VP9_COMMON *const cm = &ctx->pbi->common; | 214 int i; |
| 200 | 215 |
| 201 cm->new_fb_idx = -1; | 216 for (i = 0; i < ctx->num_frame_workers; ++i) { |
| 217 VP9Worker *const worker = &ctx->frame_workers[i]; |
| 218 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 219 VP9_COMMON *const cm = &worker_data->pbi->common; |
| 202 | 220 |
| 203 if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) { | 221 cm->new_fb_idx = -1; |
| 204 cm->get_fb_cb = ctx->get_ext_fb_cb; | 222 if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) { |
| 205 cm->release_fb_cb = ctx->release_ext_fb_cb; | 223 cm->get_fb_cb = ctx->get_ext_fb_cb; |
| 206 cm->cb_priv = ctx->ext_priv; | 224 cm->release_fb_cb = ctx->release_ext_fb_cb; |
| 207 } else { | 225 cm->cb_priv = ctx->ext_priv; |
| 208 cm->get_fb_cb = vp9_get_frame_buffer; | 226 } else { |
| 209 cm->release_fb_cb = vp9_release_frame_buffer; | 227 cm->get_fb_cb = vp9_get_frame_buffer; |
| 228 cm->release_fb_cb = vp9_release_frame_buffer; |
| 210 | 229 |
| 211 if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers)) | 230 if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers)) |
| 212 vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, | 231 vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, |
| 213 "Failed to initialize internal frame buffers"); | 232 "Failed to initialize internal frame buffers"); |
| 214 | 233 |
| 215 cm->cb_priv = &cm->int_frame_buffers; | 234 cm->cb_priv = &cm->int_frame_buffers; |
| 235 } |
| 216 } | 236 } |
| 217 } | 237 } |
| 218 | 238 |
| 219 static void set_default_ppflags(vp8_postproc_cfg_t *cfg) { | 239 static void set_default_ppflags(vp8_postproc_cfg_t *cfg) { |
| 220 cfg->post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK; | 240 cfg->post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK; |
| 221 cfg->deblocking_level = 4; | 241 cfg->deblocking_level = 4; |
| 222 cfg->noise_level = 0; | 242 cfg->noise_level = 0; |
| 223 } | 243 } |
| 224 | 244 |
| 225 static void set_ppflags(const vpx_codec_alg_priv_t *ctx, | 245 static void set_ppflags(const vpx_codec_alg_priv_t *ctx, |
| 226 vp9_ppflags_t *flags) { | 246 vp9_ppflags_t *flags) { |
| 227 flags->post_proc_flag = | 247 flags->post_proc_flag = |
| 228 ctx->postproc_cfg.post_proc_flag; | 248 ctx->postproc_cfg.post_proc_flag; |
| 229 | 249 |
| 230 flags->deblocking_level = ctx->postproc_cfg.deblocking_level; | 250 flags->deblocking_level = ctx->postproc_cfg.deblocking_level; |
| 231 flags->noise_level = ctx->postproc_cfg.noise_level; | 251 flags->noise_level = ctx->postproc_cfg.noise_level; |
| 232 } | 252 } |
| 233 | 253 |
| 234 static void init_decoder(vpx_codec_alg_priv_t *ctx) { | 254 static int frame_worker_hook(void *arg1, void *arg2) { |
| 235 ctx->pbi = vp9_decoder_create(); | 255 FrameWorkerData *const worker_data = (FrameWorkerData *)arg1; |
| 236 if (ctx->pbi == NULL) | 256 const uint8_t *data = worker_data->data; |
| 237 return; | 257 (void)arg2; |
| 258 worker_data->result = vp9_receive_compressed_data(worker_data->pbi, |
| 259 worker_data->data_size, |
| 260 &data); |
| 261 worker_data->data_end = data; |
| 262 return !worker_data->result; |
| 263 } |
| 238 | 264 |
| 239 ctx->pbi->max_threads = ctx->cfg.threads; | 265 static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) { |
| 240 ctx->pbi->inv_tile_order = ctx->invert_tile_order; | 266 int i; |
| 241 ctx->pbi->frame_parallel_decode = ctx->frame_parallel_decode; | 267 |
| 242 ctx->last_show_frame = -1; | 268 ctx->last_show_frame = -1; |
| 269 ctx->next_submit_thread_id = 0; |
| 270 ctx->next_output_thread_id = 0; |
| 271 ctx->num_frame_workers = |
| 272 (ctx->frame_parallel_decode == 1) ? ctx->cfg.threads: 1; |
| 273 |
| 274 ctx->frame_workers = (VP9Worker *) |
| 275 vpx_malloc(ctx->num_frame_workers * sizeof(*ctx->frame_workers)); |
| 276 if (ctx->frame_workers == NULL) { |
| 277 set_error_detail(ctx, "Failed to allocate frame_workers"); |
| 278 return VPX_CODEC_MEM_ERROR; |
| 279 } |
| 280 |
| 281 for (i = 0; i < ctx->num_frame_workers; ++i) { |
| 282 VP9Worker *const worker = &ctx->frame_workers[i]; |
| 283 FrameWorkerData *worker_data = NULL; |
| 284 vp9_worker_init(worker); |
| 285 worker->data1 = vpx_memalign(32, sizeof(FrameWorkerData)); |
| 286 if (worker->data1 == NULL) { |
| 287 set_error_detail(ctx, "Failed to allocate worker_data"); |
| 288 return VPX_CODEC_MEM_ERROR; |
| 289 } |
| 290 worker_data = (FrameWorkerData *)worker->data1; |
| 291 worker_data->pbi = vp9_decoder_create(); |
| 292 if (worker_data->pbi == NULL) { |
| 293 set_error_detail(ctx, "Failed to allocate worker_data"); |
| 294 return VPX_CODEC_MEM_ERROR; |
| 295 } |
| 296 |
| 297 // If decoding in serial mode, FrameWorker thread could create tile worker |
| 298 // thread or loopfilter thread. |
| 299 worker_data->pbi->max_threads = |
| 300 (ctx->frame_parallel_decode == 0) ? ctx->cfg.threads : 0; |
| 301 |
| 302 worker_data->pbi->inv_tile_order = ctx->invert_tile_order; |
| 303 worker_data->pbi->frame_parallel_decode = ctx->frame_parallel_decode; |
| 304 worker->hook = (VP9WorkerHook)frame_worker_hook; |
| 305 } |
| 243 | 306 |
| 244 // If postprocessing was enabled by the application and a | 307 // If postprocessing was enabled by the application and a |
| 245 // configuration has not been provided, default it. | 308 // configuration has not been provided, default it. |
| 246 if (!ctx->postproc_cfg_set && | 309 if (!ctx->postproc_cfg_set && |
| 247 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) | 310 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) |
| 248 set_default_ppflags(&ctx->postproc_cfg); | 311 set_default_ppflags(&ctx->postproc_cfg); |
| 249 | 312 |
| 250 init_buffer_callbacks(ctx); | 313 init_buffer_callbacks(ctx); |
| 314 |
| 315 return VPX_CODEC_OK; |
| 251 } | 316 } |
| 252 | 317 |
| 253 static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx, | 318 static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx, |
| 254 const uint8_t **data, unsigned int data_sz, | 319 const uint8_t **data, unsigned int data_sz, |
| 255 void *user_priv, int64_t deadline) { | 320 void *user_priv, int64_t deadline) { |
| 256 vp9_ppflags_t flags = {0}; | 321 vp9_ppflags_t flags = {0}; |
| 257 VP9_COMMON *cm = NULL; | |
| 258 | |
| 259 (void)deadline; | 322 (void)deadline; |
| 260 | 323 |
| 261 // Determine the stream parameters. Note that we rely on peek_si to | 324 // 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 | 325 // validate that we have a buffer that does not wrap around the top |
| 263 // of the heap. | 326 // of the heap. |
| 264 if (!ctx->si.h) { | 327 if (!ctx->si.h) { |
| 265 const vpx_codec_err_t res = | 328 const vpx_codec_err_t res = |
| 266 decoder_peek_si_internal(*data, data_sz, &ctx->si, ctx->decrypt_cb, | 329 decoder_peek_si_internal(*data, data_sz, &ctx->si, ctx->decrypt_cb, |
| 267 ctx->decrypt_state); | 330 ctx->decrypt_state); |
| 268 if (res != VPX_CODEC_OK) | 331 if (res != VPX_CODEC_OK) |
| 269 return res; | 332 return res; |
| 270 | 333 |
| 271 if (!ctx->si.is_kf) | 334 if (!ctx->si.is_kf) |
| 272 return VPX_CODEC_ERROR; | 335 return VPX_CODEC_ERROR; |
| 273 } | 336 } |
| 274 | 337 |
| 275 // Initialize the decoder instance on the first frame | 338 // Initialize the decoder workers on the first frame |
| 276 if (ctx->pbi == NULL) { | 339 if (ctx->frame_workers == NULL) { |
| 277 init_decoder(ctx); | 340 const vpx_codec_err_t res = init_decoder(ctx); |
| 278 if (ctx->pbi == NULL) | 341 if (res != VPX_CODEC_OK) |
| 279 return VPX_CODEC_ERROR; | 342 return res; |
| 280 } | 343 } |
| 281 | 344 |
| 282 // Set these even if already initialized. The caller may have changed the | 345 if (!ctx->frame_parallel_decode) { |
| 283 // decrypt config between frames. | 346 VP9Worker *const worker = ctx->frame_workers; |
| 284 ctx->pbi->decrypt_cb = ctx->decrypt_cb; | 347 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 285 ctx->pbi->decrypt_state = ctx->decrypt_state; | 348 worker_data->data = *data; |
| 349 worker_data->data_size = data_sz; |
| 286 | 350 |
| 287 cm = &ctx->pbi->common; | 351 // Set these even if already initialized. The caller may have changed the |
| 352 // decrypt config between frames. |
| 353 worker_data->pbi->decrypt_cb = ctx->decrypt_cb; |
| 354 worker_data->pbi->decrypt_state = ctx->decrypt_state; |
| 288 | 355 |
| 289 if (vp9_receive_compressed_data(ctx->pbi, data_sz, data)) | 356 vp9_worker_execute(worker); |
| 290 return update_error_state(ctx, &cm->error); | 357 if (worker->had_error) |
| 358 return update_error_state(ctx, &worker_data->pbi->common.error); |
| 359 |
| 360 // Update data pointer after decode. |
| 361 *data = worker_data->data_end; |
| 362 } else { |
| 363 // TODO(hkuang): Implement frame parallel decode. |
| 364 return VPX_CODEC_INCAPABLE; |
| 365 } |
| 291 | 366 |
| 292 if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) | 367 if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) |
| 293 set_ppflags(ctx, &flags); | 368 set_ppflags(ctx, &flags); |
| 294 | 369 |
| 295 return VPX_CODEC_OK; | 370 return VPX_CODEC_OK; |
| 296 } | 371 } |
| 297 | 372 |
| 298 static INLINE uint8_t read_marker(vpx_decrypt_cb decrypt_cb, | 373 static INLINE uint8_t read_marker(vpx_decrypt_cb decrypt_cb, |
| 299 void *decrypt_state, | 374 void *decrypt_state, |
| 300 const uint8_t *data) { | 375 const uint8_t *data) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 // in the superframe. | 449 // in the superframe. |
| 375 if (frame_count > 0) { | 450 if (frame_count > 0) { |
| 376 int i; | 451 int i; |
| 377 | 452 |
| 378 for (i = 0; i < frame_count; ++i) { | 453 for (i = 0; i < frame_count; ++i) { |
| 379 const uint8_t *data_start_copy = data_start; | 454 const uint8_t *data_start_copy = data_start; |
| 380 const uint32_t frame_size = frame_sizes[i]; | 455 const uint32_t frame_size = frame_sizes[i]; |
| 381 vpx_codec_err_t res; | 456 vpx_codec_err_t res; |
| 382 if (data_start < data | 457 if (data_start < data |
| 383 || frame_size > (uint32_t) (data_end - data_start)) { | 458 || frame_size > (uint32_t) (data_end - data_start)) { |
| 384 ctx->base.err_detail = "Invalid frame size in index"; | 459 set_error_detail(ctx, "Invalid frame size in index"); |
| 385 return VPX_CODEC_CORRUPT_FRAME; | 460 return VPX_CODEC_CORRUPT_FRAME; |
| 386 } | 461 } |
| 387 | 462 |
| 388 res = decode_one(ctx, &data_start_copy, frame_size, user_priv, | 463 res = decode_one(ctx, &data_start_copy, frame_size, user_priv, |
| 389 deadline); | 464 deadline); |
| 390 if (res != VPX_CODEC_OK) | 465 if (res != VPX_CODEC_OK) |
| 391 return res; | 466 return res; |
| 392 | 467 |
| 393 data_start += frame_size; | 468 data_start += frame_size; |
| 394 } | 469 } |
| 395 } else { | 470 } else { |
| 396 res = decode_one(ctx, &data_start, data_sz, user_priv, deadline); | 471 res = decode_one(ctx, &data_start, data_sz, user_priv, deadline); |
| 397 if (res != VPX_CODEC_OK) | 472 if (res != VPX_CODEC_OK) |
| 398 return res; | 473 return res; |
| 399 | 474 |
| 400 // Extra data detected after the frame. | 475 // Extra data detected after the frame. |
| 401 if (data_start < data_end - 1) { | 476 if (data_start < data_end - 1) { |
| 402 ctx->base.err_detail = "Fail to decode frame in parallel mode"; | 477 set_error_detail(ctx, "Fail to decode frame in parallel mode"); |
| 403 return VPX_CODEC_INCAPABLE; | 478 return VPX_CODEC_INCAPABLE; |
| 404 } | 479 } |
| 405 } | 480 } |
| 406 } else { | 481 } else { |
| 407 // Decode in serial mode. | 482 // Decode in serial mode. |
| 408 if (frame_count > 0) { | 483 if (frame_count > 0) { |
| 409 int i; | 484 int i; |
| 410 | 485 |
| 411 for (i = 0; i < frame_count; ++i) { | 486 for (i = 0; i < frame_count; ++i) { |
| 412 const uint8_t *data_start_copy = data_start; | 487 const uint8_t *data_start_copy = data_start; |
| 413 const uint32_t frame_size = frame_sizes[i]; | 488 const uint32_t frame_size = frame_sizes[i]; |
| 414 vpx_codec_err_t res; | 489 vpx_codec_err_t res; |
| 415 if (data_start < data | 490 if (data_start < data |
| 416 || frame_size > (uint32_t) (data_end - data_start)) { | 491 || frame_size > (uint32_t) (data_end - data_start)) { |
| 417 ctx->base.err_detail = "Invalid frame size in index"; | 492 set_error_detail(ctx, "Invalid frame size in index"); |
| 418 return VPX_CODEC_CORRUPT_FRAME; | 493 return VPX_CODEC_CORRUPT_FRAME; |
| 419 } | 494 } |
| 420 | 495 |
| 421 res = decode_one(ctx, &data_start_copy, frame_size, user_priv, | 496 res = decode_one(ctx, &data_start_copy, frame_size, user_priv, |
| 422 deadline); | 497 deadline); |
| 423 if (res != VPX_CODEC_OK) | 498 if (res != VPX_CODEC_OK) |
| 424 return res; | 499 return res; |
| 425 | 500 |
| 426 data_start += frame_size; | 501 data_start += frame_size; |
| 427 } | 502 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 447 | 522 |
| 448 return VPX_CODEC_OK; | 523 return VPX_CODEC_OK; |
| 449 } | 524 } |
| 450 | 525 |
| 451 static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, | 526 static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, |
| 452 vpx_codec_iter_t *iter) { | 527 vpx_codec_iter_t *iter) { |
| 453 vpx_image_t *img = NULL; | 528 vpx_image_t *img = NULL; |
| 454 | 529 |
| 455 // iter acts as a flip flop, so an image is only returned on the first | 530 // iter acts as a flip flop, so an image is only returned on the first |
| 456 // call to get_frame. | 531 // call to get_frame. |
| 457 if (*iter == NULL && ctx->pbi != NULL) { | 532 if (*iter == NULL && ctx->frame_workers != NULL) { |
| 458 YV12_BUFFER_CONFIG sd; | 533 YV12_BUFFER_CONFIG sd; |
| 459 vp9_ppflags_t flags = {0, 0, 0}; | 534 vp9_ppflags_t flags = {0, 0, 0}; |
| 460 | 535 |
| 461 if (vp9_get_raw_frame(ctx->pbi, &sd, &flags) == 0) { | 536 VP9Worker *const worker = &ctx->frame_workers[ctx->next_output_thread_id]; |
| 462 VP9_COMMON *cm = &ctx->pbi->common; | 537 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 538 if (vp9_get_raw_frame(worker_data->pbi, &sd, &flags) == 0) { |
| 539 VP9_COMMON *const cm = &worker_data->pbi->common; |
| 463 yuvconfig2image(&ctx->img, &sd, NULL); | 540 yuvconfig2image(&ctx->img, &sd, NULL); |
| 464 ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; | 541 ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; |
| 465 img = &ctx->img; | 542 img = &ctx->img; |
| 466 *iter = img; | 543 *iter = img; |
| 467 // Decrease reference count of last output frame in frame parallel mode. | 544 // Decrease reference count of last output frame in frame parallel mode. |
| 468 if (ctx->frame_parallel_decode && ctx->last_show_frame >= 0) { | 545 if (ctx->frame_parallel_decode && ctx->last_show_frame >= 0) { |
| 469 --cm->frame_bufs[ctx->last_show_frame].ref_count; | 546 --cm->frame_bufs[ctx->last_show_frame].ref_count; |
| 470 if (cm->frame_bufs[ctx->last_show_frame].ref_count == 0) { | 547 if (cm->frame_bufs[ctx->last_show_frame].ref_count == 0) { |
| 471 cm->release_fb_cb(cm->cb_priv, | 548 cm->release_fb_cb(cm->cb_priv, |
| 472 &cm->frame_bufs[ctx->last_show_frame].raw_frame_buffer); | 549 &cm->frame_bufs[ctx->last_show_frame].raw_frame_buffer); |
| 473 } | 550 } |
| 474 } | 551 } |
| 475 ctx->last_show_frame = ctx->pbi->common.new_fb_idx; | 552 ctx->last_show_frame = worker_data->pbi->common.new_fb_idx; |
| 476 } | 553 } |
| 477 } | 554 } |
| 478 | 555 |
| 479 return img; | 556 return img; |
| 480 } | 557 } |
| 481 | 558 |
| 482 static vpx_codec_err_t decoder_set_fb_fn( | 559 static vpx_codec_err_t decoder_set_fb_fn( |
| 483 vpx_codec_alg_priv_t *ctx, | 560 vpx_codec_alg_priv_t *ctx, |
| 484 vpx_get_frame_buffer_cb_fn_t cb_get, | 561 vpx_get_frame_buffer_cb_fn_t cb_get, |
| 485 vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) { | 562 vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) { |
| 486 if (cb_get == NULL || cb_release == NULL) { | 563 if (cb_get == NULL || cb_release == NULL) { |
| 487 return VPX_CODEC_INVALID_PARAM; | 564 return VPX_CODEC_INVALID_PARAM; |
| 488 } else if (ctx->pbi == NULL) { | 565 } else if (ctx->frame_workers == NULL) { |
| 489 // If the decoder has already been initialized, do not accept changes to | 566 // If the decoder has already been initialized, do not accept changes to |
| 490 // the frame buffer functions. | 567 // the frame buffer functions. |
| 491 ctx->get_ext_fb_cb = cb_get; | 568 ctx->get_ext_fb_cb = cb_get; |
| 492 ctx->release_ext_fb_cb = cb_release; | 569 ctx->release_ext_fb_cb = cb_release; |
| 493 ctx->ext_priv = cb_priv; | 570 ctx->ext_priv = cb_priv; |
| 494 return VPX_CODEC_OK; | 571 return VPX_CODEC_OK; |
| 495 } | 572 } |
| 496 | 573 |
| 497 return VPX_CODEC_ERROR; | 574 return VPX_CODEC_ERROR; |
| 498 } | 575 } |
| 499 | 576 |
| 500 static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, | 577 static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, |
| 501 va_list args) { | 578 va_list args) { |
| 502 vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *); | 579 vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *); |
| 503 | 580 |
| 581 // Only support this function in serial decode. |
| 582 if (ctx->frame_parallel_decode) { |
| 583 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 584 return VPX_CODEC_INCAPABLE; |
| 585 } |
| 586 |
| 504 if (data) { | 587 if (data) { |
| 505 vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data; | 588 vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data; |
| 506 YV12_BUFFER_CONFIG sd; | 589 YV12_BUFFER_CONFIG sd; |
| 507 | 590 VP9Worker *const worker = ctx->frame_workers; |
| 591 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 508 image2yuvconfig(&frame->img, &sd); | 592 image2yuvconfig(&frame->img, &sd); |
| 509 return vp9_set_reference_dec(&ctx->pbi->common, | 593 return vp9_set_reference_dec(&worker_data->pbi->common, |
| 510 (VP9_REFFRAME)frame->frame_type, &sd); | 594 (VP9_REFFRAME)frame->frame_type, &sd); |
| 511 } else { | 595 } else { |
| 512 return VPX_CODEC_INVALID_PARAM; | 596 return VPX_CODEC_INVALID_PARAM; |
| 513 } | 597 } |
| 514 } | 598 } |
| 515 | 599 |
| 516 static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, | 600 static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, |
| 517 va_list args) { | 601 va_list args) { |
| 518 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); | 602 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); |
| 519 | 603 |
| 604 // Only support this function in serial decode. |
| 605 if (ctx->frame_parallel_decode) { |
| 606 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 607 return VPX_CODEC_INCAPABLE; |
| 608 } |
| 609 |
| 520 if (data) { | 610 if (data) { |
| 521 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; | 611 vpx_ref_frame_t *frame = (vpx_ref_frame_t *) data; |
| 522 YV12_BUFFER_CONFIG sd; | 612 YV12_BUFFER_CONFIG sd; |
| 523 | 613 VP9Worker *const worker = ctx->frame_workers; |
| 614 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 524 image2yuvconfig(&frame->img, &sd); | 615 image2yuvconfig(&frame->img, &sd); |
| 525 | 616 return vp9_copy_reference_dec(worker_data->pbi, |
| 526 return vp9_copy_reference_dec(ctx->pbi, | |
| 527 (VP9_REFFRAME)frame->frame_type, &sd); | 617 (VP9_REFFRAME)frame->frame_type, &sd); |
| 528 } else { | 618 } else { |
| 529 return VPX_CODEC_INVALID_PARAM; | 619 return VPX_CODEC_INVALID_PARAM; |
| 530 } | 620 } |
| 531 } | 621 } |
| 532 | 622 |
| 533 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, | 623 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, |
| 534 va_list args) { | 624 va_list args) { |
| 535 vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *); | 625 vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *); |
| 536 | 626 |
| 627 // Only support this function in serial decode. |
| 628 if (ctx->frame_parallel_decode) { |
| 629 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 630 return VPX_CODEC_INCAPABLE; |
| 631 } |
| 632 |
| 537 if (data) { | 633 if (data) { |
| 538 YV12_BUFFER_CONFIG* fb; | 634 YV12_BUFFER_CONFIG* fb; |
| 539 | 635 VP9Worker *const worker = ctx->frame_workers; |
| 540 vp9_get_reference_dec(ctx->pbi, data->idx, &fb); | 636 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 637 vp9_get_reference_dec(worker_data->pbi, data->idx, &fb); |
| 541 yuvconfig2image(&data->img, fb, NULL); | 638 yuvconfig2image(&data->img, fb, NULL); |
| 542 return VPX_CODEC_OK; | 639 return VPX_CODEC_OK; |
| 543 } else { | 640 } else { |
| 544 return VPX_CODEC_INVALID_PARAM; | 641 return VPX_CODEC_INVALID_PARAM; |
| 545 } | 642 } |
| 546 } | 643 } |
| 547 | 644 |
| 548 static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx, | 645 static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx, |
| 549 va_list args) { | 646 va_list args) { |
| 550 #if CONFIG_VP9_POSTPROC | 647 #if CONFIG_VP9_POSTPROC |
| (...skipping 17 matching lines...) Expand all Loading... |
| 568 va_list args) { | 665 va_list args) { |
| 569 (void)ctx; | 666 (void)ctx; |
| 570 (void)args; | 667 (void)args; |
| 571 return VPX_CODEC_INCAPABLE; | 668 return VPX_CODEC_INCAPABLE; |
| 572 } | 669 } |
| 573 | 670 |
| 574 static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx, | 671 static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx, |
| 575 va_list args) { | 672 va_list args) { |
| 576 int *const update_info = va_arg(args, int *); | 673 int *const update_info = va_arg(args, int *); |
| 577 | 674 |
| 675 // Only support this function in serial decode. |
| 676 if (ctx->frame_parallel_decode) { |
| 677 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 678 return VPX_CODEC_INCAPABLE; |
| 679 } |
| 680 |
| 578 if (update_info) { | 681 if (update_info) { |
| 579 if (ctx->pbi) | 682 if (ctx->frame_workers) { |
| 580 *update_info = ctx->pbi->refresh_frame_flags; | 683 VP9Worker *const worker = ctx->frame_workers; |
| 581 else | 684 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 685 *update_info = worker_data->pbi->refresh_frame_flags; |
| 686 } else { |
| 582 return VPX_CODEC_ERROR; | 687 return VPX_CODEC_ERROR; |
| 688 } |
| 583 return VPX_CODEC_OK; | 689 return VPX_CODEC_OK; |
| 584 } else { | 690 } else { |
| 585 return VPX_CODEC_INVALID_PARAM; | 691 return VPX_CODEC_INVALID_PARAM; |
| 586 } | 692 } |
| 587 } | 693 } |
| 588 | 694 |
| 589 | 695 |
| 590 static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, | 696 static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, |
| 591 va_list args) { | 697 va_list args) { |
| 592 int *corrupted = va_arg(args, int *); | 698 int *corrupted = va_arg(args, int *); |
| 593 | 699 |
| 700 // Only support this function in serial decode. |
| 701 if (ctx->frame_parallel_decode) { |
| 702 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 703 return VPX_CODEC_INCAPABLE; |
| 704 } |
| 705 |
| 594 if (corrupted) { | 706 if (corrupted) { |
| 595 if (ctx->pbi) | 707 if (ctx->frame_workers) { |
| 596 *corrupted = ctx->pbi->common.frame_to_show->corrupted; | 708 VP9Worker *const worker = ctx->frame_workers; |
| 597 else | 709 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 710 *corrupted = worker_data->pbi->common.frame_to_show->corrupted; |
| 711 } else { |
| 598 return VPX_CODEC_ERROR; | 712 return VPX_CODEC_ERROR; |
| 713 } |
| 599 return VPX_CODEC_OK; | 714 return VPX_CODEC_OK; |
| 600 } else { | 715 } else { |
| 601 return VPX_CODEC_INVALID_PARAM; | 716 return VPX_CODEC_INVALID_PARAM; |
| 602 } | 717 } |
| 603 } | 718 } |
| 604 | 719 |
| 605 static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx, | 720 static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx, |
| 606 va_list args) { | 721 va_list args) { |
| 607 int *const display_size = va_arg(args, int *); | 722 int *const display_size = va_arg(args, int *); |
| 608 | 723 |
| 724 // Only support this function in serial decode. |
| 725 if (ctx->frame_parallel_decode) { |
| 726 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 727 return VPX_CODEC_INCAPABLE; |
| 728 } |
| 729 |
| 609 if (display_size) { | 730 if (display_size) { |
| 610 if (ctx->pbi) { | 731 if (ctx->frame_workers) { |
| 611 const VP9_COMMON *const cm = &ctx->pbi->common; | 732 VP9Worker *const worker = ctx->frame_workers; |
| 733 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 734 const VP9_COMMON *const cm = &worker_data->pbi->common; |
| 612 display_size[0] = cm->display_width; | 735 display_size[0] = cm->display_width; |
| 613 display_size[1] = cm->display_height; | 736 display_size[1] = cm->display_height; |
| 614 } else { | 737 } else { |
| 615 return VPX_CODEC_ERROR; | 738 return VPX_CODEC_ERROR; |
| 616 } | 739 } |
| 617 return VPX_CODEC_OK; | 740 return VPX_CODEC_OK; |
| 618 } else { | 741 } else { |
| 619 return VPX_CODEC_INVALID_PARAM; | 742 return VPX_CODEC_INVALID_PARAM; |
| 620 } | 743 } |
| 621 } | 744 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 { // NOLINT | 802 { // NOLINT |
| 680 NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t | 803 NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t |
| 681 NOT_IMPLEMENTED, // vpx_codec_encode_fn_t | 804 NOT_IMPLEMENTED, // vpx_codec_encode_fn_t |
| 682 NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t | 805 NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t |
| 683 NOT_IMPLEMENTED, // vpx_codec_enc_config_set_fn_t | 806 NOT_IMPLEMENTED, // vpx_codec_enc_config_set_fn_t |
| 684 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t | 807 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t |
| 685 NOT_IMPLEMENTED, // vpx_codec_get_preview_frame_fn_t | 808 NOT_IMPLEMENTED, // vpx_codec_get_preview_frame_fn_t |
| 686 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t | 809 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t |
| 687 } | 810 } |
| 688 }; | 811 }; |
| OLD | NEW |