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
4141 '-preset <presetname>'.
4242 * -intra option was removed, it's equivalent to -g 0.
4343 - XMV demuxer
44+- Windows Media Image decoder
4445
4546
4647 version 0.7:
configure+2−0
@@ -1354,6 +1354,7 @@ vc1_dxva2_hwaccel_deps="dxva2api_h DXVA_PictureParameters_wDecodedPictureIndex" · 1353 unmodified lines
13541354 vc1_dxva2_hwaccel_select="dxva2 vc1_decoder"
13551355 vc1_vaapi_hwaccel_select="vaapi vc1_decoder"
13561356 vc1_vdpau_decoder_select="vdpau vc1_decoder"
1357+vc1image_decoder_select="vc1_decoder"
13571358 vorbis_decoder_select="mdct"
13581359 vorbis_encoder_select="mdct"
13591360 vp6_decoder_select="huffman"
@@ -1374,6 +1375,7 @@ wmv3_decoder_select="vc1_decoder" · 14 unmodified lines
13741375 wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
13751376 wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
13761377 wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
1378+wmv3image_decoder_select="wmv3_decoder"
13771379 zlib_decoder_select="zlib"
13781380 zlib_encoder_select="zlib"
13791381 zmbv_decoder_select="zlib"
doc/general.texi+1−0
@@ -518,6 +518,7 @@ following image formats are supported: · 517 unmodified lines
518518 @item VMware Screen Codec / VMware Video @tab @tab X
519519 @tab Codec used in videos captured by VMware.
520520 @item Westwood Studios VQA (Vector Quantized Animation) video @tab @tab X
521+@item Windows Media Image @tab @tab X
521522 @item Windows Media Video 7 @tab X @tab X
522523 @item Windows Media Video 8 @tab X @tab X
523524 @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
203203 REGISTER_DECODER (VB, vb);
204204 REGISTER_DECODER (VC1, vc1);
205205 REGISTER_DECODER (VC1_VDPAU, vc1_vdpau);
206+ REGISTER_DECODER (VC1IMAGE, vc1image);
206207 REGISTER_DECODER (VCR1, vcr1);
207208 REGISTER_DECODER (VMDVIDEO, vmdvideo);
208209 REGISTER_DECODER (VMNC, vmnc);
@@ -217,6 +218,7 @@ void avcodec_register_all(void) · 8 unmodified lines
217218 REGISTER_ENCDEC (WMV2, wmv2);
218219 REGISTER_DECODER (WMV3, wmv3);
219220 REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau);
221+ REGISTER_DECODER (WMV3IMAGE, wmv3image);
220222 REGISTER_DECODER (WNV1, wnv1);
221223 REGISTER_DECODER (XAN_WC3, xan_wc3);
222224 REGISTER_DECODER (XAN_WC4, xan_wc4);
libavcodec/avcodec.h+2−0
@@ -208,6 +208,8 @@ enum CodecID { · 207 unmodified lines
208208 CODEC_ID_PRORES,
209209 CODEC_ID_JV,
210210 CODEC_ID_DFA,
211+ CODEC_ID_WMV3IMAGE,
212+ CODEC_ID_VC1IMAGE,
211213
212214 /* various PCM "codecs" */
213215 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
9191 break;
9292 case CODEC_ID_VC1:
9393 case CODEC_ID_WMV3:
94+ case CODEC_ID_VC1IMAGE:
95+ case CODEC_ID_WMV3IMAGE:
9496 s->h263_pred = 1;
9597 s->msmpeg4_version=6;
9698 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
208208 */
209209 static void free_frame_buffer(MpegEncContext *s, Picture *pic)
210210 {
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);
212217 av_freep(&pic->f.hwaccel_picture_private);
213218 }
214219
@@ -230,7 +235,10 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) · 15 unmodified lines
230235 }
231236 }
232237
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);
234242
235243 if (r < 0 || !pic->f.age || !pic->f.type || !pic->f.data[0]) {
236244 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
314314 "Old interlaced mode is not supported\n");
315315 return -1;
316316 }
317− if (v->res_sprite) {
318− av_log(avctx, AV_LOG_ERROR, "WMVP is not fully supported\n");
319− }
320317 }
321318
322319 // (fps-2)/4 (->30)
libavcodec/vc1.h+3−0
@@ -311,6 +311,9 @@ typedef struct VC1Context{ · 310 unmodified lines
311311 //@{
312312 int new_sprite;
313313 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
314317 //@}
315318
316319 int p_frame_skipped;
libavcodec/vc1dec.c+327−77
@@ -3278,116 +3278,279 @@ static void vc1_decode_blocks(VC1Context *v) · 3277 unmodified lines
32783278 }
32793279 }
32803280
3281−static inline float get_float_val(GetBitContext* gb)
3281+#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
3282+
3283+typedef 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+
3302+static inline int get_fp_val(GetBitContext* gb)
32823303 {
3283− return (float)get_bits_long(gb, 30) / (1<<15) - (1<<14);
3304+ return (get_bits_long(gb, 30) - (1<<29)) << 1;
32843305 }
32853306
3286−static void vc1_sprite_parse_transform(VC1Context *v, GetBitContext* gb, float c[7])
3307+static void vc1_sprite_parse_transform(GetBitContext* gb, int c[7])
32873308 {
3288− c[1] = c[3] = 0.0f;
3309+ c[1] = c[3] = 0;
32893310
32903311 switch (get_bits(gb, 2)) {
32913312 case 0:
3292− c[0] = 1.0f;
3293− c[2] = get_float_val(gb);
3294− c[4] = 1.0f;
3313+ c[0] = 1<<16;
3314+ c[2] = get_fp_val(gb);
3315+ c[4] = 1<<16;
32953316 break;
32963317 case 1:
3297− c[0] = c[4] = get_float_val(gb);
3298− c[2] = get_float_val(gb);
3318+ c[0] = c[4] = get_fp_val(gb);
3319+ c[2] = get_fp_val(gb);
32993320 break;
33003321 case 2:
3301− c[0] = get_float_val(gb);
3302− c[2] = get_float_val(gb);
3303− c[4] = get_float_val(gb);
3322+ c[0] = get_fp_val(gb);
3323+ c[2] = get_fp_val(gb);
3324+ c[4] = get_fp_val(gb);
33043325 break;
33053326 case 3:
3306− av_log_ask_for_sample(v->s.avctx, NULL);
3307− c[0] = get_float_val(gb);
3308− c[1] = get_float_val(gb);
3309− c[2] = get_float_val(gb);
3310− c[3] = get_float_val(gb);
3311− c[4] = get_float_val(gb);
3327+ c[0] = get_fp_val(gb);
3328+ c[1] = get_fp_val(gb);
3329+ c[2] = get_fp_val(gb);
3330+ c[3] = get_fp_val(gb);
3331+ c[4] = get_fp_val(gb);
33123332 break;
33133333 }
3314− c[5] = get_float_val(gb);
3334+ c[5] = get_fp_val(gb);
33153335 if (get_bits1(gb))
3316− c[6] = get_float_val(gb);
3336+ c[6] = get_fp_val(gb);
33173337 else
3318− c[6] = 1.0f;
3338+ c[6] = 1<<16;
33193339 }
33203340
3321−static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb)
3341+static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd)
33223342 {
3323− int effect_type, effect_flag, effect_pcount1, effect_pcount2, i;
3324− float effect_params1[14], effect_params2[10];
3325−
3326− float coefs[2][7];
3327− vc1_sprite_parse_transform(v, gb, coefs[0]);
3328− av_log(v->s.avctx, AV_LOG_DEBUG, "S1:");
3329− for (i = 0; i < 7; i++)
3330− av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", coefs[0][i]);
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:");
3343+ AVCodecContext *avctx = v->s.avctx;
3344+ int sprite, i;
3345+
3346+ for (sprite = 0; sprite <= v->two_sprites; sprite++) {
3347+ vc1_sprite_parse_transform(gb, sd->coefs[sprite]);
3348+ if (sd->coefs[sprite][1] || sd->coefs[sprite][3])
3349+ av_log_ask_for_sample(avctx, "Rotation coefficients are not zero");
3350+ av_log(avctx, AV_LOG_DEBUG, sprite ? "S2:" : "S1:");
33363351 for (i = 0; i < 7; i++)
3337− av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", coefs[1][i]);
3338− av_log(v->s.avctx, AV_LOG_DEBUG, "\n");
3352+ av_log(avctx, AV_LOG_DEBUG, " %d.%.3d",
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");
33393356 }
3357+
33403358 skip_bits(gb, 2);
3341− if (effect_type = get_bits_long(gb, 30)){
3342− switch (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;
3359+ if (sd->effect_type = get_bits_long(gb, 30)) {
3360+ switch (sd->effect_pcount1 = get_bits(gb, 4)) {
33473361 case 7:
3348− vc1_sprite_parse_transform(v, gb, effect_params1);
3362+ vc1_sprite_parse_transform(gb, sd->effect_params1);
33493363 break;
33503364 case 14:
3351− vc1_sprite_parse_transform(v, gb, effect_params1);
3352− vc1_sprite_parse_transform(v, gb, &effect_params1[7]);
3365+ vc1_sprite_parse_transform(gb, sd->effect_params1);
3366+ vc1_sprite_parse_transform(gb, sd->effect_params1 + 7);
33533367 break;
33543368 default:
3355− av_log_ask_for_sample(v->s.avctx, NULL);
3356− return;
3369+ for (i = 0; i < sd->effect_pcount1; i++)
3370+ sd->effect_params1[i] = get_fp_val(gb);
33573371 }
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]) {
33593373 // 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);
3361− for (i = 0; i < effect_pcount1; i++)
3362− av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", effect_params1[i]);
3363− av_log(v->s.avctx, AV_LOG_DEBUG, "\n");
3374+ av_log(avctx, AV_LOG_DEBUG, "Effect: %d; params: ", sd->effect_type);
3375+ for (i = 0; i < sd->effect_pcount1; i++)
3376+ av_log(avctx, AV_LOG_DEBUG, " %d.%.2d",
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");
33643380 }
33653381
3366− effect_pcount2 = get_bits(gb, 16);
3367− if (effect_pcount2 > 10) {
3368− av_log(v->s.avctx, AV_LOG_ERROR, "Too many effect parameters\n");
3382+ sd->effect_pcount2 = get_bits(gb, 16);
3383+ if (sd->effect_pcount2 > 10) {
3384+ av_log(avctx, AV_LOG_ERROR, "Too many effect parameters\n");
33693385 return;
3370− } else if (effect_pcount2) {
3371− i = 0;
3372− av_log(v->s.avctx, AV_LOG_DEBUG, "Effect params 2: ");
3373− while (i < effect_pcount2){
3374− effect_params2[i] = get_float_val(gb);
3375− av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", effect_params2[i]);
3376− i++;
3386+ } else if (sd->effect_pcount2) {
3387+ i = -1;
3388+ av_log(avctx, AV_LOG_DEBUG, "Effect params 2: ");
3389+ while (++i < sd->effect_pcount2){
3390+ sd->effect_params2[i] = get_fp_val(gb);
3391+ av_log(avctx, AV_LOG_DEBUG, " %d.%.2d",
3392+ sd->effect_params2[i] / (1<<16),
3393+ (abs(sd->effect_params2[i]) & 0xFFFF) * 1000 / (1<<16));
33773394 }
3378− av_log(v->s.avctx, AV_LOG_DEBUG, "\n");
3395+ av_log(avctx, AV_LOG_DEBUG, "\n");
33793396 }
33803397 }
3381− if (effect_flag = get_bits1(gb))
3382− av_log(v->s.avctx, AV_LOG_DEBUG, "Effect flag set\n");
3398+ if (sd->effect_flag = get_bits1(gb))
3399+ av_log(avctx, AV_LOG_DEBUG, "Effect flag set\n");
33833400
33843401 if (get_bits_count(gb) >= gb->size_in_bits +
3385− (v->s.avctx->codec_id == CODEC_ID_WMV3 ? 64 : 0))
3386− av_log(v->s.avctx, AV_LOG_ERROR, "Buffer overrun\n");
3402+ (avctx->codec_id == CODEC_ID_WMV3IMAGE ? 64 : 0))
3403+ av_log(avctx, AV_LOG_ERROR, "Buffer overrun\n");
33873404 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+
3408+static 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+
3501+static 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+
3534+static 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]);
33893550 }
33903551
3552+#endif
3553+
33913554 /** Initialize a VC1/WMV3 decoder
33923555 * @todo TODO: Handle VC-1 IDUs (Transport level?)
33933556 * @todo TODO: Decypher remaining bits in extra_data
@@ -3399,6 +3562,10 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) · 5 unmodified lines
33993562 GetBitContext gb;
34003563 int i, cur_width, cur_height;
34013564
3565+ /* save the container output size for WMImage */
3566+ v->output_width = avctx->width;
3567+ v->output_height = avctx->height;
3568+
34023569 if (!avctx->extradata_size || !avctx->extradata) return -1;
34033570 if (!(avctx->flags & CODEC_FLAG_GRAY))
34043571 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
34203587
34213588 cur_width = avctx->coded_width = avctx->width;
34223589 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)
34243591 {
34253592 int count = 0;
34263593
@@ -3562,6 +3729,25 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) · 135 unmodified lines
35623729 }
35633730
35643731 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+ }
35653751 return 0;
35663752 }
35673753
@@ -3614,7 +3800,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, · 46 unmodified lines
36143800 }
36153801
36163802 //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) {
36183804 int buf_size2 = 0;
36193805 buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
36203806
@@ -3679,8 +3865,19 @@ static int vc1_decode_frame(AVCodecContext *avctx, · 58 unmodified lines
36793865 if (v->res_sprite) {
36803866 v->new_sprite = !get_bits1(&s->gb);
36813867 v->two_sprites = get_bits1(&s->gb);
3682− if (!v->new_sprite)
3683− goto end;
3868+ /* res_sprite means a Windows Media Image stream, CODEC_ID_*IMAGE means
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+ }
36843881 }
36853882
36863883 // do parse frame header
@@ -3694,8 +3891,10 @@ static int vc1_decode_frame(AVCodecContext *avctx, · 7 unmodified lines
36943891 }
36953892 }
36963893
3697− if (v->res_sprite && s->pict_type!=AV_PICTURE_TYPE_I) {
3698− av_log(v->s.avctx, AV_LOG_WARNING, "Sprite decoder: expected I-frame\n");
3894+ if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE)
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;
36993898 }
37003899
37013900 // for skipping the frame
@@ -3758,6 +3957,19 @@ static int vc1_decode_frame(AVCodecContext *avctx, · 56 unmodified lines
37583957
37593958 assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
37603959 assert(s->current_picture.f.pict_type == s->pict_type);
3960+
3961+ if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
3962+image:
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+
37613973 if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
37623974 *pict= *(AVFrame*)s->current_picture_ptr;
37633975 } else if (s->last_picture_ptr != NULL) {
@@ -3769,9 +3981,9 @@ assert(s->current_picture.f.pict_type == s->pict_type); · 5 unmodified lines
37693981 ff_print_debug_info(s, pict);
37703982 }
37713983
3984+ }
3985+
37723986 end:
3773− if (v->res_sprite)
3774− vc1_parse_sprites(v, &s->gb);
37753987 av_free(buf2);
37763988 for (i = 0; i < n_slices; i++)
37773989 av_free(slices[i].buf);
@@ -3793,7 +4005,13 @@ err: · 15 unmodified lines
37934005 static av_cold int vc1_decode_end(AVCodecContext *avctx)
37944006 {
37954007 VC1Context *v = avctx->priv_data;
4008+ int i;
37964009
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]);
37974015 av_freep(&v->hrd_rate);
37984016 av_freep(&v->hrd_buffer);
37994017 MPV_common_end(&v->s);
@@ -3880,3 +4098,35 @@ AVCodec ff_vc1_vdpau_decoder = { · 80 unmodified lines
38804098 .profiles = NULL_IF_CONFIG_SMALL(profiles)
38814099 };
38824100 #endif
4101+
4102+#if CONFIG_WMV3IMAGE_DECODER
4103+AVCodec 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
4119+AVCodec 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
713713 }
714714 }
715715
716+#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
717+
718+static 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+
728+static 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+
751+static 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+
756+static 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+
761+static 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+
767+static 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+
716776 av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
717777 dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c;
718778 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
770830 dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c;
771831 dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c;
772832
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+
773841 if (HAVE_ALTIVEC)
774842 ff_vc1dsp_init_altivec(dsp);
775843 if (HAVE_MMX)
libavcodec/vc1dsp.h+10−0
@@ -60,6 +60,16 @@ typedef struct VC1DSPContext { · 59 unmodified lines
6060 /* This is really one func used in VC-1 decoding */
6161 h264_chroma_mc_func put_no_rnd_vc1_chroma_pixels_tab[3];
6262 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);
6373 } VC1DSPContext;
6474
6575 void ff_vc1dsp_init(VC1DSPContext* c);
libavcodec/version.h+1−1
@@ -21,7 +21,7 @@ · 20 unmodified lines
2121 #define AVCODEC_VERSION_H
2222
2323 #define LIBAVCODEC_VERSION_MAJOR 53
24−#define LIBAVCODEC_VERSION_MINOR 8
24+#define LIBAVCODEC_VERSION_MINOR 9
2525 #define LIBAVCODEC_VERSION_MICRO 0
2626
2727 #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
237237 { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '0') },
238238 { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') },
239239 { 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') },
241241 { CODEC_ID_VC1, MKTAG('W', 'V', 'C', '1') },
242242 { 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') },
244244 { CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') },
245245 { CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') },
246246 { 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