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 |