be used by video players. Original patch by NVIDIA corporation. Originally committed as revision 16699 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -1016,6 +1016,7 @@ svq3_decoder_suggest="zlib" | |||
| tiff_decoder_suggest="zlib" | |||
| tiff_encoder_suggest="zlib" | |||
| tscc_decoder_select="zlib" | |||
| vc1_vdpau_decoder_deps="vdpau" | |||
| vorbis_decoder_select="fft mdct" | |||
| vorbis_encoder_select="fft mdct" | |||
| wmav1_decoder_select="fft mdct" | |||
| @@ -1024,6 +1025,7 @@ wmav2_decoder_select="fft mdct" | |||
| wmav2_encoder_select="fft mdct" | |||
| wmv1_encoder_select="aandct" | |||
| wmv2_encoder_select="aandct" | |||
| wmv3_vdpau_decoder_deps="vdpau" | |||
| zlib_decoder_select="zlib" | |||
| zlib_encoder_select="zlib" | |||
| zmbv_decoder_select="zlib" | |||
| @@ -218,6 +218,7 @@ OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o | |||
| OBJS-$(CONFIG_ULTI_DECODER) += ulti.o | |||
| OBJS-$(CONFIG_VB_DECODER) += vb.o | |||
| OBJS-$(CONFIG_VC1_DECODER) += vc1.o vc1data.o vc1dsp.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o error_resilience.o mpegvideo.o | |||
| OBJS-$(CONFIG_VC1_VDPAU_DECODER) += vdpauvideo.o vc1.o vc1data.o vc1dsp.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o error_resilience.o mpegvideo.o | |||
| OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o | |||
| OBJS-$(CONFIG_VCR1_ENCODER) += vcr1.o | |||
| OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdav.o | |||
| @@ -241,6 +242,7 @@ OBJS-$(CONFIG_WMV1_ENCODER) += mpegvideo_enc.o motion_est.o ratecontr | |||
| OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o msmpeg4.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o mpeg12data.o mpegvideo.o error_resilience.o | |||
| OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o msmpeg4.o msmpeg4data.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o mpeg12data.o mpegvideo.o error_resilience.o | |||
| OBJS-$(CONFIG_WMV3_DECODER) += vc1.o vc1data.o vc1dsp.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o error_resilience.o mpegvideo.o | |||
| OBJS-$(CONFIG_WMV3_VDPAU_DECODER) += vdpauvideo.o vc1.o vc1data.o vc1dsp.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o error_resilience.o mpegvideo.o | |||
| OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o | |||
| OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o | |||
| OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o | |||
| @@ -157,6 +157,7 @@ void avcodec_register_all(void) | |||
| REGISTER_DECODER (ULTI, ulti); | |||
| REGISTER_DECODER (VB, vb); | |||
| REGISTER_DECODER (VC1, vc1); | |||
| REGISTER_DECODER (VC1_VDPAU, vc1_vdpau); | |||
| REGISTER_DECODER (VCR1, vcr1); | |||
| REGISTER_DECODER (VMDVIDEO, vmdvideo); | |||
| REGISTER_DECODER (VMNC, vmnc); | |||
| @@ -169,6 +170,7 @@ void avcodec_register_all(void) | |||
| REGISTER_ENCDEC (WMV1, wmv1); | |||
| REGISTER_ENCDEC (WMV2, wmv2); | |||
| REGISTER_DECODER (WMV3, wmv3); | |||
| REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau); | |||
| REGISTER_DECODER (WNV1, wnv1); | |||
| REGISTER_DECODER (XAN_WC3, xan_wc3); | |||
| REGISTER_DECODER (XL, xl); | |||
| @@ -276,6 +276,12 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { | |||
| [PIX_FMT_VDPAU_H264] = { | |||
| .name = "vdpau_h264", | |||
| }, | |||
| [PIX_FMT_VDPAU_WMV3] = { | |||
| .name = "vdpau_wmv3", | |||
| }, | |||
| [PIX_FMT_VDPAU_VC1] = { | |||
| .name = "vdpau_vc1", | |||
| }, | |||
| [PIX_FMT_UYYVYY411] = { | |||
| .name = "uyyvyy411", | |||
| .nb_channels = 1, | |||
| @@ -35,6 +35,7 @@ | |||
| #include "unary.h" | |||
| #include "simple_idct.h" | |||
| #include "mathops.h" | |||
| #include "vdpau_internal.h" | |||
| #undef NDEBUG | |||
| #include <assert.h> | |||
| @@ -4130,6 +4131,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, | |||
| MpegEncContext *s = &v->s; | |||
| AVFrame *pict = data; | |||
| uint8_t *buf2 = NULL; | |||
| const uint8_t *buf_vdpau = buf; | |||
| /* no supplementary picture */ | |||
| if (buf_size == 0) { | |||
| @@ -4151,6 +4153,13 @@ static int vc1_decode_frame(AVCodecContext *avctx, | |||
| 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; | |||
| else | |||
| avctx->pix_fmt = PIX_FMT_VDPAU_VC1; | |||
| } | |||
| //for advanced profile we may need to parse and unescape data | |||
| if (avctx->codec_id == CODEC_ID_VC1) { | |||
| int buf_size2 = 0; | |||
| @@ -4167,6 +4176,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, | |||
| if(size <= 0) continue; | |||
| switch(AV_RB32(start)){ | |||
| case VC1_CODE_FRAME: | |||
| if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) | |||
| buf_vdpau = start; | |||
| buf_size2 = vc1_unescape_buffer(start + 4, size, buf2); | |||
| break; | |||
| case VC1_CODE_ENTRYPOINT: /* it should be before frame data */ | |||
| @@ -4255,6 +4266,10 @@ static int vc1_decode_frame(AVCodecContext *avctx, | |||
| s->me.qpel_put= s->dsp.put_qpel_pixels_tab; | |||
| s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab; | |||
| if ((CONFIG_VC1_VDPAU_DECODER || CONFIG_WMV3_VDPAU_DECODER) | |||
| &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) | |||
| ff_vdpau_vc1_decode_picture(s, buf_vdpau, (buf + buf_size) - buf_vdpau); | |||
| else { | |||
| ff_er_frame_start(s); | |||
| v->bits = buf_size * 8; | |||
| @@ -4263,6 +4278,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, | |||
| // if(get_bits_count(&s->gb) > buf_size * 8) | |||
| // return -1; | |||
| ff_er_frame_end(s); | |||
| } | |||
| MPV_frame_end(s); | |||
| @@ -4336,3 +4352,35 @@ AVCodec wmv3_decoder = { | |||
| NULL, | |||
| .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"), | |||
| }; | |||
| #if CONFIG_WMV3_VDPAU_DECODER | |||
| AVCodec wmv3_vdpau_decoder = { | |||
| "wmv3_vdpau", | |||
| CODEC_TYPE_VIDEO, | |||
| CODEC_ID_WMV3, | |||
| sizeof(VC1Context), | |||
| vc1_decode_init, | |||
| NULL, | |||
| vc1_decode_end, | |||
| vc1_decode_frame, | |||
| CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, | |||
| NULL, | |||
| .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"), | |||
| }; | |||
| #endif | |||
| #if CONFIG_VC1_VDPAU_DECODER | |||
| AVCodec vc1_vdpau_decoder = { | |||
| "vc1_vdpau", | |||
| CODEC_TYPE_VIDEO, | |||
| CODEC_ID_VC1, | |||
| sizeof(VC1Context), | |||
| vc1_decode_init, | |||
| NULL, | |||
| vc1_decode_end, | |||
| vc1_decode_frame, | |||
| CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, | |||
| NULL, | |||
| .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"), | |||
| }; | |||
| #endif | |||
| @@ -72,6 +72,7 @@ struct vdpau_render_state { | |||
| union VdpPictureInfo { | |||
| VdpPictureInfoMPEG1Or2 mpeg; | |||
| VdpPictureInfoH264 h264; | |||
| VdpPictureInfoVC1 vc1; | |||
| } info; | |||
| /** Describe size/location of the compressed video data. */ | |||
| @@ -36,4 +36,7 @@ void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf, | |||
| void ff_vdpau_h264_set_reference_frames(MpegEncContext *s); | |||
| void ff_vdpau_h264_picture_complete(MpegEncContext *s); | |||
| void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf, | |||
| int buf_size); | |||
| #endif /* AVCODEC_VDPAU_INTERNAL_H */ | |||
| @@ -24,6 +24,7 @@ | |||
| #include <limits.h> | |||
| #include "avcodec.h" | |||
| #include "h264.h" | |||
| #include "vc1.h" | |||
| #undef NDEBUG | |||
| #include <assert.h> | |||
| @@ -232,4 +233,73 @@ void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf, | |||
| render->bitstream_buffers_used = 0; | |||
| } | |||
| void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf, | |||
| int buf_size) | |||
| { | |||
| VC1Context *v = s->avctx->priv_data; | |||
| struct vdpau_render_state * render, * last, * next; | |||
| render = (struct vdpau_render_state*)s->current_picture.data[0]; | |||
| assert(render); | |||
| /* fill LvPictureInfoVC1 struct */ | |||
| render->info.vc1.frame_coding_mode = v->fcm; | |||
| render->info.vc1.postprocflag = v->postprocflag; | |||
| render->info.vc1.pulldown = v->broadcast; | |||
| render->info.vc1.interlace = v->interlace; | |||
| render->info.vc1.tfcntrflag = v->tfcntrflag; | |||
| render->info.vc1.finterpflag = v->finterpflag; | |||
| render->info.vc1.psf = v->psf; | |||
| render->info.vc1.dquant = v->dquant; | |||
| render->info.vc1.panscan_flag = v->panscanflag; | |||
| render->info.vc1.refdist_flag = v->refdist_flag; | |||
| render->info.vc1.quantizer = v->quantizer_mode; | |||
| render->info.vc1.extended_mv = v->extended_mv; | |||
| render->info.vc1.extended_dmv = v->extended_dmv; | |||
| render->info.vc1.overlap = v->overlap; | |||
| render->info.vc1.vstransform = v->vstransform; | |||
| render->info.vc1.loopfilter = v->s.loop_filter; | |||
| render->info.vc1.fastuvmc = v->fastuvmc; | |||
| render->info.vc1.range_mapy_flag = v->range_mapy_flag; | |||
| render->info.vc1.range_mapy = v->range_mapy; | |||
| render->info.vc1.range_mapuv_flag = v->range_mapuv_flag; | |||
| render->info.vc1.range_mapuv = v->range_mapuv; | |||
| /* Specific to simple/main profile only */ | |||
| render->info.vc1.multires = v->multires; | |||
| render->info.vc1.syncmarker = v->s.resync_marker; | |||
| render->info.vc1.rangered = v->rangered; | |||
| render->info.vc1.maxbframes = v->s.max_b_frames; | |||
| render->info.vc1.deblockEnable = v->postprocflag & 1; | |||
| render->info.vc1.pquant = v->pq; | |||
| render->info.vc1.forward_reference = VDP_INVALID_HANDLE; | |||
| render->info.vc1.backward_reference = VDP_INVALID_HANDLE; | |||
| if (v->bi_type) | |||
| render->info.vc1.picture_type = 4; | |||
| else | |||
| render->info.vc1.picture_type = s->pict_type - 1 + s->pict_type / 3; | |||
| switch(s->pict_type){ | |||
| case FF_B_TYPE: | |||
| next = (struct vdpau_render_state*)s->next_picture.data[0]; | |||
| assert(next); | |||
| render->info.vc1.backward_reference = next->surface; | |||
| // no break here, going to set forward prediction | |||
| case FF_P_TYPE: | |||
| last = (struct vdpau_render_state*)s->last_picture.data[0]; | |||
| if (!last) // FIXME: Does this test make sense? | |||
| last = render; // predict second field from the first | |||
| render->info.vc1.forward_reference = last->surface; | |||
| } | |||
| ff_vdpau_add_data_chunk(s, buf, buf_size); | |||
| render->info.vc1.slice_count = 1; | |||
| ff_draw_horiz_band(s, 0, s->avctx->height); | |||
| render->bitstream_buffers_used = 0; | |||
| } | |||
| /* @}*/ | |||
| @@ -124,6 +124,8 @@ enum PixelFormat { | |||
| PIX_FMT_VDPAU_H264,///< H264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers | |||
| PIX_FMT_VDPAU_MPEG1,///< MPEG1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers | |||
| PIX_FMT_VDPAU_MPEG2,///< MPEG2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers | |||
| PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers | |||
| PIX_FMT_VDPAU_VC1, ///< VC1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers | |||
| PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions | |||
| }; | |||