| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 59 |
| 60 if (!ctx->priv) { | 60 if (!ctx->priv) { |
| 61 vpx_codec_alg_priv_t *alg_priv = vpx_memalign(32, sizeof(*alg_priv)); | 61 vpx_codec_alg_priv_t *alg_priv = vpx_memalign(32, sizeof(*alg_priv)); |
| 62 if (alg_priv == NULL) | 62 if (alg_priv == NULL) |
| 63 return VPX_CODEC_MEM_ERROR; | 63 return VPX_CODEC_MEM_ERROR; |
| 64 | 64 |
| 65 vp9_zero(*alg_priv); | 65 vp9_zero(*alg_priv); |
| 66 | 66 |
| 67 ctx->priv = (vpx_codec_priv_t *)alg_priv; | 67 ctx->priv = (vpx_codec_priv_t *)alg_priv; |
| 68 ctx->priv->sz = sizeof(*ctx->priv); | 68 ctx->priv->sz = sizeof(*ctx->priv); |
| 69 ctx->priv->iface = ctx->iface; | |
| 70 ctx->priv->alg_priv = alg_priv; | 69 ctx->priv->alg_priv = alg_priv; |
| 71 ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si); | 70 ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si); |
| 72 ctx->priv->init_flags = ctx->init_flags; | 71 ctx->priv->init_flags = ctx->init_flags; |
| 73 ctx->priv->alg_priv->flushed = 0; | 72 ctx->priv->alg_priv->flushed = 0; |
| 74 ctx->priv->alg_priv->frame_parallel_decode = | 73 ctx->priv->alg_priv->frame_parallel_decode = |
| 75 (ctx->init_flags & VPX_CODEC_USE_FRAME_THREADING); | 74 (ctx->init_flags & VPX_CODEC_USE_FRAME_THREADING); |
| 76 | 75 |
| 77 // Disable frame parallel decoding for now. | 76 // Disable frame parallel decoding for now. |
| 78 ctx->priv->alg_priv->frame_parallel_decode = 0; | 77 ctx->priv->alg_priv->frame_parallel_decode = 0; |
| 79 | 78 |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 if (vp9_get_raw_frame(ctx->pbi, &sd, &flags)) | 324 if (vp9_get_raw_frame(ctx->pbi, &sd, &flags)) |
| 326 return update_error_state(ctx, &cm->error); | 325 return update_error_state(ctx, &cm->error); |
| 327 | 326 |
| 328 yuvconfig2image(&ctx->img, &sd, user_priv); | 327 yuvconfig2image(&ctx->img, &sd, user_priv); |
| 329 ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; | 328 ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; |
| 330 ctx->img_avail = 1; | 329 ctx->img_avail = 1; |
| 331 | 330 |
| 332 return VPX_CODEC_OK; | 331 return VPX_CODEC_OK; |
| 333 } | 332 } |
| 334 | 333 |
| 335 static INLINE uint8_t read_marker(vpx_decrypt_cb decrypt_cb, | |
| 336 void *decrypt_state, | |
| 337 const uint8_t *data) { | |
| 338 if (decrypt_cb) { | |
| 339 uint8_t marker; | |
| 340 decrypt_cb(decrypt_state, data, &marker, 1); | |
| 341 return marker; | |
| 342 } | |
| 343 return *data; | |
| 344 } | |
| 345 | |
| 346 static vpx_codec_err_t parse_superframe_index(const uint8_t *data, | |
| 347 size_t data_sz, | |
| 348 uint32_t sizes[8], int *count, | |
| 349 vpx_decrypt_cb decrypt_cb, | |
| 350 void *decrypt_state) { | |
| 351 // A chunk ending with a byte matching 0xc0 is an invalid chunk unless | |
| 352 // it is a super frame index. If the last byte of real video compression | |
| 353 // data is 0xc0 the encoder must add a 0 byte. If we have the marker but | |
| 354 // not the associated matching marker byte at the front of the index we have | |
| 355 // an invalid bitstream and need to return an error. | |
| 356 | |
| 357 uint8_t marker; | |
| 358 | |
| 359 assert(data_sz); | |
| 360 marker = read_marker(decrypt_cb, decrypt_state, data + data_sz - 1); | |
| 361 *count = 0; | |
| 362 | |
| 363 if ((marker & 0xe0) == 0xc0) { | |
| 364 const uint32_t frames = (marker & 0x7) + 1; | |
| 365 const uint32_t mag = ((marker >> 3) & 0x3) + 1; | |
| 366 const size_t index_sz = 2 + mag * frames; | |
| 367 | |
| 368 // This chunk is marked as having a superframe index but doesn't have | |
| 369 // enough data for it, thus it's an invalid superframe index. | |
| 370 if (data_sz < index_sz) | |
| 371 return VPX_CODEC_CORRUPT_FRAME; | |
| 372 | |
| 373 { | |
| 374 const uint8_t marker2 = read_marker(decrypt_cb, decrypt_state, | |
| 375 data + data_sz - index_sz); | |
| 376 | |
| 377 // This chunk is marked as having a superframe index but doesn't have | |
| 378 // the matching marker byte at the front of the index therefore it's an | |
| 379 // invalid chunk. | |
| 380 if (marker != marker2) | |
| 381 return VPX_CODEC_CORRUPT_FRAME; | |
| 382 } | |
| 383 | |
| 384 { | |
| 385 // Found a valid superframe index. | |
| 386 uint32_t i, j; | |
| 387 const uint8_t *x = &data[data_sz - index_sz + 1]; | |
| 388 | |
| 389 // Frames has a maximum of 8 and mag has a maximum of 4. | |
| 390 uint8_t clear_buffer[32]; | |
| 391 assert(sizeof(clear_buffer) >= frames * mag); | |
| 392 if (decrypt_cb) { | |
| 393 decrypt_cb(decrypt_state, x, clear_buffer, frames * mag); | |
| 394 x = clear_buffer; | |
| 395 } | |
| 396 | |
| 397 for (i = 0; i < frames; ++i) { | |
| 398 uint32_t this_sz = 0; | |
| 399 | |
| 400 for (j = 0; j < mag; ++j) | |
| 401 this_sz |= (*x++) << (j * 8); | |
| 402 sizes[i] = this_sz; | |
| 403 } | |
| 404 *count = frames; | |
| 405 } | |
| 406 } | |
| 407 return VPX_CODEC_OK; | |
| 408 } | |
| 409 | |
| 410 static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, | 334 static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, |
| 411 const uint8_t *data, unsigned int data_sz, | 335 const uint8_t *data, unsigned int data_sz, |
| 412 void *user_priv, long deadline) { | 336 void *user_priv, long deadline) { |
| 413 const uint8_t *data_start = data; | 337 const uint8_t *data_start = data; |
| 414 const uint8_t * const data_end = data + data_sz; | 338 const uint8_t * const data_end = data + data_sz; |
| 415 vpx_codec_err_t res; | 339 vpx_codec_err_t res; |
| 416 uint32_t frame_sizes[8]; | 340 uint32_t frame_sizes[8]; |
| 417 int frame_count; | 341 int frame_count; |
| 418 | 342 |
| 419 if (data == NULL && data_sz == 0) { | 343 if (data == NULL && data_sz == 0) { |
| 420 ctx->flushed = 1; | 344 ctx->flushed = 1; |
| 421 return VPX_CODEC_OK; | 345 return VPX_CODEC_OK; |
| 422 } | 346 } |
| 423 | 347 |
| 424 // Reset flushed when receiving a valid frame. | 348 // Reset flushed when receiving a valid frame. |
| 425 ctx->flushed = 0; | 349 ctx->flushed = 0; |
| 426 | 350 |
| 427 res = parse_superframe_index(data, data_sz, frame_sizes, &frame_count, | 351 res = vp9_parse_superframe_index(data, data_sz, frame_sizes, &frame_count, |
| 428 ctx->decrypt_cb, ctx->decrypt_state); | 352 ctx->decrypt_cb, ctx->decrypt_state); |
| 429 if (res != VPX_CODEC_OK) | 353 if (res != VPX_CODEC_OK) |
| 430 return res; | 354 return res; |
| 431 | 355 |
| 432 if (ctx->frame_parallel_decode) { | 356 if (ctx->frame_parallel_decode) { |
| 433 // Decode in frame parallel mode. When decoding in this mode, the frame | 357 // Decode in frame parallel mode. When decoding in this mode, the frame |
| 434 // passed to the decoder must be either a normal frame or a superframe with | 358 // passed to the decoder must be either a normal frame or a superframe with |
| 435 // superframe index so the decoder could get each frame's start position | 359 // superframe index so the decoder could get each frame's start position |
| 436 // in the superframe. | 360 // in the superframe. |
| 437 if (frame_count > 0) { | 361 if (frame_count > 0) { |
| 438 int i; | 362 int i; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 0, | 649 0, |
| 726 NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t | 650 NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t |
| 727 NOT_IMPLEMENTED, // vpx_codec_encode_fn_t | 651 NOT_IMPLEMENTED, // vpx_codec_encode_fn_t |
| 728 NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t | 652 NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t |
| 729 NOT_IMPLEMENTED, // vpx_codec_enc_config_set_fn_t | 653 NOT_IMPLEMENTED, // vpx_codec_enc_config_set_fn_t |
| 730 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t | 654 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t |
| 731 NOT_IMPLEMENTED, // vpx_codec_get_preview_frame_fn_t | 655 NOT_IMPLEMENTED, // vpx_codec_get_preview_frame_fn_t |
| 732 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t | 656 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t |
| 733 } | 657 } |
| 734 }; | 658 }; |
| OLD | NEW |