| 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 20 matching lines...) Expand all Loading... |
| 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; | 35 struct VP9Decoder *pbi; |
| 36 int postproc_cfg_set; | 36 int postproc_cfg_set; |
| 37 vp8_postproc_cfg_t postproc_cfg; | 37 vp8_postproc_cfg_t postproc_cfg; |
| 38 vpx_decrypt_cb decrypt_cb; | 38 vpx_decrypt_cb decrypt_cb; |
| 39 void *decrypt_state; | 39 void *decrypt_state; |
| 40 vpx_image_t img; | 40 vpx_image_t img; |
| 41 int img_avail; | |
| 42 int invert_tile_order; | 41 int invert_tile_order; |
| 42 int frame_parallel_decode; // frame-based threading. |
| 43 int last_show_frame; // Index of last output frame. |
| 43 | 44 |
| 44 // External frame buffer info to save for VP9 common. | 45 // External frame buffer info to save for VP9 common. |
| 45 void *ext_priv; // Private data associated with the external frame buffers. | 46 void *ext_priv; // Private data associated with the external frame buffers. |
| 46 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; | 47 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; |
| 47 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; | 48 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; |
| 48 }; | 49 }; |
| 49 | 50 |
| 50 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, | 51 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, |
| 51 vpx_codec_priv_enc_mr_cfg_t *data) { | 52 vpx_codec_priv_enc_mr_cfg_t *data) { |
| 52 // This function only allocates space for the vpx_codec_alg_priv_t | 53 // This function only allocates space for the vpx_codec_alg_priv_t |
| 53 // structure. More memory may be required at the time the stream | 54 // structure. More memory may be required at the time the stream |
| 54 // information becomes known. | 55 // information becomes known. |
| 56 (void)data; |
| 57 |
| 55 if (!ctx->priv) { | 58 if (!ctx->priv) { |
| 56 vpx_codec_alg_priv_t *alg_priv = vpx_memalign(32, sizeof(*alg_priv)); | 59 vpx_codec_alg_priv_t *alg_priv = vpx_memalign(32, sizeof(*alg_priv)); |
| 57 if (alg_priv == NULL) | 60 if (alg_priv == NULL) |
| 58 return VPX_CODEC_MEM_ERROR; | 61 return VPX_CODEC_MEM_ERROR; |
| 59 | 62 |
| 60 vp9_zero(*alg_priv); | 63 vp9_zero(*alg_priv); |
| 61 | 64 |
| 62 ctx->priv = (vpx_codec_priv_t *)alg_priv; | 65 ctx->priv = (vpx_codec_priv_t *)alg_priv; |
| 63 ctx->priv->sz = sizeof(*ctx->priv); | 66 ctx->priv->sz = sizeof(*ctx->priv); |
| 64 ctx->priv->iface = ctx->iface; | 67 ctx->priv->iface = ctx->iface; |
| 65 ctx->priv->alg_priv = alg_priv; | 68 ctx->priv->alg_priv = alg_priv; |
| 66 ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si); | 69 ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si); |
| 67 ctx->priv->init_flags = ctx->init_flags; | 70 ctx->priv->init_flags = ctx->init_flags; |
| 71 ctx->priv->alg_priv->frame_parallel_decode = |
| 72 (ctx->init_flags & VPX_CODEC_USE_FRAME_THREADING); |
| 73 |
| 74 // Disable frame parallel decoding for now. |
| 75 ctx->priv->alg_priv->frame_parallel_decode = 0; |
| 68 | 76 |
| 69 if (ctx->config.dec) { | 77 if (ctx->config.dec) { |
| 70 // Update the reference to the config structure to an internal copy. | 78 // Update the reference to the config structure to an internal copy. |
| 71 ctx->priv->alg_priv->cfg = *ctx->config.dec; | 79 ctx->priv->alg_priv->cfg = *ctx->config.dec; |
| 72 ctx->config.dec = &ctx->priv->alg_priv->cfg; | 80 ctx->config.dec = &ctx->priv->alg_priv->cfg; |
| 73 } | 81 } |
| 74 } | 82 } |
| 75 | 83 |
| 76 return VPX_CODEC_OK; | 84 return VPX_CODEC_OK; |
| 77 } | 85 } |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 flags->noise_level = ctx->postproc_cfg.noise_level; | 231 flags->noise_level = ctx->postproc_cfg.noise_level; |
| 224 } | 232 } |
| 225 | 233 |
| 226 static void init_decoder(vpx_codec_alg_priv_t *ctx) { | 234 static void init_decoder(vpx_codec_alg_priv_t *ctx) { |
| 227 ctx->pbi = vp9_decoder_create(); | 235 ctx->pbi = vp9_decoder_create(); |
| 228 if (ctx->pbi == NULL) | 236 if (ctx->pbi == NULL) |
| 229 return; | 237 return; |
| 230 | 238 |
| 231 ctx->pbi->max_threads = ctx->cfg.threads; | 239 ctx->pbi->max_threads = ctx->cfg.threads; |
| 232 ctx->pbi->inv_tile_order = ctx->invert_tile_order; | 240 ctx->pbi->inv_tile_order = ctx->invert_tile_order; |
| 233 | 241 ctx->pbi->frame_parallel_decode = ctx->frame_parallel_decode; |
| 234 vp9_initialize_dec(); | 242 ctx->last_show_frame = -1; |
| 235 | 243 |
| 236 // If postprocessing was enabled by the application and a | 244 // If postprocessing was enabled by the application and a |
| 237 // configuration has not been provided, default it. | 245 // configuration has not been provided, default it. |
| 238 if (!ctx->postproc_cfg_set && | 246 if (!ctx->postproc_cfg_set && |
| 239 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) | 247 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) |
| 240 set_default_ppflags(&ctx->postproc_cfg); | 248 set_default_ppflags(&ctx->postproc_cfg); |
| 241 | 249 |
| 242 init_buffer_callbacks(ctx); | 250 init_buffer_callbacks(ctx); |
| 243 } | 251 } |
| 244 | 252 |
| 245 static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx, | 253 static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx, |
| 246 const uint8_t **data, unsigned int data_sz, | 254 const uint8_t **data, unsigned int data_sz, |
| 247 void *user_priv, int64_t deadline) { | 255 void *user_priv, int64_t deadline) { |
| 248 YV12_BUFFER_CONFIG sd = { 0 }; | |
| 249 int64_t time_stamp = 0, time_end_stamp = 0; | |
| 250 vp9_ppflags_t flags = {0}; | 256 vp9_ppflags_t flags = {0}; |
| 251 VP9_COMMON *cm = NULL; | 257 VP9_COMMON *cm = NULL; |
| 252 | 258 |
| 253 ctx->img_avail = 0; | 259 (void)deadline; |
| 254 | 260 |
| 255 // Determine the stream parameters. Note that we rely on peek_si to | 261 // Determine the stream parameters. Note that we rely on peek_si to |
| 256 // validate that we have a buffer that does not wrap around the top | 262 // validate that we have a buffer that does not wrap around the top |
| 257 // of the heap. | 263 // of the heap. |
| 258 if (!ctx->si.h) { | 264 if (!ctx->si.h) { |
| 259 const vpx_codec_err_t res = | 265 const vpx_codec_err_t res = |
| 260 decoder_peek_si_internal(*data, data_sz, &ctx->si, ctx->decrypt_cb, | 266 decoder_peek_si_internal(*data, data_sz, &ctx->si, ctx->decrypt_cb, |
| 261 ctx->decrypt_state); | 267 ctx->decrypt_state); |
| 262 if (res != VPX_CODEC_OK) | 268 if (res != VPX_CODEC_OK) |
| 263 return res; | 269 return res; |
| 270 |
| 271 if (!ctx->si.is_kf) |
| 272 return VPX_CODEC_ERROR; |
| 264 } | 273 } |
| 265 | 274 |
| 266 // Initialize the decoder instance on the first frame | 275 // Initialize the decoder instance on the first frame |
| 267 if (ctx->pbi == NULL) { | 276 if (ctx->pbi == NULL) { |
| 268 init_decoder(ctx); | 277 init_decoder(ctx); |
| 269 if (ctx->pbi == NULL) | 278 if (ctx->pbi == NULL) |
| 270 return VPX_CODEC_ERROR; | 279 return VPX_CODEC_ERROR; |
| 271 } | 280 } |
| 272 | 281 |
| 273 // Set these even if already initialized. The caller may have changed the | 282 // Set these even if already initialized. The caller may have changed the |
| 274 // decrypt config between frames. | 283 // decrypt config between frames. |
| 275 ctx->pbi->decrypt_cb = ctx->decrypt_cb; | 284 ctx->pbi->decrypt_cb = ctx->decrypt_cb; |
| 276 ctx->pbi->decrypt_state = ctx->decrypt_state; | 285 ctx->pbi->decrypt_state = ctx->decrypt_state; |
| 277 | 286 |
| 278 cm = &ctx->pbi->common; | 287 cm = &ctx->pbi->common; |
| 279 | 288 |
| 280 if (vp9_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) | 289 if (vp9_receive_compressed_data(ctx->pbi, data_sz, data)) |
| 281 return update_error_state(ctx, &cm->error); | 290 return update_error_state(ctx, &cm->error); |
| 282 | 291 |
| 283 if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) | 292 if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) |
| 284 set_ppflags(ctx, &flags); | 293 set_ppflags(ctx, &flags); |
| 285 | 294 |
| 286 if (vp9_get_raw_frame(ctx->pbi, &sd, &time_stamp, &time_end_stamp, &flags)) | |
| 287 return update_error_state(ctx, &cm->error); | |
| 288 | |
| 289 yuvconfig2image(&ctx->img, &sd, user_priv); | |
| 290 ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; | |
| 291 ctx->img_avail = 1; | |
| 292 | |
| 293 return VPX_CODEC_OK; | 295 return VPX_CODEC_OK; |
| 294 } | 296 } |
| 295 | 297 |
| 296 static INLINE uint8_t read_marker(vpx_decrypt_cb decrypt_cb, | 298 static INLINE uint8_t read_marker(vpx_decrypt_cb decrypt_cb, |
| 297 void *decrypt_state, | 299 void *decrypt_state, |
| 298 const uint8_t *data) { | 300 const uint8_t *data) { |
| 299 if (decrypt_cb) { | 301 if (decrypt_cb) { |
| 300 uint8_t marker; | 302 uint8_t marker; |
| 301 decrypt_cb(decrypt_state, data, &marker, 1); | 303 decrypt_cb(decrypt_state, data, &marker, 1); |
| 302 return marker; | 304 return marker; |
| 303 } | 305 } |
| 304 return *data; | 306 return *data; |
| 305 } | 307 } |
| 306 | 308 |
| 307 static void parse_superframe_index(const uint8_t *data, size_t data_sz, | 309 static void parse_superframe_index(const uint8_t *data, size_t data_sz, |
| 308 uint32_t sizes[8], int *count, | 310 uint32_t sizes[8], int *count, |
| 309 vpx_decrypt_cb decrypt_cb, | 311 vpx_decrypt_cb decrypt_cb, |
| 310 void *decrypt_state) { | 312 void *decrypt_state) { |
| 311 uint8_t marker; | 313 uint8_t marker; |
| 312 | 314 |
| 313 assert(data_sz); | 315 assert(data_sz); |
| 314 marker = read_marker(decrypt_cb, decrypt_state, data + data_sz - 1); | 316 marker = read_marker(decrypt_cb, decrypt_state, data + data_sz - 1); |
| 315 *count = 0; | 317 *count = 0; |
| 316 | 318 |
| 317 if ((marker & 0xe0) == 0xc0) { | 319 if ((marker & 0xe0) == 0xc0) { |
| 318 const uint32_t frames = (marker & 0x7) + 1; | 320 const uint32_t frames = (marker & 0x7) + 1; |
| 319 const uint32_t mag = ((marker >> 3) & 0x3) + 1; | 321 const uint32_t mag = ((marker >> 3) & 0x3) + 1; |
| 320 const size_t index_sz = 2 + mag * frames; | 322 const size_t index_sz = 2 + mag * frames; |
| 321 | 323 |
| 322 uint8_t marker2 = read_marker(decrypt_cb, decrypt_state, | 324 if (data_sz >= index_sz) { |
| 323 data + data_sz - index_sz); | 325 uint8_t marker2 = read_marker(decrypt_cb, decrypt_state, |
| 326 data + data_sz - index_sz); |
| 324 | 327 |
| 325 if (data_sz >= index_sz && marker2 == marker) { | 328 if (marker == marker2) { |
| 326 // found a valid superframe index | 329 // Found a valid superframe index. |
| 327 uint32_t i, j; | 330 uint32_t i, j; |
| 328 const uint8_t *x = &data[data_sz - index_sz + 1]; | 331 const uint8_t *x = &data[data_sz - index_sz + 1]; |
| 329 | 332 |
| 330 // frames has a maximum of 8 and mag has a maximum of 4. | 333 // Frames has a maximum of 8 and mag has a maximum of 4. |
| 331 uint8_t clear_buffer[32]; | 334 uint8_t clear_buffer[32]; |
| 332 assert(sizeof(clear_buffer) >= frames * mag); | 335 assert(sizeof(clear_buffer) >= frames * mag); |
| 333 if (decrypt_cb) { | 336 if (decrypt_cb) { |
| 334 decrypt_cb(decrypt_state, x, clear_buffer, frames * mag); | 337 decrypt_cb(decrypt_state, x, clear_buffer, frames * mag); |
| 335 x = clear_buffer; | 338 x = clear_buffer; |
| 339 } |
| 340 |
| 341 for (i = 0; i < frames; ++i) { |
| 342 uint32_t this_sz = 0; |
| 343 |
| 344 for (j = 0; j < mag; ++j) |
| 345 this_sz |= (*x++) << (j * 8); |
| 346 sizes[i] = this_sz; |
| 347 } |
| 348 |
| 349 *count = frames; |
| 336 } | 350 } |
| 337 | |
| 338 for (i = 0; i < frames; i++) { | |
| 339 uint32_t this_sz = 0; | |
| 340 | |
| 341 for (j = 0; j < mag; j++) | |
| 342 this_sz |= (*x++) << (j * 8); | |
| 343 sizes[i] = this_sz; | |
| 344 } | |
| 345 | |
| 346 *count = frames; | |
| 347 } | 351 } |
| 348 } | 352 } |
| 349 } | 353 } |
| 350 | 354 |
| 351 static vpx_codec_err_t decode_one_iter(vpx_codec_alg_priv_t *ctx, | |
| 352 const uint8_t **data_start_ptr, | |
| 353 const uint8_t *data_end, | |
| 354 uint32_t frame_size, void *user_priv, | |
| 355 long deadline) { | |
| 356 const vpx_codec_err_t res = decode_one(ctx, data_start_ptr, frame_size, | |
| 357 user_priv, deadline); | |
| 358 if (res != VPX_CODEC_OK) | |
| 359 return res; | |
| 360 | |
| 361 // Account for suboptimal termination by the encoder. | |
| 362 while (*data_start_ptr < data_end) { | |
| 363 const uint8_t marker = read_marker(ctx->decrypt_cb, ctx->decrypt_state, | |
| 364 *data_start_ptr); | |
| 365 if (marker) | |
| 366 break; | |
| 367 (*data_start_ptr)++; | |
| 368 } | |
| 369 | |
| 370 return VPX_CODEC_OK; | |
| 371 } | |
| 372 | |
| 373 static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, | 355 static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, |
| 374 const uint8_t *data, unsigned int data_sz, | 356 const uint8_t *data, unsigned int data_sz, |
| 375 void *user_priv, long deadline) { | 357 void *user_priv, long deadline) { |
| 376 const uint8_t *data_start = data; | 358 const uint8_t *data_start = data; |
| 377 const uint8_t *const data_end = data + data_sz; | 359 const uint8_t * const data_end = data + data_sz; |
| 378 vpx_codec_err_t res; | 360 vpx_codec_err_t res; |
| 379 uint32_t frame_sizes[8]; | 361 uint32_t frame_sizes[8]; |
| 380 int frame_count; | 362 int frame_count; |
| 381 | 363 |
| 382 if (data == NULL || data_sz == 0) | 364 if (data == NULL || data_sz == 0) |
| 383 return VPX_CODEC_INVALID_PARAM; | 365 return VPX_CODEC_INVALID_PARAM; |
| 384 | 366 |
| 385 parse_superframe_index(data, data_sz, frame_sizes, &frame_count, | 367 parse_superframe_index(data, data_sz, frame_sizes, &frame_count, |
| 386 ctx->decrypt_cb, ctx->decrypt_state); | 368 ctx->decrypt_cb, ctx->decrypt_state); |
| 387 | 369 |
| 388 if (frame_count > 0) { | 370 if (ctx->frame_parallel_decode) { |
| 389 int i; | 371 // Decode in frame parallel mode. When decoding in this mode, the frame |
| 372 // passed to the decoder must be either a normal frame or a superframe with |
| 373 // superframe index so the decoder could get each frame's start position |
| 374 // in the superframe. |
| 375 if (frame_count > 0) { |
| 376 int i; |
| 390 | 377 |
| 391 for (i = 0; i < frame_count; ++i) { | 378 for (i = 0; i < frame_count; ++i) { |
| 392 const uint32_t frame_size = frame_sizes[i]; | 379 const uint8_t *data_start_copy = data_start; |
| 393 if (data_start < data || | 380 const uint32_t frame_size = frame_sizes[i]; |
| 394 frame_size > (uint32_t)(data_end - data_start)) { | 381 vpx_codec_err_t res; |
| 395 ctx->base.err_detail = "Invalid frame size in index"; | 382 if (data_start < data |
| 396 return VPX_CODEC_CORRUPT_FRAME; | 383 || frame_size > (uint32_t) (data_end - data_start)) { |
| 384 ctx->base.err_detail = "Invalid frame size in index"; |
| 385 return VPX_CODEC_CORRUPT_FRAME; |
| 386 } |
| 387 |
| 388 res = decode_one(ctx, &data_start_copy, frame_size, user_priv, |
| 389 deadline); |
| 390 if (res != VPX_CODEC_OK) |
| 391 return res; |
| 392 |
| 393 data_start += frame_size; |
| 397 } | 394 } |
| 398 | 395 } else { |
| 399 res = decode_one_iter(ctx, &data_start, data_end, frame_size, | 396 res = decode_one(ctx, &data_start, data_sz, user_priv, deadline); |
| 400 user_priv, deadline); | |
| 401 if (res != VPX_CODEC_OK) | 397 if (res != VPX_CODEC_OK) |
| 402 return res; | 398 return res; |
| 399 |
| 400 // Extra data detected after the frame. |
| 401 if (data_start < data_end - 1) { |
| 402 ctx->base.err_detail = "Fail to decode frame in parallel mode"; |
| 403 return VPX_CODEC_INCAPABLE; |
| 404 } |
| 403 } | 405 } |
| 404 } else { | 406 } else { |
| 405 while (data_start < data_end) { | 407 // Decode in serial mode. |
| 406 res = decode_one_iter(ctx, &data_start, data_end, | 408 if (frame_count > 0) { |
| 407 (uint32_t)(data_end - data_start), | 409 int i; |
| 408 user_priv, deadline); | 410 |
| 409 if (res != VPX_CODEC_OK) | 411 for (i = 0; i < frame_count; ++i) { |
| 410 return res; | 412 const uint8_t *data_start_copy = data_start; |
| 413 const uint32_t frame_size = frame_sizes[i]; |
| 414 vpx_codec_err_t res; |
| 415 if (data_start < data |
| 416 || frame_size > (uint32_t) (data_end - data_start)) { |
| 417 ctx->base.err_detail = "Invalid frame size in index"; |
| 418 return VPX_CODEC_CORRUPT_FRAME; |
| 419 } |
| 420 |
| 421 res = decode_one(ctx, &data_start_copy, frame_size, user_priv, |
| 422 deadline); |
| 423 if (res != VPX_CODEC_OK) |
| 424 return res; |
| 425 |
| 426 data_start += frame_size; |
| 427 } |
| 428 } else { |
| 429 while (data_start < data_end) { |
| 430 const uint32_t frame_size = (uint32_t) (data_end - data_start); |
| 431 const vpx_codec_err_t res = decode_one(ctx, &data_start, frame_size, |
| 432 user_priv, deadline); |
| 433 if (res != VPX_CODEC_OK) |
| 434 return res; |
| 435 |
| 436 // Account for suboptimal termination by the encoder. |
| 437 while (data_start < data_end) { |
| 438 const uint8_t marker = read_marker(ctx->decrypt_cb, |
| 439 ctx->decrypt_state, data_start); |
| 440 if (marker) |
| 441 break; |
| 442 ++data_start; |
| 443 } |
| 444 } |
| 411 } | 445 } |
| 412 } | 446 } |
| 413 | 447 |
| 414 return VPX_CODEC_OK; | 448 return VPX_CODEC_OK; |
| 415 } | 449 } |
| 416 | 450 |
| 417 static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, | 451 static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, |
| 418 vpx_codec_iter_t *iter) { | 452 vpx_codec_iter_t *iter) { |
| 419 vpx_image_t *img = NULL; | 453 vpx_image_t *img = NULL; |
| 420 | 454 |
| 421 if (ctx->img_avail) { | 455 // iter acts as a flip flop, so an image is only returned on the first |
| 422 // iter acts as a flip flop, so an image is only returned on the first | 456 // call to get_frame. |
| 423 // call to get_frame. | 457 if (*iter == NULL && ctx->pbi != NULL) { |
| 424 if (!(*iter)) { | 458 YV12_BUFFER_CONFIG sd; |
| 459 vp9_ppflags_t flags = {0, 0, 0}; |
| 460 |
| 461 if (vp9_get_raw_frame(ctx->pbi, &sd, &flags) == 0) { |
| 462 VP9_COMMON *cm = &ctx->pbi->common; |
| 463 yuvconfig2image(&ctx->img, &sd, NULL); |
| 464 ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; |
| 425 img = &ctx->img; | 465 img = &ctx->img; |
| 426 *iter = img; | 466 *iter = img; |
| 467 // Decrease reference count of last output frame in frame parallel mode. |
| 468 if (ctx->frame_parallel_decode && ctx->last_show_frame >= 0) { |
| 469 --cm->frame_bufs[ctx->last_show_frame].ref_count; |
| 470 if (cm->frame_bufs[ctx->last_show_frame].ref_count == 0) { |
| 471 cm->release_fb_cb(cm->cb_priv, |
| 472 &cm->frame_bufs[ctx->last_show_frame].raw_frame_buffer); |
| 473 } |
| 474 } |
| 475 ctx->last_show_frame = ctx->pbi->common.new_fb_idx; |
| 427 } | 476 } |
| 428 } | 477 } |
| 429 ctx->img_avail = 0; | |
| 430 | 478 |
| 431 return img; | 479 return img; |
| 432 } | 480 } |
| 433 | 481 |
| 434 static vpx_codec_err_t decoder_set_fb_fn( | 482 static vpx_codec_err_t decoder_set_fb_fn( |
| 435 vpx_codec_alg_priv_t *ctx, | 483 vpx_codec_alg_priv_t *ctx, |
| 436 vpx_get_frame_buffer_cb_fn_t cb_get, | 484 vpx_get_frame_buffer_cb_fn_t cb_get, |
| 437 vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) { | 485 vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) { |
| 438 if (cb_get == NULL || cb_release == NULL) { | 486 if (cb_get == NULL || cb_release == NULL) { |
| 439 return VPX_CODEC_INVALID_PARAM; | 487 return VPX_CODEC_INVALID_PARAM; |
| 440 } else if (ctx->pbi == NULL) { | 488 } else if (ctx->pbi == NULL) { |
| 441 // If the decoder has already been initialized, do not accept changes to | 489 // If the decoder has already been initialized, do not accept changes to |
| 442 // the frame buffer functions. | 490 // the frame buffer functions. |
| 443 ctx->get_ext_fb_cb = cb_get; | 491 ctx->get_ext_fb_cb = cb_get; |
| 444 ctx->release_ext_fb_cb = cb_release; | 492 ctx->release_ext_fb_cb = cb_release; |
| 445 ctx->ext_priv = cb_priv; | 493 ctx->ext_priv = cb_priv; |
| 446 return VPX_CODEC_OK; | 494 return VPX_CODEC_OK; |
| 447 } | 495 } |
| 448 | 496 |
| 449 return VPX_CODEC_ERROR; | 497 return VPX_CODEC_ERROR; |
| 450 } | 498 } |
| 451 | 499 |
| 452 static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, | 500 static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, |
| 453 int ctr_id, va_list args) { | 501 va_list args) { |
| 454 vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *); | 502 vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *); |
| 455 | 503 |
| 456 if (data) { | 504 if (data) { |
| 457 vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data; | 505 vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data; |
| 458 YV12_BUFFER_CONFIG sd; | 506 YV12_BUFFER_CONFIG sd; |
| 459 | 507 |
| 460 image2yuvconfig(&frame->img, &sd); | 508 image2yuvconfig(&frame->img, &sd); |
| 461 return vp9_set_reference_dec(&ctx->pbi->common, | 509 return vp9_set_reference_dec(&ctx->pbi->common, |
| 462 (VP9_REFFRAME)frame->frame_type, &sd); | 510 (VP9_REFFRAME)frame->frame_type, &sd); |
| 463 } else { | 511 } else { |
| 464 return VPX_CODEC_INVALID_PARAM; | 512 return VPX_CODEC_INVALID_PARAM; |
| 465 } | 513 } |
| 466 } | 514 } |
| 467 | 515 |
| 468 static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, | 516 static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, |
| 469 int ctr_id, va_list args) { | 517 va_list args) { |
| 470 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); | 518 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); |
| 471 | 519 |
| 472 if (data) { | 520 if (data) { |
| 473 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; | 521 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; |
| 474 YV12_BUFFER_CONFIG sd; | 522 YV12_BUFFER_CONFIG sd; |
| 475 | 523 |
| 476 image2yuvconfig(&frame->img, &sd); | 524 image2yuvconfig(&frame->img, &sd); |
| 477 | 525 |
| 478 return vp9_copy_reference_dec(ctx->pbi, | 526 return vp9_copy_reference_dec(ctx->pbi, |
| 479 (VP9_REFFRAME)frame->frame_type, &sd); | 527 (VP9_REFFRAME)frame->frame_type, &sd); |
| 480 } else { | 528 } else { |
| 481 return VPX_CODEC_INVALID_PARAM; | 529 return VPX_CODEC_INVALID_PARAM; |
| 482 } | 530 } |
| 483 } | 531 } |
| 484 | 532 |
| 485 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, | 533 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, |
| 486 int ctr_id, va_list args) { | 534 va_list args) { |
| 487 vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *); | 535 vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *); |
| 488 | 536 |
| 489 if (data) { | 537 if (data) { |
| 490 YV12_BUFFER_CONFIG* fb; | 538 YV12_BUFFER_CONFIG* fb; |
| 491 | 539 |
| 492 vp9_get_reference_dec(ctx->pbi, data->idx, &fb); | 540 vp9_get_reference_dec(ctx->pbi, data->idx, &fb); |
| 493 yuvconfig2image(&data->img, fb, NULL); | 541 yuvconfig2image(&data->img, fb, NULL); |
| 494 return VPX_CODEC_OK; | 542 return VPX_CODEC_OK; |
| 495 } else { | 543 } else { |
| 496 return VPX_CODEC_INVALID_PARAM; | 544 return VPX_CODEC_INVALID_PARAM; |
| 497 } | 545 } |
| 498 } | 546 } |
| 499 | 547 |
| 500 static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx, | 548 static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx, |
| 501 int ctr_id, va_list args) { | 549 va_list args) { |
| 502 #if CONFIG_VP9_POSTPROC | 550 #if CONFIG_VP9_POSTPROC |
| 503 vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *); | 551 vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *); |
| 504 | 552 |
| 505 if (data) { | 553 if (data) { |
| 506 ctx->postproc_cfg_set = 1; | 554 ctx->postproc_cfg_set = 1; |
| 507 ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data); | 555 ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data); |
| 508 return VPX_CODEC_OK; | 556 return VPX_CODEC_OK; |
| 509 } else { | 557 } else { |
| 510 return VPX_CODEC_INVALID_PARAM; | 558 return VPX_CODEC_INVALID_PARAM; |
| 511 } | 559 } |
| 512 #else | 560 #else |
| 561 (void)ctx; |
| 562 (void)args; |
| 513 return VPX_CODEC_INCAPABLE; | 563 return VPX_CODEC_INCAPABLE; |
| 514 #endif | 564 #endif |
| 515 } | 565 } |
| 516 | 566 |
| 517 static vpx_codec_err_t ctrl_set_dbg_options(vpx_codec_alg_priv_t *ctx, | 567 static vpx_codec_err_t ctrl_set_dbg_options(vpx_codec_alg_priv_t *ctx, |
| 518 int ctrl_id, va_list args) { | 568 va_list args) { |
| 569 (void)ctx; |
| 570 (void)args; |
| 519 return VPX_CODEC_INCAPABLE; | 571 return VPX_CODEC_INCAPABLE; |
| 520 } | 572 } |
| 521 | 573 |
| 522 static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx, | 574 static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx, |
| 523 int ctrl_id, va_list args) { | 575 va_list args) { |
| 524 int *const update_info = va_arg(args, int *); | 576 int *const update_info = va_arg(args, int *); |
| 525 | 577 |
| 526 if (update_info) { | 578 if (update_info) { |
| 527 if (ctx->pbi) | 579 if (ctx->pbi) |
| 528 *update_info = ctx->pbi->refresh_frame_flags; | 580 *update_info = ctx->pbi->refresh_frame_flags; |
| 529 else | 581 else |
| 530 return VPX_CODEC_ERROR; | 582 return VPX_CODEC_ERROR; |
| 531 return VPX_CODEC_OK; | 583 return VPX_CODEC_OK; |
| 532 } else { | 584 } else { |
| 533 return VPX_CODEC_INVALID_PARAM; | 585 return VPX_CODEC_INVALID_PARAM; |
| 534 } | 586 } |
| 535 } | 587 } |
| 536 | 588 |
| 537 | 589 |
| 538 static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, | 590 static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, |
| 539 int ctrl_id, va_list args) { | 591 va_list args) { |
| 540 int *corrupted = va_arg(args, int *); | 592 int *corrupted = va_arg(args, int *); |
| 541 | 593 |
| 542 if (corrupted) { | 594 if (corrupted) { |
| 543 if (ctx->pbi) | 595 if (ctx->pbi) |
| 544 *corrupted = ctx->pbi->common.frame_to_show->corrupted; | 596 *corrupted = ctx->pbi->common.frame_to_show->corrupted; |
| 545 else | 597 else |
| 546 return VPX_CODEC_ERROR; | 598 return VPX_CODEC_ERROR; |
| 547 return VPX_CODEC_OK; | 599 return VPX_CODEC_OK; |
| 548 } else { | 600 } else { |
| 549 return VPX_CODEC_INVALID_PARAM; | 601 return VPX_CODEC_INVALID_PARAM; |
| 550 } | 602 } |
| 551 } | 603 } |
| 552 | 604 |
| 553 static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx, | 605 static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx, |
| 554 int ctrl_id, va_list args) { | 606 va_list args) { |
| 555 int *const display_size = va_arg(args, int *); | 607 int *const display_size = va_arg(args, int *); |
| 556 | 608 |
| 557 if (display_size) { | 609 if (display_size) { |
| 558 if (ctx->pbi) { | 610 if (ctx->pbi) { |
| 559 const VP9_COMMON *const cm = &ctx->pbi->common; | 611 const VP9_COMMON *const cm = &ctx->pbi->common; |
| 560 display_size[0] = cm->display_width; | 612 display_size[0] = cm->display_width; |
| 561 display_size[1] = cm->display_height; | 613 display_size[1] = cm->display_height; |
| 562 } else { | 614 } else { |
| 563 return VPX_CODEC_ERROR; | 615 return VPX_CODEC_ERROR; |
| 564 } | 616 } |
| 565 return VPX_CODEC_OK; | 617 return VPX_CODEC_OK; |
| 566 } else { | 618 } else { |
| 567 return VPX_CODEC_INVALID_PARAM; | 619 return VPX_CODEC_INVALID_PARAM; |
| 568 } | 620 } |
| 569 } | 621 } |
| 570 | 622 |
| 571 static vpx_codec_err_t ctrl_set_invert_tile_order(vpx_codec_alg_priv_t *ctx, | 623 static vpx_codec_err_t ctrl_set_invert_tile_order(vpx_codec_alg_priv_t *ctx, |
| 572 int ctr_id, va_list args) { | 624 va_list args) { |
| 573 ctx->invert_tile_order = va_arg(args, int); | 625 ctx->invert_tile_order = va_arg(args, int); |
| 574 return VPX_CODEC_OK; | 626 return VPX_CODEC_OK; |
| 575 } | 627 } |
| 576 | 628 |
| 577 static vpx_codec_err_t ctrl_set_decryptor(vpx_codec_alg_priv_t *ctx, | 629 static vpx_codec_err_t ctrl_set_decryptor(vpx_codec_alg_priv_t *ctx, |
| 578 int ctrl_id, | |
| 579 va_list args) { | 630 va_list args) { |
| 580 vpx_decrypt_init *init = va_arg(args, vpx_decrypt_init *); | 631 vpx_decrypt_init *init = va_arg(args, vpx_decrypt_init *); |
| 581 ctx->decrypt_cb = init ? init->decrypt_cb : NULL; | 632 ctx->decrypt_cb = init ? init->decrypt_cb : NULL; |
| 582 ctx->decrypt_state = init ? init->decrypt_state : NULL; | 633 ctx->decrypt_state = init ? init->decrypt_state : NULL; |
| 583 return VPX_CODEC_OK; | 634 return VPX_CODEC_OK; |
| 584 } | 635 } |
| 585 | 636 |
| 586 static vpx_codec_ctrl_fn_map_t decoder_ctrl_maps[] = { | 637 static vpx_codec_ctrl_fn_map_t decoder_ctrl_maps[] = { |
| 587 {VP8_COPY_REFERENCE, ctrl_copy_reference}, | 638 {VP8_COPY_REFERENCE, ctrl_copy_reference}, |
| 588 | 639 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 619 NOT_IMPLEMENTED, // vpx_codec_get_mmap_fn_t | 670 NOT_IMPLEMENTED, // vpx_codec_get_mmap_fn_t |
| 620 NOT_IMPLEMENTED, // vpx_codec_set_mmap_fn_t | 671 NOT_IMPLEMENTED, // vpx_codec_set_mmap_fn_t |
| 621 { // NOLINT | 672 { // NOLINT |
| 622 decoder_peek_si, // vpx_codec_peek_si_fn_t | 673 decoder_peek_si, // vpx_codec_peek_si_fn_t |
| 623 decoder_get_si, // vpx_codec_get_si_fn_t | 674 decoder_get_si, // vpx_codec_get_si_fn_t |
| 624 decoder_decode, // vpx_codec_decode_fn_t | 675 decoder_decode, // vpx_codec_decode_fn_t |
| 625 decoder_get_frame, // vpx_codec_frame_get_fn_t | 676 decoder_get_frame, // vpx_codec_frame_get_fn_t |
| 626 decoder_set_fb_fn, // vpx_codec_set_fb_fn_t | 677 decoder_set_fb_fn, // vpx_codec_set_fb_fn_t |
| 627 }, | 678 }, |
| 628 { // NOLINT | 679 { // NOLINT |
| 629 NOT_IMPLEMENTED, | 680 NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t |
| 630 NOT_IMPLEMENTED, | 681 NOT_IMPLEMENTED, // vpx_codec_encode_fn_t |
| 631 NOT_IMPLEMENTED, | 682 NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t |
| 632 NOT_IMPLEMENTED, | 683 NOT_IMPLEMENTED, // vpx_codec_enc_config_set_fn_t |
| 633 NOT_IMPLEMENTED, | 684 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t |
| 634 NOT_IMPLEMENTED | 685 NOT_IMPLEMENTED, // vpx_codec_get_preview_frame_fn_t |
| 686 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t |
| 635 } | 687 } |
| 636 }; | 688 }; |
| OLD | NEW |