| 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 11 matching lines...) Expand all Loading... |
| 22 #include "vpx_mem/vpx_mem.h" | 22 #include "vpx_mem/vpx_mem.h" |
| 23 #if CONFIG_ERROR_CONCEALMENT | 23 #if CONFIG_ERROR_CONCEALMENT |
| 24 #include "decoder/error_concealment.h" | 24 #include "decoder/error_concealment.h" |
| 25 #endif | 25 #endif |
| 26 #include "decoder/decoderthreading.h" | 26 #include "decoder/decoderthreading.h" |
| 27 | 27 |
| 28 #define VP8_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) | 28 #define VP8_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) |
| 29 #define VP8_CAP_ERROR_CONCEALMENT (CONFIG_ERROR_CONCEALMENT ? \ | 29 #define VP8_CAP_ERROR_CONCEALMENT (CONFIG_ERROR_CONCEALMENT ? \ |
| 30 VPX_CODEC_CAP_ERROR_CONCEALMENT : 0) | 30 VPX_CODEC_CAP_ERROR_CONCEALMENT : 0) |
| 31 | 31 |
| 32 #define VP8_DECRYPT_KEY_SIZE 32 |
| 33 |
| 32 typedef vpx_codec_stream_info_t vp8_stream_info_t; | 34 typedef vpx_codec_stream_info_t vp8_stream_info_t; |
| 33 | 35 |
| 34 /* Structures for handling memory allocations */ | 36 /* Structures for handling memory allocations */ |
| 35 typedef enum | 37 typedef enum |
| 36 { | 38 { |
| 37 VP8_SEG_ALG_PRIV = 256, | 39 VP8_SEG_ALG_PRIV = 256, |
| 38 VP8_SEG_MAX | 40 VP8_SEG_MAX |
| 39 } mem_seg_id_t; | 41 } mem_seg_id_t; |
| 40 #define NELEMENTS(x) ((int)(sizeof(x)/sizeof(x[0]))) | 42 #define NELEMENTS(x) ((int)(sizeof(x)/sizeof(x[0]))) |
| 41 | 43 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 66 int decoder_init; | 68 int decoder_init; |
| 67 int postproc_cfg_set; | 69 int postproc_cfg_set; |
| 68 vp8_postproc_cfg_t postproc_cfg; | 70 vp8_postproc_cfg_t postproc_cfg; |
| 69 #if CONFIG_POSTPROC_VISUALIZER | 71 #if CONFIG_POSTPROC_VISUALIZER |
| 70 unsigned int dbg_postproc_flag; | 72 unsigned int dbg_postproc_flag; |
| 71 int dbg_color_ref_frame_flag; | 73 int dbg_color_ref_frame_flag; |
| 72 int dbg_color_mb_modes_flag; | 74 int dbg_color_mb_modes_flag; |
| 73 int dbg_color_b_modes_flag; | 75 int dbg_color_b_modes_flag; |
| 74 int dbg_display_mv_flag; | 76 int dbg_display_mv_flag; |
| 75 #endif | 77 #endif |
| 78 unsigned char decrypt_key[VP8_DECRYPT_KEY_SIZE]; |
| 76 vpx_image_t img; | 79 vpx_image_t img; |
| 77 int img_setup; | 80 int img_setup; |
| 78 struct frame_buffers yv12_frame_buffers; | 81 struct frame_buffers yv12_frame_buffers; |
| 79 void *user_priv; | 82 void *user_priv; |
| 80 FRAGMENT_DATA fragments; | 83 FRAGMENT_DATA fragments; |
| 81 }; | 84 }; |
| 82 | 85 |
| 83 static unsigned long vp8_priv_sz(const vpx_codec_dec_cfg_t *si, vpx_codec_flags_
t flags) | 86 static unsigned long vp8_priv_sz(const vpx_codec_dec_cfg_t *si, vpx_codec_flags_
t flags) |
| 84 { | 87 { |
| 85 /* Although this declaration is constant, we can't use it in the requested | 88 /* Although this declaration is constant, we can't use it in the requested |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 { | 146 { |
| 144 res = VPX_CODEC_MEM_ERROR; | 147 res = VPX_CODEC_MEM_ERROR; |
| 145 break; | 148 break; |
| 146 } | 149 } |
| 147 } | 150 } |
| 148 } | 151 } |
| 149 | 152 |
| 150 return res; | 153 return res; |
| 151 } | 154 } |
| 152 | 155 |
| 156 static const unsigned char fake_decrypt_key[VP8_DECRYPT_KEY_SIZE] = { 0 }; |
| 157 |
| 153 static void vp8_init_ctx(vpx_codec_ctx_t *ctx, const vpx_codec_mmap_t *mmap) | 158 static void vp8_init_ctx(vpx_codec_ctx_t *ctx, const vpx_codec_mmap_t *mmap) |
| 154 { | 159 { |
| 155 int i; | 160 int i; |
| 156 | 161 |
| 157 ctx->priv = mmap->base; | 162 ctx->priv = mmap->base; |
| 158 ctx->priv->sz = sizeof(*ctx->priv); | 163 ctx->priv->sz = sizeof(*ctx->priv); |
| 159 ctx->priv->iface = ctx->iface; | 164 ctx->priv->iface = ctx->iface; |
| 160 ctx->priv->alg_priv = mmap->base; | 165 ctx->priv->alg_priv = mmap->base; |
| 161 | 166 |
| 162 for (i = 0; i < NELEMENTS(ctx->priv->alg_priv->mmaps); i++) | 167 for (i = 0; i < NELEMENTS(ctx->priv->alg_priv->mmaps); i++) |
| 163 ctx->priv->alg_priv->mmaps[i].id = vp8_mem_req_segs[i].id; | 168 ctx->priv->alg_priv->mmaps[i].id = vp8_mem_req_segs[i].id; |
| 164 | 169 |
| 165 ctx->priv->alg_priv->mmaps[0] = *mmap; | 170 ctx->priv->alg_priv->mmaps[0] = *mmap; |
| 166 ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si); | 171 ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si); |
| 172 memcpy(ctx->priv->alg_priv->decrypt_key, fake_decrypt_key, |
| 173 VP8_DECRYPT_KEY_SIZE); |
| 167 ctx->priv->init_flags = ctx->init_flags; | 174 ctx->priv->init_flags = ctx->init_flags; |
| 168 | 175 |
| 169 if (ctx->config.dec) | 176 if (ctx->config.dec) |
| 170 { | 177 { |
| 171 /* Update the reference to the config structure to an internal copy. */ | 178 /* Update the reference to the config structure to an internal copy. */ |
| 172 ctx->priv->alg_priv->cfg = *ctx->config.dec; | 179 ctx->priv->alg_priv->cfg = *ctx->config.dec; |
| 173 ctx->config.dec = &ctx->priv->alg_priv->cfg; | 180 ctx->config.dec = &ctx->priv->alg_priv->cfg; |
| 174 } | 181 } |
| 175 } | 182 } |
| 176 | 183 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 | 262 |
| 256 for (i = NELEMENTS(ctx->mmaps) - 1; i >= 0; i--) | 263 for (i = NELEMENTS(ctx->mmaps) - 1; i >= 0; i--) |
| 257 { | 264 { |
| 258 if (ctx->mmaps[i].dtor) | 265 if (ctx->mmaps[i].dtor) |
| 259 ctx->mmaps[i].dtor(&ctx->mmaps[i]); | 266 ctx->mmaps[i].dtor(&ctx->mmaps[i]); |
| 260 } | 267 } |
| 261 | 268 |
| 262 return VPX_CODEC_OK; | 269 return VPX_CODEC_OK; |
| 263 } | 270 } |
| 264 | 271 |
| 265 static vpx_codec_err_t vp8_peek_si(const uint8_t *data, | 272 static vpx_codec_err_t vp8_peek_si_external(const uint8_t *data, |
| 266 unsigned int data_sz, | 273 unsigned int data_sz, |
| 267 vpx_codec_stream_info_t *si) | 274 vpx_codec_stream_info_t *si, |
| 275 const unsigned char *decrypt_key) |
| 268 { | 276 { |
| 269 vpx_codec_err_t res = VPX_CODEC_OK; | 277 vpx_codec_err_t res = VPX_CODEC_OK; |
| 270 | 278 |
| 271 if(data + data_sz <= data) | 279 if(data + data_sz <= data) |
| 280 { |
| 272 res = VPX_CODEC_INVALID_PARAM; | 281 res = VPX_CODEC_INVALID_PARAM; |
| 282 } |
| 273 else | 283 else |
| 274 { | 284 { |
| 275 /* Parse uncompresssed part of key frame header. | 285 /* Parse uncompresssed part of key frame header. |
| 276 * 3 bytes:- including version, frame type and an offset | 286 * 3 bytes:- including version, frame type and an offset |
| 277 * 3 bytes:- sync code (0x9d, 0x01, 0x2a) | 287 * 3 bytes:- sync code (0x9d, 0x01, 0x2a) |
| 278 * 4 bytes:- including image width and height in the lowest 14 bits | 288 * 4 bytes:- including image width and height in the lowest 14 bits |
| 279 * of each 2-byte value. | 289 * of each 2-byte value. |
| 280 */ | 290 */ |
| 291 |
| 292 const uint8_t data0 = decrypt_byte(data, data, decrypt_key); |
| 281 si->is_kf = 0; | 293 si->is_kf = 0; |
| 294 if (data_sz >= 10 && !(data0 & 0x01)) /* I-Frame */ |
| 295 { |
| 296 const uint8_t data3 = decrypt_byte(data + 3, data, decrypt_key); |
| 297 const uint8_t data4 = decrypt_byte(data + 4, data, decrypt_key); |
| 298 const uint8_t data5 = decrypt_byte(data + 5, data, decrypt_key); |
| 299 const uint8_t data6 = decrypt_byte(data + 6, data, decrypt_key); |
| 300 const uint8_t data7 = decrypt_byte(data + 7, data, decrypt_key); |
| 301 const uint8_t data8 = decrypt_byte(data + 8, data, decrypt_key); |
| 302 const uint8_t data9 = decrypt_byte(data + 9, data, decrypt_key); |
| 282 | 303 |
| 283 if (data_sz >= 10 && !(data[0] & 0x01)) /* I-Frame */ | |
| 284 { | |
| 285 const uint8_t *c = data + 3; | |
| 286 si->is_kf = 1; | 304 si->is_kf = 1; |
| 287 | 305 |
| 288 /* vet via sync code */ | 306 /* vet via sync code */ |
| 289 if (c[0] != 0x9d || c[1] != 0x01 || c[2] != 0x2a) | 307 if (data3 != 0x9d || data4 != 0x01 || data5 != 0x2a) |
| 290 res = VPX_CODEC_UNSUP_BITSTREAM; | 308 res = VPX_CODEC_UNSUP_BITSTREAM; |
| 291 | 309 |
| 292 si->w = (c[3] | (c[4] << 8)) & 0x3fff; | 310 si->w = (data6 | (data7 << 8)) & 0x3fff; |
| 293 si->h = (c[5] | (c[6] << 8)) & 0x3fff; | 311 si->h = (data8 | (data9 << 8)) & 0x3fff; |
| 294 | 312 |
| 295 /*printf("w=%d, h=%d\n", si->w, si->h);*/ | 313 /*printf("w=%d, h=%d\n", si->w, si->h);*/ |
| 296 if (!(si->h | si->w)) | 314 if (!(si->h | si->w)) |
| 297 res = VPX_CODEC_UNSUP_BITSTREAM; | 315 res = VPX_CODEC_UNSUP_BITSTREAM; |
| 298 } | 316 } |
| 299 else | 317 else |
| 318 { |
| 300 res = VPX_CODEC_UNSUP_BITSTREAM; | 319 res = VPX_CODEC_UNSUP_BITSTREAM; |
| 320 } |
| 301 } | 321 } |
| 302 | 322 |
| 303 return res; | 323 return res; |
| 324 } |
| 304 | 325 |
| 326 static vpx_codec_err_t vp8_peek_si(const uint8_t *data, |
| 327 unsigned int data_sz, |
| 328 vpx_codec_stream_info_t *si) { |
| 329 return vp8_peek_si_external(data, data_sz, si, fake_decrypt_key); |
| 305 } | 330 } |
| 306 | 331 |
| 307 static vpx_codec_err_t vp8_get_si(vpx_codec_alg_priv_t *ctx, | 332 static vpx_codec_err_t vp8_get_si(vpx_codec_alg_priv_t *ctx, |
| 308 vpx_codec_stream_info_t *si) | 333 vpx_codec_stream_info_t *si) |
| 309 { | 334 { |
| 310 | 335 |
| 311 unsigned int sz; | 336 unsigned int sz; |
| 312 | 337 |
| 313 if (si->sz >= sizeof(vp8_stream_info_t)) | 338 if (si->sz >= sizeof(vp8_stream_info_t)) |
| 314 sz = sizeof(vp8_stream_info_t); | 339 sz = sizeof(vp8_stream_info_t); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 if(update_fragments(ctx, data, data_sz, &res) <= 0) | 448 if(update_fragments(ctx, data, data_sz, &res) <= 0) |
| 424 return res; | 449 return res; |
| 425 | 450 |
| 426 /* Determine the stream parameters. Note that we rely on peek_si to | 451 /* Determine the stream parameters. Note that we rely on peek_si to |
| 427 * validate that we have a buffer that does not wrap around the top | 452 * validate that we have a buffer that does not wrap around the top |
| 428 * of the heap. | 453 * of the heap. |
| 429 */ | 454 */ |
| 430 w = ctx->si.w; | 455 w = ctx->si.w; |
| 431 h = ctx->si.h; | 456 h = ctx->si.h; |
| 432 | 457 |
| 433 res = ctx->base.iface->dec.peek_si(ctx->fragments.ptrs[0], | 458 res = vp8_peek_si_external(ctx->fragments.ptrs[0], |
| 434 ctx->fragments.sizes[0], &ctx->si); | 459 ctx->fragments.sizes[0], |
| 460 &ctx->si, |
| 461 ctx->decrypt_key); |
| 435 | 462 |
| 436 if((res == VPX_CODEC_UNSUP_BITSTREAM) && !ctx->si.is_kf) | 463 if((res == VPX_CODEC_UNSUP_BITSTREAM) && !ctx->si.is_kf) |
| 437 { | 464 { |
| 438 /* the peek function returns an error for non keyframes, however for | 465 /* the peek function returns an error for non keyframes, however for |
| 439 * this case, it is not an error */ | 466 * this case, it is not an error */ |
| 440 res = VPX_CODEC_OK; | 467 res = VPX_CODEC_OK; |
| 441 } | 468 } |
| 442 | 469 |
| 443 if(!ctx->decoder_init && !ctx->si.is_kf) | 470 if(!ctx->decoder_init && !ctx->si.is_kf) |
| 444 res = VPX_CODEC_UNSUP_BITSTREAM; | 471 res = VPX_CODEC_UNSUP_BITSTREAM; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 if (!ctx->postproc_cfg_set | 525 if (!ctx->postproc_cfg_set |
| 499 && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) | 526 && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) |
| 500 { | 527 { |
| 501 ctx->postproc_cfg.post_proc_flag = | 528 ctx->postproc_cfg.post_proc_flag = |
| 502 VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE; | 529 VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE; |
| 503 ctx->postproc_cfg.deblocking_level = 4; | 530 ctx->postproc_cfg.deblocking_level = 4; |
| 504 ctx->postproc_cfg.noise_level = 0; | 531 ctx->postproc_cfg.noise_level = 0; |
| 505 } | 532 } |
| 506 | 533 |
| 507 res = vp8_create_decoder_instances(&ctx->yv12_frame_buffers, &oxcf); | 534 res = vp8_create_decoder_instances(&ctx->yv12_frame_buffers, &oxcf); |
| 535 ctx->yv12_frame_buffers.pbi[0]->decrypt_key = ctx->decrypt_key; |
| 508 } | 536 } |
| 509 | 537 |
| 510 ctx->decoder_init = 1; | 538 ctx->decoder_init = 1; |
| 511 } | 539 } |
| 512 | 540 |
| 513 if (!res) | 541 if (!res) |
| 514 { | 542 { |
| 515 VP8D_COMP *pbi = ctx->yv12_frame_buffers.pbi[0]; | 543 VP8D_COMP *pbi = ctx->yv12_frame_buffers.pbi[0]; |
| 516 if(resolution_change) | 544 if(resolution_change) |
| 517 { | 545 { |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0]; | 947 VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0]; |
| 920 *corrupted = pbi->common.frame_to_show->corrupted; | 948 *corrupted = pbi->common.frame_to_show->corrupted; |
| 921 | 949 |
| 922 return VPX_CODEC_OK; | 950 return VPX_CODEC_OK; |
| 923 } | 951 } |
| 924 else | 952 else |
| 925 return VPX_CODEC_INVALID_PARAM; | 953 return VPX_CODEC_INVALID_PARAM; |
| 926 | 954 |
| 927 } | 955 } |
| 928 | 956 |
| 957 |
| 958 static vpx_codec_err_t vp8_set_decrypt_key(vpx_codec_alg_priv_t *ctx, |
| 959 int ctr_id, |
| 960 va_list args) |
| 961 { |
| 962 const unsigned char *data = va_arg(args, const unsigned char *); |
| 963 if (data == NULL) { |
| 964 return VPX_CODEC_INVALID_PARAM; |
| 965 } |
| 966 |
| 967 memcpy(ctx->decrypt_key, data, VP8_DECRYPT_KEY_SIZE); |
| 968 return VPX_CODEC_OK; |
| 969 } |
| 970 |
| 929 vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = | 971 vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = |
| 930 { | 972 { |
| 931 {VP8_SET_REFERENCE, vp8_set_reference}, | 973 {VP8_SET_REFERENCE, vp8_set_reference}, |
| 932 {VP8_COPY_REFERENCE, vp8_get_reference}, | 974 {VP8_COPY_REFERENCE, vp8_get_reference}, |
| 933 {VP8_SET_POSTPROC, vp8_set_postproc}, | 975 {VP8_SET_POSTPROC, vp8_set_postproc}, |
| 934 {VP8_SET_DBG_COLOR_REF_FRAME, vp8_set_dbg_options}, | 976 {VP8_SET_DBG_COLOR_REF_FRAME, vp8_set_dbg_options}, |
| 935 {VP8_SET_DBG_COLOR_MB_MODES, vp8_set_dbg_options}, | 977 {VP8_SET_DBG_COLOR_MB_MODES, vp8_set_dbg_options}, |
| 936 {VP8_SET_DBG_COLOR_B_MODES, vp8_set_dbg_options}, | 978 {VP8_SET_DBG_COLOR_B_MODES, vp8_set_dbg_options}, |
| 937 {VP8_SET_DBG_DISPLAY_MV, vp8_set_dbg_options}, | 979 {VP8_SET_DBG_DISPLAY_MV, vp8_set_dbg_options}, |
| 938 {VP8D_GET_LAST_REF_UPDATES, vp8_get_last_ref_updates}, | 980 {VP8D_GET_LAST_REF_UPDATES, vp8_get_last_ref_updates}, |
| 939 {VP8D_GET_FRAME_CORRUPTED, vp8_get_frame_corrupted}, | 981 {VP8D_GET_FRAME_CORRUPTED, vp8_get_frame_corrupted}, |
| 940 {VP8D_GET_LAST_REF_USED, vp8_get_last_ref_frame}, | 982 {VP8D_GET_LAST_REF_USED, vp8_get_last_ref_frame}, |
| 983 {VP8_SET_DECRYPT_KEY, vp8_set_decrypt_key}, |
| 941 { -1, NULL}, | 984 { -1, NULL}, |
| 942 }; | 985 }; |
| 943 | 986 |
| 944 | 987 |
| 945 #ifndef VERSION_STRING | 988 #ifndef VERSION_STRING |
| 946 #define VERSION_STRING | 989 #define VERSION_STRING |
| 947 #endif | 990 #endif |
| 948 CODEC_INTERFACE(vpx_codec_vp8_dx) = | 991 CODEC_INTERFACE(vpx_codec_vp8_dx) = |
| 949 { | 992 { |
| 950 "WebM Project VP8 Decoder" VERSION_STRING, | 993 "WebM Project VP8 Decoder" VERSION_STRING, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 965 }, | 1008 }, |
| 966 { /* encoder functions */ | 1009 { /* encoder functions */ |
| 967 NOT_IMPLEMENTED, | 1010 NOT_IMPLEMENTED, |
| 968 NOT_IMPLEMENTED, | 1011 NOT_IMPLEMENTED, |
| 969 NOT_IMPLEMENTED, | 1012 NOT_IMPLEMENTED, |
| 970 NOT_IMPLEMENTED, | 1013 NOT_IMPLEMENTED, |
| 971 NOT_IMPLEMENTED, | 1014 NOT_IMPLEMENTED, |
| 972 NOT_IMPLEMENTED | 1015 NOT_IMPLEMENTED |
| 973 } | 1016 } |
| 974 }; | 1017 }; |
| OLD | NEW |