|
|
|
@ -3097,6 +3097,116 @@ static void vc1_decode_blocks(VC1Context *v, int mby_start, int mby_end) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline float get_float_val(GetBitContext* gb) |
|
|
|
|
{ |
|
|
|
|
return (float)get_bits_long(gb, 30) / (1<<15) - (1<<14); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void vc1_sprite_parse_transform(VC1Context *v, GetBitContext* gb, float c[7]) |
|
|
|
|
{ |
|
|
|
|
c[1] = c[3] = 0.0f; |
|
|
|
|
|
|
|
|
|
switch (get_bits(gb, 2)) { |
|
|
|
|
case 0: |
|
|
|
|
c[0] = 1.0f; |
|
|
|
|
c[2] = get_float_val(gb); |
|
|
|
|
c[4] = 1.0f; |
|
|
|
|
break; |
|
|
|
|
case 1: |
|
|
|
|
c[0] = c[4] = get_float_val(gb); |
|
|
|
|
c[2] = get_float_val(gb); |
|
|
|
|
break; |
|
|
|
|
case 2: |
|
|
|
|
c[0] = get_float_val(gb); |
|
|
|
|
c[2] = get_float_val(gb); |
|
|
|
|
c[4] = get_float_val(gb); |
|
|
|
|
break; |
|
|
|
|
case 3: |
|
|
|
|
av_log_ask_for_sample(v->s.avctx, NULL); |
|
|
|
|
c[0] = get_float_val(gb); |
|
|
|
|
c[1] = get_float_val(gb); |
|
|
|
|
c[2] = get_float_val(gb); |
|
|
|
|
c[3] = get_float_val(gb); |
|
|
|
|
c[4] = get_float_val(gb); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
c[5] = get_float_val(gb); |
|
|
|
|
if (get_bits1(gb)) |
|
|
|
|
c[6] = get_float_val(gb); |
|
|
|
|
else |
|
|
|
|
c[6] = 1.0f; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb) |
|
|
|
|
{ |
|
|
|
|
int effect_type, effect_flag, effect_pcount1, effect_pcount2, i; |
|
|
|
|
float effect_params1[14], effect_params2[10]; |
|
|
|
|
|
|
|
|
|
float coefs[2][7]; |
|
|
|
|
vc1_sprite_parse_transform(v, gb, coefs[0]); |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, "S1:"); |
|
|
|
|
for (i = 0; i < 7; i++) |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", coefs[0][i]); |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, "\n"); |
|
|
|
|
|
|
|
|
|
if (v->two_sprites) { |
|
|
|
|
vc1_sprite_parse_transform(v, gb, coefs[1]); |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, "S2:"); |
|
|
|
|
for (i = 0; i < 7; i++) |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", coefs[1][i]); |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, "\n"); |
|
|
|
|
} |
|
|
|
|
skip_bits(gb, 2); |
|
|
|
|
if (effect_type = get_bits_long(gb, 30)){ |
|
|
|
|
switch (effect_pcount1 = get_bits(gb, 4)) { |
|
|
|
|
case 2: |
|
|
|
|
effect_params1[0] = get_float_val(gb); |
|
|
|
|
effect_params1[1] = get_float_val(gb); |
|
|
|
|
break; |
|
|
|
|
case 7: |
|
|
|
|
vc1_sprite_parse_transform(v, gb, effect_params1); |
|
|
|
|
break; |
|
|
|
|
case 14: |
|
|
|
|
vc1_sprite_parse_transform(v, gb, effect_params1); |
|
|
|
|
vc1_sprite_parse_transform(v, gb, &effect_params1[7]); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
av_log_ask_for_sample(v->s.avctx, NULL); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (effect_type != 13 || effect_params1[0] != coefs[0][6]) { |
|
|
|
|
// effect 13 is simple alpha blending and matches the opacity above
|
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, "Effect: %d; params: ", effect_type); |
|
|
|
|
for (i = 0; i < effect_pcount1; i++) |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", effect_params1[i]); |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, "\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
effect_pcount2 = get_bits(gb, 16); |
|
|
|
|
if (effect_pcount2 > 10) { |
|
|
|
|
av_log(v->s.avctx, AV_LOG_ERROR, "Too many effect parameters\n"); |
|
|
|
|
return; |
|
|
|
|
} else if (effect_pcount2) { |
|
|
|
|
i = 0; |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, "Effect params 2: "); |
|
|
|
|
while (i < effect_pcount2){ |
|
|
|
|
effect_params2[i] = get_float_val(gb); |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", effect_params2[i]); |
|
|
|
|
i++; |
|
|
|
|
} |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, "\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (effect_flag = get_bits1(gb)) |
|
|
|
|
av_log(v->s.avctx, AV_LOG_DEBUG, "Effect flag set\n"); |
|
|
|
|
|
|
|
|
|
if (get_bits_count(gb) >= gb->size_in_bits + |
|
|
|
|
(v->s.avctx->codec_id == CODEC_ID_WMV3 ? 64 : 0)) |
|
|
|
|
av_log(v->s.avctx, AV_LOG_ERROR, "Buffer overrun\n"); |
|
|
|
|
if (get_bits_count(gb) < gb->size_in_bits - 8) |
|
|
|
|
av_log(v->s.avctx, AV_LOG_WARNING, "Buffer not fully read\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** Initialize a VC1/WMV3 decoder
|
|
|
|
|
* @todo TODO: Handle VC-1 IDUs (Transport level?) |
|
|
|
|
* @todo TODO: Decypher remaining bits in extra_data |
|
|
|
@ -3160,7 +3270,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) |
|
|
|
|
{ |
|
|
|
|
av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count); |
|
|
|
|
} |
|
|
|
|
} else { // VC1/WVC1
|
|
|
|
|
} else { // VC1/WVC1/WVP2
|
|
|
|
|
const uint8_t *start = avctx->extradata; |
|
|
|
|
uint8_t *end = avctx->extradata + avctx->extradata_size; |
|
|
|
|
const uint8_t *next; |
|
|
|
@ -3204,6 +3314,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
v->res_sprite = (avctx->codec_tag == MKTAG('W','V','P','2')); |
|
|
|
|
} |
|
|
|
|
avctx->profile = v->profile; |
|
|
|
|
if (v->profile == PROFILE_ADVANCED) |
|
|
|
@ -3359,6 +3470,14 @@ static int vc1_decode_frame(AVCodecContext *avctx, |
|
|
|
|
init_get_bits(&s->gb, buf2, buf_size2*8); |
|
|
|
|
} else |
|
|
|
|
init_get_bits(&s->gb, buf, buf_size*8); |
|
|
|
|
|
|
|
|
|
if (v->res_sprite) { |
|
|
|
|
v->new_sprite = !get_bits1(&s->gb); |
|
|
|
|
v->two_sprites = get_bits1(&s->gb); |
|
|
|
|
if (!v->new_sprite) |
|
|
|
|
goto end; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// do parse frame header
|
|
|
|
|
if(v->profile < PROFILE_ADVANCED) { |
|
|
|
|
if(vc1_parse_frame_header(v, &s->gb) == -1) { |
|
|
|
@ -3370,8 +3489,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(v->res_sprite && (s->pict_type!=FF_I_TYPE)){ |
|
|
|
|
goto err; |
|
|
|
|
if (v->res_sprite && s->pict_type!=FF_I_TYPE) { |
|
|
|
|
av_log(v->s.avctx, AV_LOG_WARNING, "Sprite decoder: expected I-frame\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// for skipping the frame
|
|
|
|
@ -3455,6 +3574,8 @@ assert(s->current_picture.pict_type == s->pict_type); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
end: |
|
|
|
|
if (v->res_sprite) |
|
|
|
|
vc1_parse_sprites(v, &s->gb); |
|
|
|
|
av_free(buf2); |
|
|
|
|
for (i = 0; i < n_slices; i++) |
|
|
|
|
av_free(slices[i].buf); |
|
|
|
|