History

Windows Media Image decoder (WMVP/WVP2)

Alberto Delmás committed 15 years ago

Commit 45ecda81 parent 3be5a9414 files · +431 −85Browse files

Unified · Split

14 files
  1. Changelog +1 −0
  2. configure +2 −0
  3. doc/general.texi +1 −0
  4. libavcodec/allcodecs.c +2 −0
  5. libavcodec/avcodec.h +2 −0
  6. libavcodec/h263dec.c +2 −0
  7. libavcodec/mpegvideo.c +10 −2
  8. libavcodec/vc1.c +0 −3
  9. libavcodec/vc1.h +3 −0
  10. libavcodec/vc1dec.c +327 −77
  11. libavcodec/vc1dsp.c +68 −0
  12. libavcodec/vc1dsp.h +10 −0
  13. libavcodec/version.h +1 −1
  14. libavformat/riff.c +2 −2
Changelog+1−0
@@ -41,6 +41,7 @@ easier to use. The changes are: · 40 unmodified lines
41 '-preset <presetname>'.41 '-preset <presetname>'.
42 * -intra option was removed, it's equivalent to -g 0.42 * -intra option was removed, it's equivalent to -g 0.
43- XMV demuxer43- XMV demuxer
44- Windows Media Image decoder
44 45
45 46
46version 0.7:47version 0.7:
configure+2−0
@@ -1354,6 +1354,7 @@ vc1_dxva2_hwaccel_deps="dxva2api_h DXVA_PictureParameters_wDecodedPictureIndex" · 1353 unmodified lines
1354vc1_dxva2_hwaccel_select="dxva2 vc1_decoder"1354vc1_dxva2_hwaccel_select="dxva2 vc1_decoder"
1355vc1_vaapi_hwaccel_select="vaapi vc1_decoder"1355vc1_vaapi_hwaccel_select="vaapi vc1_decoder"
1356vc1_vdpau_decoder_select="vdpau vc1_decoder"1356vc1_vdpau_decoder_select="vdpau vc1_decoder"
1357vc1image_decoder_select="vc1_decoder"
1357vorbis_decoder_select="mdct"1358vorbis_decoder_select="mdct"
1358vorbis_encoder_select="mdct"1359vorbis_encoder_select="mdct"
1359vp6_decoder_select="huffman"1360vp6_decoder_select="huffman"
@@ -1374,6 +1375,7 @@ wmv3_decoder_select="vc1_decoder" · 14 unmodified lines
1374wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"1375wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
1375wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"1376wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
1376wmv3_vdpau_decoder_select="vc1_vdpau_decoder"1377wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
1378wmv3image_decoder_select="wmv3_decoder"
1377zlib_decoder_select="zlib"1379zlib_decoder_select="zlib"
1378zlib_encoder_select="zlib"1380zlib_encoder_select="zlib"
1379zmbv_decoder_select="zlib"1381zmbv_decoder_select="zlib"
doc/general.texi+1−0
@@ -518,6 +518,7 @@ following image formats are supported: · 517 unmodified lines
518@item VMware Screen Codec / VMware Video @tab @tab X518@item VMware Screen Codec / VMware Video @tab @tab X
519 @tab Codec used in videos captured by VMware.519 @tab Codec used in videos captured by VMware.
520@item Westwood Studios VQA (Vector Quantized Animation) video @tab @tab X520@item Westwood Studios VQA (Vector Quantized Animation) video @tab @tab X
521@item Windows Media Image @tab @tab X
521@item Windows Media Video 7 @tab X @tab X522@item Windows Media Video 7 @tab X @tab X
522@item Windows Media Video 8 @tab X @tab X523@item Windows Media Video 8 @tab X @tab X
523@item Windows Media Video 9 @tab @tab X524@item Windows Media Video 9 @tab @tab X
libavcodec/allcodecs.c+2−0
@@ -203,6 +203,7 @@ void avcodec_register_all(void) · 202 unmodified lines
203 REGISTER_DECODER (VB, vb);203 REGISTER_DECODER (VB, vb);
204 REGISTER_DECODER (VC1, vc1);204 REGISTER_DECODER (VC1, vc1);
205 REGISTER_DECODER (VC1_VDPAU, vc1_vdpau);205 REGISTER_DECODER (VC1_VDPAU, vc1_vdpau);
206 REGISTER_DECODER (VC1IMAGE, vc1image);
206 REGISTER_DECODER (VCR1, vcr1);207 REGISTER_DECODER (VCR1, vcr1);
207 REGISTER_DECODER (VMDVIDEO, vmdvideo);208 REGISTER_DECODER (VMDVIDEO, vmdvideo);
208 REGISTER_DECODER (VMNC, vmnc);209 REGISTER_DECODER (VMNC, vmnc);
@@ -217,6 +218,7 @@ void avcodec_register_all(void) · 8 unmodified lines
217 REGISTER_ENCDEC (WMV2, wmv2);218 REGISTER_ENCDEC (WMV2, wmv2);
218 REGISTER_DECODER (WMV3, wmv3);219 REGISTER_DECODER (WMV3, wmv3);
219 REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau);220 REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau);
221 REGISTER_DECODER (WMV3IMAGE, wmv3image);
220 REGISTER_DECODER (WNV1, wnv1);222 REGISTER_DECODER (WNV1, wnv1);
221 REGISTER_DECODER (XAN_WC3, xan_wc3);223 REGISTER_DECODER (XAN_WC3, xan_wc3);
222 REGISTER_DECODER (XAN_WC4, xan_wc4);224 REGISTER_DECODER (XAN_WC4, xan_wc4);
libavcodec/avcodec.h+2−0
@@ -208,6 +208,8 @@ enum CodecID { · 207 unmodified lines
208 CODEC_ID_PRORES,208 CODEC_ID_PRORES,
209 CODEC_ID_JV,209 CODEC_ID_JV,
210 CODEC_ID_DFA,210 CODEC_ID_DFA,
211 CODEC_ID_WMV3IMAGE,
212 CODEC_ID_VC1IMAGE,
211 213
212 /* various PCM "codecs" */214 /* various PCM "codecs" */
213 CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs215 CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
libavcodec/h263dec.c+2−0
@@ -91,6 +91,8 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) · 90 unmodified lines
91 break;91 break;
92 case CODEC_ID_VC1:92 case CODEC_ID_VC1:
93 case CODEC_ID_WMV3:93 case CODEC_ID_WMV3:
94 case CODEC_ID_VC1IMAGE:
95 case CODEC_ID_WMV3IMAGE:
94 s->h263_pred = 1;96 s->h263_pred = 1;
95 s->msmpeg4_version=6;97 s->msmpeg4_version=6;
96 avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;98 avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
libavcodec/mpegvideo.c+10−2
@@ -208,7 +208,12 @@ void ff_copy_picture(Picture *dst, Picture *src){ · 207 unmodified lines
208 */208 */
209static void free_frame_buffer(MpegEncContext *s, Picture *pic)209static void free_frame_buffer(MpegEncContext *s, Picture *pic)
210{210{
211 ff_thread_release_buffer(s->avctx, (AVFrame*)pic);211 /* Windows Media Image codecs allocate internal buffers with different
212 dimensions; ignore user defined callbacks for these */
213 if (s->codec_id != CODEC_ID_WMV3IMAGE && s->codec_id != CODEC_ID_VC1IMAGE)
214 ff_thread_release_buffer(s->avctx, (AVFrame*)pic);
215 else
216 avcodec_default_release_buffer(s->avctx, (AVFrame*)pic);
212 av_freep(&pic->f.hwaccel_picture_private);217 av_freep(&pic->f.hwaccel_picture_private);
213}218}
214 219
@@ -230,7 +235,10 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) · 15 unmodified lines
230 }235 }
231 }236 }
232 237
233 r = ff_thread_get_buffer(s->avctx, (AVFrame*)pic);238 if (s->codec_id != CODEC_ID_WMV3IMAGE && s->codec_id != CODEC_ID_VC1IMAGE)
239 r = ff_thread_get_buffer(s->avctx, (AVFrame*)pic);
240 else
241 r = avcodec_default_get_buffer(s->avctx, (AVFrame*)pic);
234 242
235 if (r < 0 || !pic->f.age || !pic->f.type || !pic->f.data[0]) {243 if (r < 0 || !pic->f.age || !pic->f.type || !pic->f.data[0]) {
236 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n",244 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n",
libavcodec/vc1.c+0−3
@@ -314,9 +314,6 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte · 313 unmodified lines
314 "Old interlaced mode is not supported\n");314 "Old interlaced mode is not supported\n");
315 return -1;315 return -1;
316 }316 }
317 if (v->res_sprite) {
318 av_log(avctx, AV_LOG_ERROR, "WMVP is not fully supported\n");
319 }
320 }317 }
321 318
322 // (fps-2)/4 (->30)319 // (fps-2)/4 (->30)
libavcodec/vc1.h+3−0
@@ -311,6 +311,9 @@ typedef struct VC1Context{ · 310 unmodified lines
311 //@{311 //@{
312 int new_sprite;312 int new_sprite;
313 int two_sprites;313 int two_sprites;
314 AVFrame sprite_output_frame;
315 int output_width, output_height, sprite_width, sprite_height;
316 uint8_t* sr_rows[2][2]; ///< Sprite resizer line cache
314 //@}317 //@}
315 318
316 int p_frame_skipped;319 int p_frame_skipped;
libavcodec/vc1dec.c+327−77
@@ -3278,116 +3278,279 @@ static void vc1_decode_blocks(VC1Context *v) · 3277 unmodified lines
3278 }3278 }
3279}3279}
3280 3280
3281static inline float get_float_val(GetBitContext* gb)3281#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
3282
3283typedef struct {
3284 /**
3285 * Transform coefficients for both sprites in 16.16 fixed point format,
3286 * in the order they appear in the bitstream:
3287 * x scale
3288 * rotation 1 (unused)
3289 * x offset
3290 * rotation 2 (unused)
3291 * y scale
3292 * y offset
3293 * alpha
3294 */
3295 int coefs[2][7];
3296
3297 int effect_type, effect_flag;
3298 int effect_pcount1, effect_pcount2; ///< amount of effect parameters stored in effect_params
3299 int effect_params1[15], effect_params2[10]; ///< effect parameters in 16.16 fixed point format
3300} SpriteData;
3301
3302static inline int get_fp_val(GetBitContext* gb)
3282{3303{
3283 return (float)get_bits_long(gb, 30) / (1<<15) - (1<<14);3304 return (get_bits_long(gb, 30) - (1<<29)) << 1;
3284}3305}
3285 3306
3286static void vc1_sprite_parse_transform(VC1Context *v, GetBitContext* gb, float c[7])3307static void vc1_sprite_parse_transform(GetBitContext* gb, int c[7])
3287{3308{
3288 c[1] = c[3] = 0.0f;3309 c[1] = c[3] = 0;
3289 3310
3290 switch (get_bits(gb, 2)) {3311 switch (get_bits(gb, 2)) {
3291 case 0:3312 case 0:
3292 c[0] = 1.0f;3313 c[0] = 1<<16;
3293 c[2] = get_float_val(gb);3314 c[2] = get_fp_val(gb);
3294 c[4] = 1.0f;3315 c[4] = 1<<16;
3295 break;3316 break;
3296 case 1:3317 case 1:
3297 c[0] = c[4] = get_float_val(gb);3318 c[0] = c[4] = get_fp_val(gb);
3298 c[2] = get_float_val(gb);3319 c[2] = get_fp_val(gb);
3299 break;3320 break;
3300 case 2:3321 case 2:
3301 c[0] = get_float_val(gb);3322 c[0] = get_fp_val(gb);
3302 c[2] = get_float_val(gb);3323 c[2] = get_fp_val(gb);
3303 c[4] = get_float_val(gb);3324 c[4] = get_fp_val(gb);
3304 break;3325 break;
3305 case 3:3326 case 3:
3306 av_log_ask_for_sample(v->s.avctx, NULL);3327 c[0] = get_fp_val(gb);
3307 c[0] = get_float_val(gb);3328 c[1] = get_fp_val(gb);
3308 c[1] = get_float_val(gb);3329 c[2] = get_fp_val(gb);
3309 c[2] = get_float_val(gb);3330 c[3] = get_fp_val(gb);
3310 c[3] = get_float_val(gb);3331 c[4] = get_fp_val(gb);
3311 c[4] = get_float_val(gb);
3312 break;3332 break;
3313 }3333 }
3314 c[5] = get_float_val(gb);3334 c[5] = get_fp_val(gb);
3315 if (get_bits1(gb))3335 if (get_bits1(gb))
3316 c[6] = get_float_val(gb);3336 c[6] = get_fp_val(gb);
3317 else3337 else
3318 c[6] = 1.0f;3338 c[6] = 1<<16;
3319}3339}
3320 3340
3321static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb)3341static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd)
3322{3342{
3323 int effect_type, effect_flag, effect_pcount1, effect_pcount2, i;3343 AVCodecContext *avctx = v->s.avctx;
3324 float effect_params1[14], effect_params2[10];3344 int sprite, i;
3325 3345
3326 float coefs[2][7];3346 for (sprite = 0; sprite <= v->two_sprites; sprite++) {
3327 vc1_sprite_parse_transform(v, gb, coefs[0]);3347 vc1_sprite_parse_transform(gb, sd->coefs[sprite]);
3328 av_log(v->s.avctx, AV_LOG_DEBUG, "S1:");3348 if (sd->coefs[sprite][1] || sd->coefs[sprite][3])
3329 for (i = 0; i < 7; i++)3349 av_log_ask_for_sample(avctx, "Rotation coefficients are not zero");
3330 av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", coefs[0][i]);3350 av_log(avctx, AV_LOG_DEBUG, sprite ? "S2:" : "S1:");
3331 av_log(v->s.avctx, AV_LOG_DEBUG, "\n");
3332
3333 if (v->two_sprites) {
3334 vc1_sprite_parse_transform(v, gb, coefs[1]);
3335 av_log(v->s.avctx, AV_LOG_DEBUG, "S2:");
3336 for (i = 0; i < 7; i++)3351 for (i = 0; i < 7; i++)
3337 av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", coefs[1][i]);3352 av_log(avctx, AV_LOG_DEBUG, " %d.%.3d",
3338 av_log(v->s.avctx, AV_LOG_DEBUG, "\n");3353 sd->coefs[sprite][i] / (1<<16),
3354 (abs(sd->coefs[sprite][i]) & 0xFFFF) * 1000 / (1<<16));
3355 av_log(avctx, AV_LOG_DEBUG, "\n");
3339 }3356 }
3357
3340 skip_bits(gb, 2);3358 skip_bits(gb, 2);
3341 if (effect_type = get_bits_long(gb, 30)){3359 if (sd->effect_type = get_bits_long(gb, 30)) {
3342 switch (effect_pcount1 = get_bits(gb, 4)) {3360 switch (sd->effect_pcount1 = get_bits(gb, 4)) {
3343 case 2:
3344 effect_params1[0] = get_float_val(gb);
3345 effect_params1[1] = get_float_val(gb);
3346 break;
3347 case 7:3361 case 7:
3348 vc1_sprite_parse_transform(v, gb, effect_params1);3362 vc1_sprite_parse_transform(gb, sd->effect_params1);
3349 break;3363 break;
3350 case 14:3364 case 14:
3351 vc1_sprite_parse_transform(v, gb, effect_params1);3365 vc1_sprite_parse_transform(gb, sd->effect_params1);
3352 vc1_sprite_parse_transform(v, gb, &effect_params1[7]);3366 vc1_sprite_parse_transform(gb, sd->effect_params1 + 7);
3353 break;3367 break;
3354 default:3368 default:
3355 av_log_ask_for_sample(v->s.avctx, NULL);3369 for (i = 0; i < sd->effect_pcount1; i++)
3356 return;3370 sd->effect_params1[i] = get_fp_val(gb);
3357 }3371 }
3358 if (effect_type != 13 || effect_params1[0] != coefs[0][6]) {3372 if (sd->effect_type != 13 || sd->effect_params1[0] != sd->coefs[0][6]) {
3359 // effect 13 is simple alpha blending and matches the opacity above3373 // effect 13 is simple alpha blending and matches the opacity above
3360 av_log(v->s.avctx, AV_LOG_DEBUG, "Effect: %d; params: ", effect_type);3374 av_log(avctx, AV_LOG_DEBUG, "Effect: %d; params: ", sd->effect_type);
3361 for (i = 0; i < effect_pcount1; i++)3375 for (i = 0; i < sd->effect_pcount1; i++)
3362 av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", effect_params1[i]);3376 av_log(avctx, AV_LOG_DEBUG, " %d.%.2d",
3363 av_log(v->s.avctx, AV_LOG_DEBUG, "\n");3377 sd->effect_params1[i] / (1<<16),
3378 (abs(sd->effect_params1[i]) & 0xFFFF) * 1000 / (1<<16));
3379 av_log(avctx, AV_LOG_DEBUG, "\n");
3364 }3380 }
3365 3381
3366 effect_pcount2 = get_bits(gb, 16);3382 sd->effect_pcount2 = get_bits(gb, 16);
3367 if (effect_pcount2 > 10) {3383 if (sd->effect_pcount2 > 10) {
3368 av_log(v->s.avctx, AV_LOG_ERROR, "Too many effect parameters\n");3384 av_log(avctx, AV_LOG_ERROR, "Too many effect parameters\n");
3369 return;3385 return;
3370 } else if (effect_pcount2) {3386 } else if (sd->effect_pcount2) {
3371 i = 0;3387 i = -1;
3372 av_log(v->s.avctx, AV_LOG_DEBUG, "Effect params 2: ");3388 av_log(avctx, AV_LOG_DEBUG, "Effect params 2: ");
3373 while (i < effect_pcount2){3389 while (++i < sd->effect_pcount2){
3374 effect_params2[i] = get_float_val(gb);3390 sd->effect_params2[i] = get_fp_val(gb);
3375 av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", effect_params2[i]);3391 av_log(avctx, AV_LOG_DEBUG, " %d.%.2d",
3376 i++;3392 sd->effect_params2[i] / (1<<16),
3393 (abs(sd->effect_params2[i]) & 0xFFFF) * 1000 / (1<<16));
3377 }3394 }
3378 av_log(v->s.avctx, AV_LOG_DEBUG, "\n");3395 av_log(avctx, AV_LOG_DEBUG, "\n");
3379 }3396 }
3380 }3397 }
3381 if (effect_flag = get_bits1(gb))3398 if (sd->effect_flag = get_bits1(gb))
3382 av_log(v->s.avctx, AV_LOG_DEBUG, "Effect flag set\n");3399 av_log(avctx, AV_LOG_DEBUG, "Effect flag set\n");
3383 3400
3384 if (get_bits_count(gb) >= gb->size_in_bits +3401 if (get_bits_count(gb) >= gb->size_in_bits +
3385 (v->s.avctx->codec_id == CODEC_ID_WMV3 ? 64 : 0))3402 (avctx->codec_id == CODEC_ID_WMV3IMAGE ? 64 : 0))
3386 av_log(v->s.avctx, AV_LOG_ERROR, "Buffer overrun\n");3403 av_log(avctx, AV_LOG_ERROR, "Buffer overrun\n");
3387 if (get_bits_count(gb) < gb->size_in_bits - 8)3404 if (get_bits_count(gb) < gb->size_in_bits - 8)
3388 av_log(v->s.avctx, AV_LOG_WARNING, "Buffer not fully read\n");3405 av_log(avctx, AV_LOG_WARNING, "Buffer not fully read\n");
3406}
3407
3408static void vc1_draw_sprites(VC1Context *v, SpriteData* sd)
3409{
3410 int i, plane, row, sprite;
3411 int sr_cache[2][2] = { { -1, -1 }, { -1, -1 } };
3412 uint8_t* src_h[2][2];
3413 int xoff[2], xadv[2], yoff[2], yadv[2], alpha;
3414 int ysub[2];
3415 MpegEncContext *s = &v->s;
3416
3417 for (i = 0; i < 2; i++) {
3418 xoff[i] = av_clip(sd->coefs[i][2], 0, v->sprite_width-1 << 16);
3419 xadv[i] = sd->coefs[i][0];
3420 if (xadv[i] != 1<<16 || (v->sprite_width<<16) - (v->output_width<<16) - xoff[i])
3421 xadv[i] = av_clip(xadv[i], 0, ((v->sprite_width<<16) - xoff[i] - 1) / v->output_width);
3422
3423 yoff[i] = av_clip(sd->coefs[i][5], 0, v->sprite_height-1 << 16);
3424 yadv[i] = av_clip(sd->coefs[i][4], 0, ((v->sprite_height<<16) - yoff[i]) / v->output_height);
3425 }
3426 alpha = av_clip(sd->coefs[1][6], 0, (1<<16) - 1);
3427
3428 for (plane = 0; plane < (s->flags&CODEC_FLAG_GRAY ? 1 : 3); plane++) {
3429 int width = v->output_width>>!!plane;
3430
3431 for (row = 0; row < v->output_height>>!!plane; row++) {
3432 uint8_t *dst = v->sprite_output_frame.data[plane] +
3433 v->sprite_output_frame.linesize[plane] * row;
3434
3435 for (sprite = 0; sprite <= v->two_sprites; sprite++) {
3436 uint8_t *iplane = s->current_picture.f.data[plane];
3437 int iline = s->current_picture.f.linesize[plane];
3438 int ycoord = yoff[sprite] + yadv[sprite]*row;
3439 int yline = ycoord>>16;
3440 ysub[sprite] = ycoord&0xFFFF;
3441 if (sprite) {
3442 iplane = s->last_picture.f.data[plane];
3443 iline = s->last_picture.f.linesize[plane];
3444 }
3445 if (!(xoff[sprite]&0xFFFF) && xadv[sprite] == 1<<16) {
3446 src_h[sprite][0] = iplane+(xoff[sprite]>>16)+ yline *iline;
3447 if (ysub[sprite])
3448 src_h[sprite][1] = iplane+(xoff[sprite]>>16)+(yline+1)*iline;
3449 } else {
3450 if (sr_cache[sprite][0] != yline) {
3451 if (sr_cache[sprite][1] == yline) {
3452 FFSWAP(uint8_t*, v->sr_rows[sprite][0], v->sr_rows[sprite][1]);
3453 FFSWAP(int, sr_cache[sprite][0], sr_cache[sprite][1]);
3454 } else {
3455 v->vc1dsp.sprite_h(v->sr_rows[sprite][0], iplane+yline*iline, xoff[sprite], xadv[sprite], width);
3456 sr_cache[sprite][0] = yline;
3457 }
3458 }
3459 if (ysub[sprite] && sr_cache[sprite][1] != yline + 1) {
3460 v->vc1dsp.sprite_h(v->sr_rows[sprite][1], iplane+(yline+1)*iline, xoff[sprite], xadv[sprite], width);
3461 sr_cache[sprite][1] = yline + 1;
3462 }
3463 src_h[sprite][0] = v->sr_rows[sprite][0];
3464 src_h[sprite][1] = v->sr_rows[sprite][1];
3465 }
3466 }
3467
3468 if (!v->two_sprites) {
3469 if (ysub[0]) {
3470 v->vc1dsp.sprite_v_single(dst, src_h[0][0], src_h[0][1], ysub[0], width);
3471 } else {
3472 memcpy(dst, src_h[0][0], width);
3473 }
3474 } else {
3475 if (ysub[0] && ysub[1]) {
3476 v->vc1dsp.sprite_v_double_twoscale(dst, src_h[0][0], src_h[0][1], ysub[0],
3477 src_h[1][0], src_h[1][1], ysub[1], alpha, width);
3478 } else if (ysub[0]) {
3479 v->vc1dsp.sprite_v_double_onescale(dst, src_h[0][0], src_h[0][1], ysub[0],
3480 src_h[1][0], alpha, width);
3481 } else if (ysub[1]) {
3482 v->vc1dsp.sprite_v_double_onescale(dst, src_h[1][0], src_h[1][1], ysub[1],
3483 src_h[0][0], (1<<16)-1-alpha, width);
3484 } else {
3485 v->vc1dsp.sprite_v_double_noscale(dst, src_h[0][0], src_h[1][0], alpha, width);
3486 }
3487 }
3488 }
3489
3490 if (!plane) {
3491 for (i = 0; i < 2; i++) {
3492 xoff[i] >>= 1;
3493 yoff[i] >>= 1;
3494 }
3495 }
3496
3497 }
3498}
3499
3500
3501static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb)
3502{
3503 MpegEncContext *s = &v->s;
3504 AVCodecContext *avctx = s->avctx;
3505 SpriteData sd;
3506
3507 vc1_parse_sprites(v, gb, &sd);
3508
3509 if (!s->current_picture.f.data[0]) {
3510 av_log(avctx, AV_LOG_ERROR, "Got no sprites\n");
3511 return -1;
3512 }
3513
3514 if (v->two_sprites && (!s->last_picture_ptr || !s->last_picture.f.data[0])) {
3515 av_log(avctx, AV_LOG_WARNING, "Need two sprites, only got one\n");
3516 v->two_sprites = 0;
3517 }
3518
3519 if (v->sprite_output_frame.data[0])
3520 avctx->release_buffer(avctx, &v->sprite_output_frame);
3521
3522 v->sprite_output_frame.buffer_hints = FF_BUFFER_HINTS_VALID;
3523 v->sprite_output_frame.reference = 0;
3524 if (avctx->get_buffer(avctx, &v->sprite_output_frame) < 0) {
3525 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
3526 return -1;
3527 }
3528
3529 vc1_draw_sprites(v, &sd);
3530
3531 return 0;
3532}
3533
3534static void vc1_sprite_flush(AVCodecContext *avctx)
3535{
3536 VC1Context *v = avctx->priv_data;
3537 MpegEncContext *s = &v->s;
3538 AVFrame *f = &s->current_picture.f;
3539 int plane, i;
3540
3541 /* Windows Media Image codecs have a convergence interval of two keyframes.
3542 Since we can't enforce it, clear to black the missing sprite. This is
3543 wrong but it looks better than doing nothing. */
3544
3545 if (f->data[0])
3546 for (plane = 0; plane < (s->flags&CODEC_FLAG_GRAY ? 1 : 3); plane++)
3547 for (i = 0; i < v->sprite_height>>!!plane; i++)
3548 memset(f->data[plane]+i*f->linesize[plane],
3549 plane ? 128 : 0, f->linesize[plane]);
3389}3550}
3390 3551
3552#endif
3553
3391/** Initialize a VC1/WMV3 decoder3554/** Initialize a VC1/WMV3 decoder
3392 * @todo TODO: Handle VC-1 IDUs (Transport level?)3555 * @todo TODO: Handle VC-1 IDUs (Transport level?)
3393 * @todo TODO: Decypher remaining bits in extra_data3556 * @todo TODO: Decypher remaining bits in extra_data
@@ -3399,6 +3562,10 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) · 5 unmodified lines
3399 GetBitContext gb;3562 GetBitContext gb;
3400 int i, cur_width, cur_height;3563 int i, cur_width, cur_height;
3401 3564
3565 /* save the container output size for WMImage */
3566 v->output_width = avctx->width;
3567 v->output_height = avctx->height;
3568
3402 if (!avctx->extradata_size || !avctx->extradata) return -1;3569 if (!avctx->extradata_size || !avctx->extradata) return -1;
3403 if (!(avctx->flags & CODEC_FLAG_GRAY))3570 if (!(avctx->flags & CODEC_FLAG_GRAY))
3404 avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);3571 avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
@@ -3420,7 +3587,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) · 15 unmodified lines
3420 3587
3421 cur_width = avctx->coded_width = avctx->width;3588 cur_width = avctx->coded_width = avctx->width;
3422 cur_height = avctx->coded_height = avctx->height;3589 cur_height = avctx->coded_height = avctx->height;
3423 if (avctx->codec_id == CODEC_ID_WMV3)3590 if (avctx->codec_id == CODEC_ID_WMV3 || avctx->codec_id == CODEC_ID_WMV3IMAGE)
3424 {3591 {
3425 int count = 0;3592 int count = 0;
3426 3593
@@ -3562,6 +3729,25 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) · 135 unmodified lines
3562 }3729 }
3563 3730
3564 ff_intrax8_common_init(&v->x8,s);3731 ff_intrax8_common_init(&v->x8,s);
3732
3733 if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
3734 for (i = 0; i < 4; i++)
3735 if (!(v->sr_rows[i>>1][i%2] = av_malloc(v->output_width))) return -1;
3736
3737 s->low_delay = 1;
3738
3739 v->sprite_width = avctx->coded_width;
3740 v->sprite_height = avctx->coded_height;
3741
3742 avctx->coded_width = avctx->width = v->output_width;
3743 avctx->coded_height = avctx->height = v->output_height;
3744
3745 // prevent 16.16 overflows
3746 if (v->sprite_width > 1<<14 ||
3747 v->sprite_height > 1<<14 ||
3748 v->output_width > 1<<14 ||
3749 v->output_height > 1<<14) return -1;
3750 }
3565 return 0;3751 return 0;
3566}3752}
3567 3753
@@ -3614,7 +3800,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, · 46 unmodified lines
3614 }3800 }
3615 3801
3616 //for advanced profile we may need to parse and unescape data3802 //for advanced profile we may need to parse and unescape data
3617 if (avctx->codec_id == CODEC_ID_VC1) {3803 if (avctx->codec_id == CODEC_ID_VC1 || avctx->codec_id == CODEC_ID_VC1IMAGE) {
3618 int buf_size2 = 0;3804 int buf_size2 = 0;
3619 buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);3805 buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
3620 3806
@@ -3679,8 +3865,19 @@ static int vc1_decode_frame(AVCodecContext *avctx, · 58 unmodified lines
3679 if (v->res_sprite) {3865 if (v->res_sprite) {
3680 v->new_sprite = !get_bits1(&s->gb);3866 v->new_sprite = !get_bits1(&s->gb);
3681 v->two_sprites = get_bits1(&s->gb);3867 v->two_sprites = get_bits1(&s->gb);
3682 if (!v->new_sprite)3868 /* res_sprite means a Windows Media Image stream, CODEC_ID_*IMAGE means
3683 goto end;3869 we're using the sprite compositor. These are intentionally kept separate
3870 so you can get the raw sprites by using the wmv3 decoder for WMVP or
3871 the vc1 one for WVP2 */
3872 if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
3873 if (v->new_sprite) {
3874 // switch AVCodecContext parameters to those of the sprites
3875 avctx->width = avctx->coded_width = v->sprite_width;
3876 avctx->height = avctx->coded_height = v->sprite_height;
3877 } else {
3878 goto image;
3879 }
3880 }
3684 }3881 }
3685 3882
3686 // do parse frame header3883 // do parse frame header
@@ -3694,8 +3891,10 @@ static int vc1_decode_frame(AVCodecContext *avctx, · 7 unmodified lines
3694 }3891 }
3695 }3892 }
3696 3893
3697 if (v->res_sprite && s->pict_type!=AV_PICTURE_TYPE_I) {3894 if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE)
3698 av_log(v->s.avctx, AV_LOG_WARNING, "Sprite decoder: expected I-frame\n");3895 && s->pict_type!=AV_PICTURE_TYPE_I) {
3896 av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected I-frame\n");
3897 goto err;
3699 }3898 }
3700 3899
3701 // for skipping the frame3900 // for skipping the frame
@@ -3758,6 +3957,19 @@ static int vc1_decode_frame(AVCodecContext *avctx, · 56 unmodified lines
3758 3957
3759assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);3958assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
3760assert(s->current_picture.f.pict_type == s->pict_type);3959assert(s->current_picture.f.pict_type == s->pict_type);
3960
3961 if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
3962image:
3963 avctx->width = avctx->coded_width = v->output_width;
3964 avctx->height = avctx->coded_height = v->output_height;
3965 if (avctx->skip_frame >= AVDISCARD_NONREF) goto end;
3966#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
3967 if (vc1_decode_sprites(v, &s->gb)) goto err;
3968#endif
3969 *pict = v->sprite_output_frame;
3970 *data_size = sizeof(AVFrame);
3971 } else {
3972
3761 if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {3973 if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
3762 *pict= *(AVFrame*)s->current_picture_ptr;3974 *pict= *(AVFrame*)s->current_picture_ptr;
3763 } else if (s->last_picture_ptr != NULL) {3975 } else if (s->last_picture_ptr != NULL) {
@@ -3769,9 +3981,9 @@ assert(s->current_picture.f.pict_type == s->pict_type); · 5 unmodified lines
3769 ff_print_debug_info(s, pict);3981 ff_print_debug_info(s, pict);
3770 }3982 }
3771 3983
3984 }
3985
3772end:3986end:
3773 if (v->res_sprite)
3774 vc1_parse_sprites(v, &s->gb);
3775 av_free(buf2);3987 av_free(buf2);
3776 for (i = 0; i < n_slices; i++)3988 for (i = 0; i < n_slices; i++)
3777 av_free(slices[i].buf);3989 av_free(slices[i].buf);
@@ -3793,7 +4005,13 @@ err: · 15 unmodified lines
3793static av_cold int vc1_decode_end(AVCodecContext *avctx)4005static av_cold int vc1_decode_end(AVCodecContext *avctx)
3794{4006{
3795 VC1Context *v = avctx->priv_data;4007 VC1Context *v = avctx->priv_data;
4008 int i;
3796 4009
4010 if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE)
4011 && v->sprite_output_frame.data[0])
4012 avctx->release_buffer(avctx, &v->sprite_output_frame);
4013 for (i = 0; i < 4; i++)
4014 av_freep(&v->sr_rows[i>>1][i%2]);
3797 av_freep(&v->hrd_rate);4015 av_freep(&v->hrd_rate);
3798 av_freep(&v->hrd_buffer);4016 av_freep(&v->hrd_buffer);
3799 MPV_common_end(&v->s);4017 MPV_common_end(&v->s);
@@ -3880,3 +4098,35 @@ AVCodec ff_vc1_vdpau_decoder = { · 80 unmodified lines
3880 .profiles = NULL_IF_CONFIG_SMALL(profiles)4098 .profiles = NULL_IF_CONFIG_SMALL(profiles)
3881};4099};
3882#endif4100#endif
4101
4102#if CONFIG_WMV3IMAGE_DECODER
4103AVCodec ff_wmv3image_decoder = {
4104 .name = "wmv3image",
4105 .type = AVMEDIA_TYPE_VIDEO,
4106 .id = CODEC_ID_WMV3IMAGE,
4107 .priv_data_size = sizeof(VC1Context),
4108 .init = vc1_decode_init,
4109 .close = vc1_decode_end,
4110 .decode = vc1_decode_frame,
4111 .capabilities = CODEC_CAP_DR1,
4112 .flush = vc1_sprite_flush,
4113 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"),
4114 .pix_fmts = ff_pixfmt_list_420
4115};
4116#endif
4117
4118#if CONFIG_VC1IMAGE_DECODER
4119AVCodec ff_vc1image_decoder = {
4120 .name = "vc1image",
4121 .type = AVMEDIA_TYPE_VIDEO,
4122 .id = CODEC_ID_VC1IMAGE,
4123 .priv_data_size = sizeof(VC1Context),
4124 .init = vc1_decode_init,
4125 .close = vc1_decode_end,
4126 .decode = vc1_decode_frame,
4127 .capabilities = CODEC_CAP_DR1,
4128 .flush = vc1_sprite_flush,
4129 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"),
4130 .pix_fmts = ff_pixfmt_list_420
4131};
4132#endif
libavcodec/vc1dsp.c+68−0
@@ -713,6 +713,66 @@ static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a · 712 unmodified lines
713 }713 }
714}714}
715 715
716#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
717
718static void sprite_h_c(uint8_t *dst, const uint8_t *src, int offset, int advance, int count)
719{
720 while (count--) {
721 int a = src[(offset >> 16) ];
722 int b = src[(offset >> 16) + 1];
723 *dst++ = a + ((b - a) * (offset&0xFFFF) >> 16);
724 offset += advance;
725 }
726}
727
728static av_always_inline void sprite_v_template(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
729 int two_sprites, const uint8_t *src2a, const uint8_t *src2b, int offset2,
730 int alpha, int scaled, int width)
731{
732 int a1, b1, a2, b2;
733 while (width--) {
734 a1 = *src1a++;
735 if (scaled) {
736 b1 = *src1b++;
737 a1 = a1 + ((b1 - a1) * offset1 >> 16);
738 }
739 if (two_sprites) {
740 a2 = *src2a++;
741 if (scaled > 1) {
742 b2 = *src2b++;
743 a2 = a2 + ((b2 - a2) * offset2 >> 16);
744 }
745 a1 = a1 + ((a2 - a1) * alpha >> 16);
746 }
747 *dst++ = a1;
748 }
749}
750
751static void sprite_v_single_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset, int width)
752{
753 sprite_v_template(dst, src1a, src1b, offset, 0, NULL, NULL, 0, 0, 1, width);
754}
755
756static void sprite_v_double_noscale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src2a, int alpha, int width)
757{
758 sprite_v_template(dst, src1a, NULL, 0, 1, src2a, NULL, 0, alpha, 0, width);
759}
760
761static void sprite_v_double_onescale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
762 const uint8_t *src2a, int alpha, int width)
763{
764 sprite_v_template(dst, src1a, src1b, offset1, 1, src2a, NULL, 0, alpha, 1, width);
765}
766
767static void sprite_v_double_twoscale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
768 const uint8_t *src2a, const uint8_t *src2b, int offset2,
769 int alpha, int width)
770{
771 sprite_v_template(dst, src1a, src1b, offset1, 1, src2a, src2b, offset2, alpha, 2, width);
772}
773
774#endif
775
716av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {776av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
717 dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c;777 dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c;
718 dsp->vc1_inv_trans_4x8 = vc1_inv_trans_4x8_c;778 dsp->vc1_inv_trans_4x8 = vc1_inv_trans_4x8_c;
@@ -770,6 +830,14 @@ av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) { · 51 unmodified lines
770 dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c;830 dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c;
771 dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c;831 dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c;
772 832
833#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
834 dsp->sprite_h = sprite_h_c;
835 dsp->sprite_v_single = sprite_v_single_c;
836 dsp->sprite_v_double_noscale = sprite_v_double_noscale_c;
837 dsp->sprite_v_double_onescale = sprite_v_double_onescale_c;
838 dsp->sprite_v_double_twoscale = sprite_v_double_twoscale_c;
839#endif
840
773 if (HAVE_ALTIVEC)841 if (HAVE_ALTIVEC)
774 ff_vc1dsp_init_altivec(dsp);842 ff_vc1dsp_init_altivec(dsp);
775 if (HAVE_MMX)843 if (HAVE_MMX)
libavcodec/vc1dsp.h+10−0
@@ -60,6 +60,16 @@ typedef struct VC1DSPContext { · 59 unmodified lines
60 /* This is really one func used in VC-1 decoding */60 /* This is really one func used in VC-1 decoding */
61 h264_chroma_mc_func put_no_rnd_vc1_chroma_pixels_tab[3];61 h264_chroma_mc_func put_no_rnd_vc1_chroma_pixels_tab[3];
62 h264_chroma_mc_func avg_no_rnd_vc1_chroma_pixels_tab[3];62 h264_chroma_mc_func avg_no_rnd_vc1_chroma_pixels_tab[3];
63
64 /* Windows Media Image functions */
65 void (*sprite_h)(uint8_t *dst, const uint8_t *src, int offset, int advance, int count);
66 void (*sprite_v_single)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset, int width);
67 void (*sprite_v_double_noscale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src2a, int alpha, int width);
68 void (*sprite_v_double_onescale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
69 const uint8_t *src2a, int alpha, int width);
70 void (*sprite_v_double_twoscale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
71 const uint8_t *src2a, const uint8_t *src2b, int offset2,
72 int alpha, int width);
63} VC1DSPContext;73} VC1DSPContext;
64 74
65void ff_vc1dsp_init(VC1DSPContext* c);75void ff_vc1dsp_init(VC1DSPContext* c);
libavcodec/version.h+1−1
@@ -21,7 +21,7 @@ · 20 unmodified lines
21#define AVCODEC_VERSION_H21#define AVCODEC_VERSION_H
22 22
23#define LIBAVCODEC_VERSION_MAJOR 5323#define LIBAVCODEC_VERSION_MAJOR 53
24#define LIBAVCODEC_VERSION_MINOR 824#define LIBAVCODEC_VERSION_MINOR 9
25#define LIBAVCODEC_VERSION_MICRO 025#define LIBAVCODEC_VERSION_MICRO 0
26 26
27#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \27#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
libavformat/riff.c+2−2
@@ -237,10 +237,10 @@ const AVCodecTag ff_codec_bmp_tags[] = { · 236 unmodified lines
237 { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '0') },237 { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '0') },
238 { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') },238 { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') },
239 { CODEC_ID_WMV3, MKTAG('W', 'M', 'V', '3') },239 { CODEC_ID_WMV3, MKTAG('W', 'M', 'V', '3') },
240 { CODEC_ID_WMV3, MKTAG('W', 'M', 'V', 'P') },240 { CODEC_ID_WMV3IMAGE, MKTAG('W', 'M', 'V', 'P') },
241 { CODEC_ID_VC1, MKTAG('W', 'V', 'C', '1') },241 { CODEC_ID_VC1, MKTAG('W', 'V', 'C', '1') },
242 { CODEC_ID_VC1, MKTAG('W', 'M', 'V', 'A') },242 { CODEC_ID_VC1, MKTAG('W', 'M', 'V', 'A') },
243 { CODEC_ID_VC1, MKTAG('W', 'V', 'P', '2') },243 { CODEC_ID_VC1IMAGE, MKTAG('W', 'V', 'P', '2') },
244 { CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') },244 { CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') },
245 { CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') },245 { CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') },
246 { CODEC_ID_AASC, MKTAG('A', 'A', 'S', 'C') },246 { CODEC_ID_AASC, MKTAG('A', 'A', 'S', 'C') },

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t