summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorNVIDIA Corporation <>2009-01-16 02:14:07 +0000
committerCarl Eugen Hoyos <cehoyos@rainbow.studorg.tuwien.ac.at>2009-01-16 02:14:07 +0000
commitd37edddc09527fbeba3099d8af123a2af879e112 (patch)
tree5c27a764447b09e82bb2eea8a6f0bdef99bcef22 /libavcodec
parent3700d8002809defe16f555490007fa69c3ddcfc9 (diff)
Add VDPAU hardware accelerated decoding for MPEG1 and MPEG2 which can
be used by video players. Original patch by NVIDIA corporation. Originally committed as revision 16628 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/Makefile1
-rw-r--r--libavcodec/allcodecs.c1
-rw-r--r--libavcodec/imgconvert.c6
-rw-r--r--libavcodec/mpeg12.c40
-rw-r--r--libavcodec/vdpau.h1
-rw-r--r--libavcodec/vdpau_internal.h4
-rw-r--r--libavcodec/vdpauvideo.c55
7 files changed, 105 insertions, 3 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index e026ffa6d4..f23b1cecfe 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -133,6 +133,7 @@ OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec.o mpegaudiodecheader.o mp
OBJS-$(CONFIG_MPC7_DECODER) += mpc7.o mpc.o mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o
OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o
OBJS-$(CONFIG_MDEC_DECODER) += mdec.o mpeg12.o mpeg12data.o mpegvideo.o error_resilience.o
+OBJS-$(CONFIG_MPEG_VDPAU_DECODER) += vdpauvideo.o mpeg12.o mpeg12data.o mpegvideo.o error_resilience.o
OBJS-$(CONFIG_MPEGVIDEO_DECODER) += mpeg12.o mpeg12data.o mpegvideo.o error_resilience.o
OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12.o mpeg12data.o mpegvideo.o error_resilience.o
OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12data.o mpegvideo_enc.o motion_est.o ratecontrol.o mpeg12.o mpeg12data.o mpegvideo.o error_resilience.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 0efbd64512..ba3ab1648c 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -109,6 +109,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video);
REGISTER_ENCDEC (MPEG4, mpeg4);
REGISTER_DECODER (MPEGVIDEO, mpegvideo);
+ REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau);
REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1);
REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2);
REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3);
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index 94ea967d1d..ac76b78d7f 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -267,6 +267,12 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
[PIX_FMT_XVMC_MPEG2_IDCT] = {
.name = "xvmcidct",
},
+ [PIX_FMT_VDPAU_MPEG1] = {
+ .name = "vdpau_mpeg1",
+ },
+ [PIX_FMT_VDPAU_MPEG2] = {
+ .name = "vdpau_mpeg2",
+ },
[PIX_FMT_VDPAU_H264] = {
.name = "vdpau_h264",
},
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 8971e2bbb2..9f982194b0 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -34,6 +34,7 @@
#include "mpeg12data.h"
#include "mpeg12decdata.h"
#include "bytestream.h"
+#include "vdpau_internal.h"
//#undef NDEBUG
//#include <assert.h>
@@ -1218,7 +1219,12 @@ static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx){
if(avctx->xvmc_acceleration)
return avctx->get_format(avctx,pixfmt_xvmc_mpg2_420);
- else{
+ else if(avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){
+ if(avctx->codec_id == CODEC_ID_MPEG1VIDEO)
+ return PIX_FMT_VDPAU_MPEG1;
+ else
+ return PIX_FMT_VDPAU_MPEG2;
+ }else{
if(s->chroma_format < 2)
return PIX_FMT_YUV420P;
else if(s->chroma_format == 2)
@@ -1307,7 +1313,8 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){
avctx->pix_fmt = mpeg_get_pixelformat(avctx);
//until then pix_fmt may be changed right after codec init
- if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT )
+ if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ||
+ s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU )
if( avctx->idct_algo == FF_IDCT_AUTO )
avctx->idct_algo = FF_IDCT_SIMPLE;
@@ -2076,7 +2083,8 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
avctx->pix_fmt = mpeg_get_pixelformat(avctx);
- if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT )
+ if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ||
+ s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU )
if( avctx->idct_algo == FF_IDCT_AUTO )
avctx->idct_algo = FF_IDCT_SIMPLE;
@@ -2304,6 +2312,10 @@ static int decode_chunks(AVCodecContext *avctx,
for(i=0; i<s->slice_count; i++)
s2->error_count += s2->thread_context[i]->error_count;
}
+
+ if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
+ ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);
+
if (slice_end(avctx, picture)) {
if(s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
*data_size = sizeof(AVPicture);
@@ -2389,6 +2401,11 @@ static int decode_chunks(AVCodecContext *avctx,
return -1;
}
+ if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
+ s->slice_count++;
+ break;
+ }
+
if(avctx->thread_count > 1){
int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count;
if(threshold <= mb_y){
@@ -2508,3 +2525,20 @@ AVCodec mpeg_xvmc_decoder = {
};
#endif
+
+#if CONFIG_MPEG_VDPAU_DECODER
+AVCodec mpeg_vdpau_decoder = {
+ "mpegvideo_vdpau",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_MPEG2VIDEO,
+ sizeof(Mpeg1Context),
+ mpeg_decode_init,
+ NULL,
+ mpeg_decode_end,
+ mpeg_decode_frame,
+ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
+ .flush= ff_mpeg_flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
+};
+#endif
+
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index 2d03356127..a28ad7fa82 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -70,6 +70,7 @@ struct vdpau_render_state {
/** picture parameter information for all supported codecs */
union VdpPictureInfo {
+ VdpPictureInfoMPEG1Or2 mpeg;
VdpPictureInfoH264 h264;
} info;
diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h
index cefd97754a..4f993af94b 100644
--- a/libavcodec/vdpau_internal.h
+++ b/libavcodec/vdpau_internal.h
@@ -29,6 +29,10 @@
void ff_vdpau_add_data_chunk(MpegEncContext *s, const uint8_t *buf,
int buf_size);
+
+void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf,
+ int buf_size, int slice_count);
+
void ff_vdpau_h264_set_reference_frames(MpegEncContext *s);
void ff_vdpau_h264_picture_complete(MpegEncContext *s);
diff --git a/libavcodec/vdpauvideo.c b/libavcodec/vdpauvideo.c
index e0cd627f97..b5b91cb2f3 100644
--- a/libavcodec/vdpauvideo.c
+++ b/libavcodec/vdpauvideo.c
@@ -177,4 +177,59 @@ void ff_vdpau_h264_picture_complete(MpegEncContext *s)
render->bitstream_buffers_used = 0;
}
+void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf,
+ int buf_size, int slice_count)
+{
+ struct vdpau_render_state * render, * last, * next;
+ int i;
+
+ render = (struct vdpau_render_state*)s->current_picture_ptr->data[0];
+ assert(render);
+
+ /* fill VdpPictureInfoMPEG1Or2 struct */
+ render->info.mpeg.picture_structure = s->picture_structure;
+ render->info.mpeg.picture_coding_type = s->pict_type;
+ render->info.mpeg.intra_dc_precision = s->intra_dc_precision;
+ render->info.mpeg.frame_pred_frame_dct = s->frame_pred_frame_dct;
+ render->info.mpeg.concealment_motion_vectors = s->concealment_motion_vectors;
+ render->info.mpeg.intra_vlc_format = s->intra_vlc_format;
+ render->info.mpeg.alternate_scan = s->alternate_scan;
+ render->info.mpeg.q_scale_type = s->q_scale_type;
+ render->info.mpeg.top_field_first = s->top_field_first;
+ render->info.mpeg.full_pel_forward_vector = s->full_pel[0]; // MPEG-1 only. Set 0 for MPEG-2
+ render->info.mpeg.full_pel_backward_vector = s->full_pel[1]; // MPEG-1 only. Set 0 for MPEG-2
+ render->info.mpeg.f_code[0][0] = s->mpeg_f_code[0][0]; // For MPEG-1 fill both horiz. & vert.
+ render->info.mpeg.f_code[0][1] = s->mpeg_f_code[0][1];
+ render->info.mpeg.f_code[1][0] = s->mpeg_f_code[1][0];
+ render->info.mpeg.f_code[1][1] = s->mpeg_f_code[1][1];
+ for (i = 0; i < 64; ++i) {
+ render->info.mpeg.intra_quantizer_matrix[i] = s->intra_matrix[i];
+ render->info.mpeg.non_intra_quantizer_matrix[i] = s->inter_matrix[i];
+ }
+
+ render->info.mpeg.forward_reference = VDP_INVALID_HANDLE;
+ render->info.mpeg.backward_reference = VDP_INVALID_HANDLE;
+
+ switch(s->pict_type){
+ case FF_B_TYPE:
+ next = (struct vdpau_render_state*)s->next_picture.data[0];
+ assert(next);
+ render->info.mpeg.backward_reference = next->surface;
+ // no return 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.mpeg.forward_reference = last->surface;
+ }
+
+ ff_vdpau_add_data_chunk(s, buf, buf_size);
+
+ render->info.mpeg.slice_count = slice_count;
+
+ if (slice_count)
+ ff_draw_horiz_band(s, 0, s->avctx->height);
+ render->bitstream_buffers_used = 0;
+}
+
/* @}*/