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 |