Commit 45ecda85 authored by Alberto Delmás's avatar Alberto Delmás Committed by Anton Khirnov

Windows Media Image decoder (WMVP/WVP2)

Signed-off-by: 's avatarAnton Khirnov <anton@khirnov.net>
parent 3be5a943
......@@ -41,6 +41,7 @@ easier to use. The changes are:
'-preset <presetname>'.
* -intra option was removed, it's equivalent to -g 0.
- XMV demuxer
- Windows Media Image decoder
version 0.7:
......
......@@ -1354,6 +1354,7 @@ vc1_dxva2_hwaccel_deps="dxva2api_h DXVA_PictureParameters_wDecodedPictureIndex"
vc1_dxva2_hwaccel_select="dxva2 vc1_decoder"
vc1_vaapi_hwaccel_select="vaapi vc1_decoder"
vc1_vdpau_decoder_select="vdpau vc1_decoder"
vc1image_decoder_select="vc1_decoder"
vorbis_decoder_select="mdct"
vorbis_encoder_select="mdct"
vp6_decoder_select="huffman"
......@@ -1374,6 +1375,7 @@ wmv3_decoder_select="vc1_decoder"
wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
wmv3image_decoder_select="wmv3_decoder"
zlib_decoder_select="zlib"
zlib_encoder_select="zlib"
zmbv_decoder_select="zlib"
......
......@@ -518,6 +518,7 @@ following image formats are supported:
@item VMware Screen Codec / VMware Video @tab @tab X
@tab Codec used in videos captured by VMware.
@item Westwood Studios VQA (Vector Quantized Animation) video @tab @tab X
@item Windows Media Image @tab @tab X
@item Windows Media Video 7 @tab X @tab X
@item Windows Media Video 8 @tab X @tab X
@item Windows Media Video 9 @tab @tab X
......
......@@ -203,6 +203,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (VB, vb);
REGISTER_DECODER (VC1, vc1);
REGISTER_DECODER (VC1_VDPAU, vc1_vdpau);
REGISTER_DECODER (VC1IMAGE, vc1image);
REGISTER_DECODER (VCR1, vcr1);
REGISTER_DECODER (VMDVIDEO, vmdvideo);
REGISTER_DECODER (VMNC, vmnc);
......@@ -217,6 +218,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (WMV2, wmv2);
REGISTER_DECODER (WMV3, wmv3);
REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau);
REGISTER_DECODER (WMV3IMAGE, wmv3image);
REGISTER_DECODER (WNV1, wnv1);
REGISTER_DECODER (XAN_WC3, xan_wc3);
REGISTER_DECODER (XAN_WC4, xan_wc4);
......
......@@ -208,6 +208,8 @@ enum CodecID {
CODEC_ID_PRORES,
CODEC_ID_JV,
CODEC_ID_DFA,
CODEC_ID_WMV3IMAGE,
CODEC_ID_VC1IMAGE,
/* various PCM "codecs" */
CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
......
......@@ -91,6 +91,8 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
break;
case CODEC_ID_VC1:
case CODEC_ID_WMV3:
case CODEC_ID_VC1IMAGE:
case CODEC_ID_WMV3IMAGE:
s->h263_pred = 1;
s->msmpeg4_version=6;
avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
......
......@@ -208,7 +208,12 @@ void ff_copy_picture(Picture *dst, Picture *src){
*/
static void free_frame_buffer(MpegEncContext *s, Picture *pic)
{
ff_thread_release_buffer(s->avctx, (AVFrame*)pic);
/* Windows Media Image codecs allocate internal buffers with different
dimensions; ignore user defined callbacks for these */
if (s->codec_id != CODEC_ID_WMV3IMAGE && s->codec_id != CODEC_ID_VC1IMAGE)
ff_thread_release_buffer(s->avctx, (AVFrame*)pic);
else
avcodec_default_release_buffer(s->avctx, (AVFrame*)pic);
av_freep(&pic->f.hwaccel_picture_private);
}
......@@ -230,7 +235,10 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
}
}
r = ff_thread_get_buffer(s->avctx, (AVFrame*)pic);
if (s->codec_id != CODEC_ID_WMV3IMAGE && s->codec_id != CODEC_ID_VC1IMAGE)
r = ff_thread_get_buffer(s->avctx, (AVFrame*)pic);
else
r = avcodec_default_get_buffer(s->avctx, (AVFrame*)pic);
if (r < 0 || !pic->f.age || !pic->f.type || !pic->f.data[0]) {
av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n",
......
......@@ -314,9 +314,6 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
"Old interlaced mode is not supported\n");
return -1;
}
if (v->res_sprite) {
av_log(avctx, AV_LOG_ERROR, "WMVP is not fully supported\n");
}
}
// (fps-2)/4 (->30)
......
......@@ -311,6 +311,9 @@ typedef struct VC1Context{
//@{
int new_sprite;
int two_sprites;
AVFrame sprite_output_frame;
int output_width, output_height, sprite_width, sprite_height;
uint8_t* sr_rows[2][2]; ///< Sprite resizer line cache
//@}
int p_frame_skipped;
......
This diff is collapsed.
......@@ -713,6 +713,66 @@ static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a
}
}
#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
static void sprite_h_c(uint8_t *dst, const uint8_t *src, int offset, int advance, int count)
{
while (count--) {
int a = src[(offset >> 16) ];
int b = src[(offset >> 16) + 1];
*dst++ = a + ((b - a) * (offset&0xFFFF) >> 16);
offset += advance;
}
}
static av_always_inline void sprite_v_template(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
int two_sprites, const uint8_t *src2a, const uint8_t *src2b, int offset2,
int alpha, int scaled, int width)
{
int a1, b1, a2, b2;
while (width--) {
a1 = *src1a++;
if (scaled) {
b1 = *src1b++;
a1 = a1 + ((b1 - a1) * offset1 >> 16);
}
if (two_sprites) {
a2 = *src2a++;
if (scaled > 1) {
b2 = *src2b++;
a2 = a2 + ((b2 - a2) * offset2 >> 16);
}
a1 = a1 + ((a2 - a1) * alpha >> 16);
}
*dst++ = a1;
}
}
static void sprite_v_single_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset, int width)
{
sprite_v_template(dst, src1a, src1b, offset, 0, NULL, NULL, 0, 0, 1, width);
}
static void sprite_v_double_noscale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src2a, int alpha, int width)
{
sprite_v_template(dst, src1a, NULL, 0, 1, src2a, NULL, 0, alpha, 0, width);
}
static void sprite_v_double_onescale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
const uint8_t *src2a, int alpha, int width)
{
sprite_v_template(dst, src1a, src1b, offset1, 1, src2a, NULL, 0, alpha, 1, width);
}
static void sprite_v_double_twoscale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
const uint8_t *src2a, const uint8_t *src2b, int offset2,
int alpha, int width)
{
sprite_v_template(dst, src1a, src1b, offset1, 1, src2a, src2b, offset2, alpha, 2, width);
}
#endif
av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c;
dsp->vc1_inv_trans_4x8 = vc1_inv_trans_4x8_c;
......@@ -770,6 +830,14 @@ av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c;
dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c;
#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
dsp->sprite_h = sprite_h_c;
dsp->sprite_v_single = sprite_v_single_c;
dsp->sprite_v_double_noscale = sprite_v_double_noscale_c;
dsp->sprite_v_double_onescale = sprite_v_double_onescale_c;
dsp->sprite_v_double_twoscale = sprite_v_double_twoscale_c;
#endif
if (HAVE_ALTIVEC)
ff_vc1dsp_init_altivec(dsp);
if (HAVE_MMX)
......
......@@ -60,6 +60,16 @@ typedef struct VC1DSPContext {
/* This is really one func used in VC-1 decoding */
h264_chroma_mc_func put_no_rnd_vc1_chroma_pixels_tab[3];
h264_chroma_mc_func avg_no_rnd_vc1_chroma_pixels_tab[3];
/* Windows Media Image functions */
void (*sprite_h)(uint8_t *dst, const uint8_t *src, int offset, int advance, int count);
void (*sprite_v_single)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset, int width);
void (*sprite_v_double_noscale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src2a, int alpha, int width);
void (*sprite_v_double_onescale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
const uint8_t *src2a, int alpha, int width);
void (*sprite_v_double_twoscale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
const uint8_t *src2a, const uint8_t *src2b, int offset2,
int alpha, int width);
} VC1DSPContext;
void ff_vc1dsp_init(VC1DSPContext* c);
......
......@@ -21,7 +21,7 @@
#define AVCODEC_VERSION_H
#define LIBAVCODEC_VERSION_MAJOR 53
#define LIBAVCODEC_VERSION_MINOR 8
#define LIBAVCODEC_VERSION_MINOR 9
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
......
......@@ -237,10 +237,10 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_QPEG, MKTAG('Q', '1', '.', '0') },
{ CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') },
{ CODEC_ID_WMV3, MKTAG('W', 'M', 'V', '3') },
{ CODEC_ID_WMV3, MKTAG('W', 'M', 'V', 'P') },
{ CODEC_ID_WMV3IMAGE, MKTAG('W', 'M', 'V', 'P') },
{ CODEC_ID_VC1, MKTAG('W', 'V', 'C', '1') },
{ CODEC_ID_VC1, MKTAG('W', 'M', 'V', 'A') },
{ CODEC_ID_VC1, MKTAG('W', 'V', 'P', '2') },
{ CODEC_ID_VC1IMAGE, MKTAG('W', 'V', 'P', '2') },
{ CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') },
{ CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') },
{ CODEC_ID_AASC, MKTAG('A', 'A', 'S', 'C') },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment