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