/* * smpte-vc1.c * * Glue code to the SMPTE reference VC-1 decoder * by Mike Melanson (mike at multimedia.cx) */ #include "avcodec.h" #include #undef ABS #include "libvc1/vc1types.h" #include "libvc1/vc1dec.h" #include "libvc1/vc1decbit.h" #undef printf typedef struct { vc1DEC_sState *state; vc1DEC_sBitstream bitstream; vc1DEC_sDecoderConfiguration config; AVFrame picture; } VC1DecodeContext; static int wmv_decode_init(AVCodecContext *avctx) { int instance_size; VC1DecodeContext *s = avctx->priv_data; printf("WMV3 init\n"); avctx->pix_fmt= PIX_FMT_YUV420P; /* initialize config structure */ s->config.eLevel = vc1_LevelUnknown; s->config.MaxCodedWidth = avctx->width; s->config.MaxCodedHeight = avctx->height; s->state = NULL; { int i; unsigned char *extradata = avctx->extradata; printf (" VC-1: Initializing with %d bytes of extradata\n", avctx->extradata_size); for (i = 0; i < avctx->extradata_size; i++) printf (" %02X", extradata[i]); printf ("\n"); } if (vc1DECBIT_InitialiseBitstream( &s->bitstream, avctx->extradata, avctx->extradata_size, FALSE) != vc1_ResultOK) { printf ("vc1DECBIT_InitialiseBitstream() failed\n"); return -1; } if (vc1DEC_DecoderRequirements( &instance_size, &s->config, &s->bitstream) != vc1_ResultOK) { printf("vc1DEC_DecoderRequirements() failed\n"); return -1; } s->state = av_malloc(instance_size); if (!s->state) { printf ("no more memory\n"); return -1; } if (vc1DEC_DecoderInitialise( s->state, &s->config) != vc1_ResultOK) { printf ("vc1DEC_DecoderInitialise() failed\n"); return -1; } if (vc1DEC_DecodeSequence( s->state, &s->bitstream) != vc1_ResultOK) { printf ("vc1DEC_DecodeSequence() failed\n"); return -1; } return 0; } static int wmv_decode_frame(AVCodecContext *avctx, void *data, int *data_size, unsigned char *buf, int buf_size) { VC1DecodeContext *s = avctx->priv_data; AVFrame *p = &s->picture; vc1_sPicture picture; static int counter = -1; counter++; printf (" decoding frame %d\n", counter); if (p->data[0]) avctx->release_buffer(avctx,p); p->reference = 0; if (avctx->get_buffer(avctx,p)<0) { printf("wmv_decode_frame get_buffer() failed\n"); return -1; } /* assign planes and strides */ picture.sY.pData = p->data[0]; picture.sY.Bpl = p->linesize[0]; picture.sU.pData = p->data[1]; picture.sU.Bpl = p->linesize[1]; picture.sV.pData = p->data[2]; picture.sV.Bpl = p->linesize[2]; if (vc1DECBIT_InitialiseBitstream( &s->bitstream, buf, buf_size, FALSE) != vc1_ResultOK) { printf ("vc1DECBIT_InitialiseBitstream failed\n"); return -1; } if (vc1DEC_DecodeFrame( s->state, &s->bitstream, &picture) != vc1_ResultOK) { printf ("vc1DEC_DecodeFrame() failed\n"); return -1; } *data_size = sizeof(AVPicture); *(AVFrame *)data = s->picture; return buf_size; } static int wmv_decode_end(AVCodecContext *avctx) { VC1DecodeContext *s = avctx->priv_data; av_free(s->state); return 0; } AVCodec wmv3_decoder = { "wmv3", CODEC_TYPE_VIDEO, CODEC_ID_WMV3, sizeof(VC1DecodeContext), wmv_decode_init, NULL, wmv_decode_end, wmv_decode_frame };