|
|
|
@ -3551,6 +3551,58 @@ static void vc1_sprite_flush(AVCodecContext *avctx) |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) |
|
|
|
|
{ |
|
|
|
|
MpegEncContext *s = &v->s; |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
/* Allocate mb bitplanes */ |
|
|
|
|
v->mv_type_mb_plane = av_malloc(s->mb_stride * s->mb_height); |
|
|
|
|
v->direct_mb_plane = av_malloc(s->mb_stride * s->mb_height); |
|
|
|
|
v->acpred_plane = av_malloc(s->mb_stride * s->mb_height); |
|
|
|
|
v->over_flags_plane = av_malloc(s->mb_stride * s->mb_height); |
|
|
|
|
|
|
|
|
|
v->n_allocated_blks = s->mb_width + 2; |
|
|
|
|
v->block = av_malloc(sizeof(*v->block) * v->n_allocated_blks); |
|
|
|
|
v->cbp_base = av_malloc(sizeof(v->cbp_base[0]) * 2 * s->mb_stride); |
|
|
|
|
v->cbp = v->cbp_base + s->mb_stride; |
|
|
|
|
v->ttblk_base = av_malloc(sizeof(v->ttblk_base[0]) * 2 * s->mb_stride); |
|
|
|
|
v->ttblk = v->ttblk_base + s->mb_stride; |
|
|
|
|
v->is_intra_base = av_malloc(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride); |
|
|
|
|
v->is_intra = v->is_intra_base + s->mb_stride; |
|
|
|
|
v->luma_mv_base = av_malloc(sizeof(v->luma_mv_base[0]) * 2 * s->mb_stride); |
|
|
|
|
v->luma_mv = v->luma_mv_base + s->mb_stride; |
|
|
|
|
|
|
|
|
|
/* allocate block type info in that way so it could be used with s->block_index[] */ |
|
|
|
|
v->mb_type_base = av_malloc(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); |
|
|
|
|
v->mb_type[0] = v->mb_type_base + s->b8_stride + 1; |
|
|
|
|
v->mb_type[1] = v->mb_type_base + s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride + 1; |
|
|
|
|
v->mb_type[2] = v->mb_type[1] + s->mb_stride * (s->mb_height + 1); |
|
|
|
|
|
|
|
|
|
/* Init coded blocks info */ |
|
|
|
|
if (v->profile == PROFILE_ADVANCED) |
|
|
|
|
{ |
|
|
|
|
// if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0)
|
|
|
|
|
// return -1;
|
|
|
|
|
// if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0)
|
|
|
|
|
// return -1;
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ff_intrax8_common_init(&v->x8,s); |
|
|
|
|
|
|
|
|
|
if (s->avctx->codec_id == CODEC_ID_WMV3IMAGE || s->avctx->codec_id == CODEC_ID_VC1IMAGE) { |
|
|
|
|
for (i = 0; i < 4; i++) |
|
|
|
|
if (!(v->sr_rows[i>>1][i%2] = av_malloc(v->output_width))) return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!v->mv_type_mb_plane || !v->direct_mb_plane || !v->acpred_plane || !v->over_flags_plane || |
|
|
|
|
!v->block || !v->cbp_base || !v->ttblk_base || !v->is_intra_base || !v->luma_mv_base || |
|
|
|
|
!v->mb_type_base) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** Initialize a VC1/WMV3 decoder
|
|
|
|
|
* @todo TODO: Handle VC-1 IDUs (Transport level?) |
|
|
|
|
* @todo TODO: Decypher remaining bits in extra_data |
|
|
|
@ -3560,7 +3612,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) |
|
|
|
|
VC1Context *v = avctx->priv_data; |
|
|
|
|
MpegEncContext *s = &v->s; |
|
|
|
|
GetBitContext gb; |
|
|
|
|
int i, cur_width, cur_height; |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
/* save the container output size for WMImage */ |
|
|
|
|
v->output_width = avctx->width; |
|
|
|
@ -3580,13 +3632,9 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) |
|
|
|
|
avctx->idct_algo=FF_IDCT_WMV2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(ff_msmpeg4_decode_init(avctx) < 0) |
|
|
|
|
return -1; |
|
|
|
|
if (vc1_init_common(v) < 0) return -1; |
|
|
|
|
ff_vc1dsp_init(&v->vc1dsp); |
|
|
|
|
|
|
|
|
|
cur_width = avctx->coded_width = avctx->width; |
|
|
|
|
cur_height = avctx->coded_height = avctx->height; |
|
|
|
|
if (avctx->codec_id == CODEC_ID_WMV3 || avctx->codec_id == CODEC_ID_WMV3IMAGE) |
|
|
|
|
{ |
|
|
|
|
int count = 0; |
|
|
|
@ -3657,25 +3705,12 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) |
|
|
|
|
} |
|
|
|
|
v->res_sprite = (avctx->codec_tag == MKTAG('W','V','P','2')); |
|
|
|
|
} |
|
|
|
|
// Sequence header information may not have been parsed
|
|
|
|
|
// yet when ff_msmpeg4_decode_init was called the fist time
|
|
|
|
|
// above. If sequence information changes, we need to call
|
|
|
|
|
// it again.
|
|
|
|
|
if (cur_width != avctx->width || |
|
|
|
|
cur_height != avctx->height) { |
|
|
|
|
MPV_common_end(s); |
|
|
|
|
if(ff_msmpeg4_decode_init(avctx) < 0) |
|
|
|
|
return -1; |
|
|
|
|
avctx->coded_width = avctx->width; |
|
|
|
|
avctx->coded_height = avctx->height; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
avctx->profile = v->profile; |
|
|
|
|
if (v->profile == PROFILE_ADVANCED) |
|
|
|
|
avctx->level = v->level; |
|
|
|
|
|
|
|
|
|
avctx->has_b_frames= !!(avctx->max_b_frames); |
|
|
|
|
s->low_delay = !avctx->has_b_frames; |
|
|
|
|
|
|
|
|
|
s->mb_width = (avctx->coded_width+15)>>4; |
|
|
|
|
s->mb_height = (avctx->coded_height+15)>>4; |
|
|
|
@ -3696,46 +3731,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) |
|
|
|
|
v->top_blk_sh = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Allocate mb bitplanes */ |
|
|
|
|
v->mv_type_mb_plane = av_malloc(s->mb_stride * s->mb_height); |
|
|
|
|
v->direct_mb_plane = av_malloc(s->mb_stride * s->mb_height); |
|
|
|
|
v->acpred_plane = av_malloc(s->mb_stride * s->mb_height); |
|
|
|
|
v->over_flags_plane = av_malloc(s->mb_stride * s->mb_height); |
|
|
|
|
|
|
|
|
|
v->n_allocated_blks = s->mb_width + 2; |
|
|
|
|
v->block = av_malloc(sizeof(*v->block) * v->n_allocated_blks); |
|
|
|
|
v->cbp_base = av_malloc(sizeof(v->cbp_base[0]) * 2 * s->mb_stride); |
|
|
|
|
v->cbp = v->cbp_base + s->mb_stride; |
|
|
|
|
v->ttblk_base = av_malloc(sizeof(v->ttblk_base[0]) * 2 * s->mb_stride); |
|
|
|
|
v->ttblk = v->ttblk_base + s->mb_stride; |
|
|
|
|
v->is_intra_base = av_malloc(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride); |
|
|
|
|
v->is_intra = v->is_intra_base + s->mb_stride; |
|
|
|
|
v->luma_mv_base = av_malloc(sizeof(v->luma_mv_base[0]) * 2 * s->mb_stride); |
|
|
|
|
v->luma_mv = v->luma_mv_base + s->mb_stride; |
|
|
|
|
|
|
|
|
|
/* allocate block type info in that way so it could be used with s->block_index[] */ |
|
|
|
|
v->mb_type_base = av_malloc(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); |
|
|
|
|
v->mb_type[0] = v->mb_type_base + s->b8_stride + 1; |
|
|
|
|
v->mb_type[1] = v->mb_type_base + s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride + 1; |
|
|
|
|
v->mb_type[2] = v->mb_type[1] + s->mb_stride * (s->mb_height + 1); |
|
|
|
|
|
|
|
|
|
/* Init coded blocks info */ |
|
|
|
|
if (v->profile == PROFILE_ADVANCED) |
|
|
|
|
{ |
|
|
|
|
// if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0)
|
|
|
|
|
// return -1;
|
|
|
|
|
// if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0)
|
|
|
|
|
// return -1;
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ff_intrax8_common_init(&v->x8,s); |
|
|
|
|
|
|
|
|
|
if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) { |
|
|
|
|
for (i = 0; i < 4; i++) |
|
|
|
|
if (!(v->sr_rows[i>>1][i%2] = av_malloc(v->output_width))) return -1; |
|
|
|
|
|
|
|
|
|
s->low_delay = 1; |
|
|
|
|
|
|
|
|
|
v->sprite_width = avctx->coded_width; |
|
|
|
|
v->sprite_height = avctx->coded_height; |
|
|
|
|
|
|
|
|
@ -3751,6 +3747,36 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** Close a VC1/WMV3 decoder
|
|
|
|
|
* @warning Initial try at using MpegEncContext stuff |
|
|
|
|
*/ |
|
|
|
|
static av_cold int vc1_decode_end(AVCodecContext *avctx) |
|
|
|
|
{ |
|
|
|
|
VC1Context *v = avctx->priv_data; |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) |
|
|
|
|
&& v->sprite_output_frame.data[0]) |
|
|
|
|
avctx->release_buffer(avctx, &v->sprite_output_frame); |
|
|
|
|
for (i = 0; i < 4; i++) |
|
|
|
|
av_freep(&v->sr_rows[i>>1][i%2]); |
|
|
|
|
av_freep(&v->hrd_rate); |
|
|
|
|
av_freep(&v->hrd_buffer); |
|
|
|
|
MPV_common_end(&v->s); |
|
|
|
|
av_freep(&v->mv_type_mb_plane); |
|
|
|
|
av_freep(&v->direct_mb_plane); |
|
|
|
|
av_freep(&v->acpred_plane); |
|
|
|
|
av_freep(&v->over_flags_plane); |
|
|
|
|
av_freep(&v->mb_type_base); |
|
|
|
|
av_freep(&v->block); |
|
|
|
|
av_freep(&v->cbp_base); |
|
|
|
|
av_freep(&v->ttblk_base); |
|
|
|
|
av_freep(&v->is_intra_base); // FIXME use v->mb_type[]
|
|
|
|
|
av_freep(&v->luma_mv_base); |
|
|
|
|
ff_intrax8_common_end(&v->x8); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Decode a VC1/WMV3 frame
|
|
|
|
|
* @todo TODO: Handle VC-1 IDUs (Transport level?) |
|
|
|
@ -3785,13 +3811,6 @@ static int vc1_decode_frame(AVCodecContext *avctx, |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* We need to set current_picture_ptr before reading the header,
|
|
|
|
|
* otherwise we cannot store anything in there. */ |
|
|
|
|
if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) { |
|
|
|
|
int i= ff_find_unused_picture(s, 0); |
|
|
|
|
s->current_picture_ptr= &s->picture[i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){ |
|
|
|
|
if (v->profile < PROFILE_ADVANCED) |
|
|
|
|
avctx->pix_fmt = PIX_FMT_VDPAU_WMV3; |
|
|
|
@ -3880,6 +3899,31 @@ static int vc1_decode_frame(AVCodecContext *avctx, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (s->context_initialized && |
|
|
|
|
(s->width != avctx->coded_width || |
|
|
|
|
s->height != avctx->coded_height)) { |
|
|
|
|
vc1_decode_end(avctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!s->context_initialized) { |
|
|
|
|
if (ff_msmpeg4_decode_init(avctx) < 0 || vc1_decode_init_alloc_tables(v) < 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
s->low_delay = !avctx->has_b_frames || v->res_sprite; |
|
|
|
|
|
|
|
|
|
if (v->profile == PROFILE_ADVANCED) { |
|
|
|
|
s->h_edge_pos = avctx->coded_width; |
|
|
|
|
s->v_edge_pos = avctx->coded_height; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* We need to set current_picture_ptr before reading the header,
|
|
|
|
|
* otherwise we cannot store anything in there. */ |
|
|
|
|
if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) { |
|
|
|
|
int i= ff_find_unused_picture(s, 0); |
|
|
|
|
s->current_picture_ptr= &s->picture[i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// do parse frame header
|
|
|
|
|
if(v->profile < PROFILE_ADVANCED) { |
|
|
|
|
if(vc1_parse_frame_header(v, &s->gb) == -1) { |
|
|
|
@ -4011,36 +4055,6 @@ err: |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Close a VC1/WMV3 decoder
|
|
|
|
|
* @warning Initial try at using MpegEncContext stuff |
|
|
|
|
*/ |
|
|
|
|
static av_cold int vc1_decode_end(AVCodecContext *avctx) |
|
|
|
|
{ |
|
|
|
|
VC1Context *v = avctx->priv_data; |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) |
|
|
|
|
&& v->sprite_output_frame.data[0]) |
|
|
|
|
avctx->release_buffer(avctx, &v->sprite_output_frame); |
|
|
|
|
for (i = 0; i < 4; i++) |
|
|
|
|
av_freep(&v->sr_rows[i>>1][i%2]); |
|
|
|
|
av_freep(&v->hrd_rate); |
|
|
|
|
av_freep(&v->hrd_buffer); |
|
|
|
|
MPV_common_end(&v->s); |
|
|
|
|
av_freep(&v->mv_type_mb_plane); |
|
|
|
|
av_freep(&v->direct_mb_plane); |
|
|
|
|
av_freep(&v->acpred_plane); |
|
|
|
|
av_freep(&v->over_flags_plane); |
|
|
|
|
av_freep(&v->mb_type_base); |
|
|
|
|
av_freep(&v->block); |
|
|
|
|
av_freep(&v->cbp_base); |
|
|
|
|
av_freep(&v->ttblk_base); |
|
|
|
|
av_freep(&v->is_intra_base); // FIXME use v->mb_type[]
|
|
|
|
|
av_freep(&v->luma_mv_base); |
|
|
|
|
ff_intrax8_common_end(&v->x8); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const AVProfile profiles[] = { |
|
|
|
|
{ FF_PROFILE_VC1_SIMPLE, "Simple" }, |
|
|
|
|
{ FF_PROFILE_VC1_MAIN, "Main" }, |
|
|
|
|