Original patch by NVIDIA corporation.
Originally committed as revision 16628 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -993,6 +993,7 @@ mjpeg_encoder_select="aandct" |
| 993 | 993 |
mpeg1video_encoder_select="aandct" |
| 994 | 994 |
mpeg2video_encoder_select="aandct" |
| 995 | 995 |
mpeg4_encoder_select="aandct" |
| 996 |
+mpeg_vdpau_decoder_deps="vdpau" |
|
| 996 | 997 |
mpeg_xvmc_decoder_deps="xvmc X11_extensions_XvMClib_h" |
| 997 | 998 |
msmpeg4v1_encoder_select="aandct" |
| 998 | 999 |
msmpeg4v2_encoder_select="aandct" |
| ... | ... |
@@ -133,6 +133,7 @@ OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec.o mpegaudiodecheader.o mp |
| 133 | 133 |
OBJS-$(CONFIG_MPC7_DECODER) += mpc7.o mpc.o mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o |
| 134 | 134 |
OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o |
| 135 | 135 |
OBJS-$(CONFIG_MDEC_DECODER) += mdec.o mpeg12.o mpeg12data.o mpegvideo.o error_resilience.o |
| 136 |
+OBJS-$(CONFIG_MPEG_VDPAU_DECODER) += vdpauvideo.o mpeg12.o mpeg12data.o mpegvideo.o error_resilience.o |
|
| 136 | 137 |
OBJS-$(CONFIG_MPEGVIDEO_DECODER) += mpeg12.o mpeg12data.o mpegvideo.o error_resilience.o |
| 137 | 138 |
OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12.o mpeg12data.o mpegvideo.o error_resilience.o |
| 138 | 139 |
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 |
| ... | ... |
@@ -109,6 +109,7 @@ void avcodec_register_all(void) |
| 109 | 109 |
REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); |
| 110 | 110 |
REGISTER_ENCDEC (MPEG4, mpeg4); |
| 111 | 111 |
REGISTER_DECODER (MPEGVIDEO, mpegvideo); |
| 112 |
+ REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau); |
|
| 112 | 113 |
REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1); |
| 113 | 114 |
REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); |
| 114 | 115 |
REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); |
| ... | ... |
@@ -267,6 +267,12 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
|
| 267 | 267 |
[PIX_FMT_XVMC_MPEG2_IDCT] = {
|
| 268 | 268 |
.name = "xvmcidct", |
| 269 | 269 |
}, |
| 270 |
+ [PIX_FMT_VDPAU_MPEG1] = {
|
|
| 271 |
+ .name = "vdpau_mpeg1", |
|
| 272 |
+ }, |
|
| 273 |
+ [PIX_FMT_VDPAU_MPEG2] = {
|
|
| 274 |
+ .name = "vdpau_mpeg2", |
|
| 275 |
+ }, |
|
| 270 | 276 |
[PIX_FMT_VDPAU_H264] = {
|
| 271 | 277 |
.name = "vdpau_h264", |
| 272 | 278 |
}, |
| ... | ... |
@@ -34,6 +34,7 @@ |
| 34 | 34 |
#include "mpeg12data.h" |
| 35 | 35 |
#include "mpeg12decdata.h" |
| 36 | 36 |
#include "bytestream.h" |
| 37 |
+#include "vdpau_internal.h" |
|
| 37 | 38 |
|
| 38 | 39 |
//#undef NDEBUG |
| 39 | 40 |
//#include <assert.h> |
| ... | ... |
@@ -1218,7 +1219,12 @@ static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx){
|
| 1218 | 1218 |
|
| 1219 | 1219 |
if(avctx->xvmc_acceleration) |
| 1220 | 1220 |
return avctx->get_format(avctx,pixfmt_xvmc_mpg2_420); |
| 1221 |
- else{
|
|
| 1221 |
+ else if(avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){
|
|
| 1222 |
+ if(avctx->codec_id == CODEC_ID_MPEG1VIDEO) |
|
| 1223 |
+ return PIX_FMT_VDPAU_MPEG1; |
|
| 1224 |
+ else |
|
| 1225 |
+ return PIX_FMT_VDPAU_MPEG2; |
|
| 1226 |
+ }else{
|
|
| 1222 | 1227 |
if(s->chroma_format < 2) |
| 1223 | 1228 |
return PIX_FMT_YUV420P; |
| 1224 | 1229 |
else if(s->chroma_format == 2) |
| ... | ... |
@@ -1307,7 +1313,8 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){
|
| 1307 | 1307 |
|
| 1308 | 1308 |
avctx->pix_fmt = mpeg_get_pixelformat(avctx); |
| 1309 | 1309 |
//until then pix_fmt may be changed right after codec init |
| 1310 |
- if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ) |
|
| 1310 |
+ if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || |
|
| 1311 |
+ s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ) |
|
| 1311 | 1312 |
if( avctx->idct_algo == FF_IDCT_AUTO ) |
| 1312 | 1313 |
avctx->idct_algo = FF_IDCT_SIMPLE; |
| 1313 | 1314 |
|
| ... | ... |
@@ -2076,7 +2083,8 @@ static int vcr2_init_sequence(AVCodecContext *avctx) |
| 2076 | 2076 |
|
| 2077 | 2077 |
avctx->pix_fmt = mpeg_get_pixelformat(avctx); |
| 2078 | 2078 |
|
| 2079 |
- if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ) |
|
| 2079 |
+ if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || |
|
| 2080 |
+ s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ) |
|
| 2080 | 2081 |
if( avctx->idct_algo == FF_IDCT_AUTO ) |
| 2081 | 2082 |
avctx->idct_algo = FF_IDCT_SIMPLE; |
| 2082 | 2083 |
|
| ... | ... |
@@ -2304,6 +2312,10 @@ static int decode_chunks(AVCodecContext *avctx, |
| 2304 | 2304 |
for(i=0; i<s->slice_count; i++) |
| 2305 | 2305 |
s2->error_count += s2->thread_context[i]->error_count; |
| 2306 | 2306 |
} |
| 2307 |
+ |
|
| 2308 |
+ if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) |
|
| 2309 |
+ ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count); |
|
| 2310 |
+ |
|
| 2307 | 2311 |
if (slice_end(avctx, picture)) {
|
| 2308 | 2312 |
if(s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice |
| 2309 | 2313 |
*data_size = sizeof(AVPicture); |
| ... | ... |
@@ -2389,6 +2401,11 @@ static int decode_chunks(AVCodecContext *avctx, |
| 2389 | 2389 |
return -1; |
| 2390 | 2390 |
} |
| 2391 | 2391 |
|
| 2392 |
+ if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
|
|
| 2393 |
+ s->slice_count++; |
|
| 2394 |
+ break; |
|
| 2395 |
+ } |
|
| 2396 |
+ |
|
| 2392 | 2397 |
if(avctx->thread_count > 1){
|
| 2393 | 2398 |
int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count; |
| 2394 | 2399 |
if(threshold <= mb_y){
|
| ... | ... |
@@ -2508,3 +2525,20 @@ AVCodec mpeg_xvmc_decoder = {
|
| 2508 | 2508 |
}; |
| 2509 | 2509 |
|
| 2510 | 2510 |
#endif |
| 2511 |
+ |
|
| 2512 |
+#if CONFIG_MPEG_VDPAU_DECODER |
|
| 2513 |
+AVCodec mpeg_vdpau_decoder = {
|
|
| 2514 |
+ "mpegvideo_vdpau", |
|
| 2515 |
+ CODEC_TYPE_VIDEO, |
|
| 2516 |
+ CODEC_ID_MPEG2VIDEO, |
|
| 2517 |
+ sizeof(Mpeg1Context), |
|
| 2518 |
+ mpeg_decode_init, |
|
| 2519 |
+ NULL, |
|
| 2520 |
+ mpeg_decode_end, |
|
| 2521 |
+ mpeg_decode_frame, |
|
| 2522 |
+ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY, |
|
| 2523 |
+ .flush= ff_mpeg_flush, |
|
| 2524 |
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
|
|
| 2525 |
+}; |
|
| 2526 |
+#endif |
|
| 2527 |
+ |
| ... | ... |
@@ -29,6 +29,10 @@ |
| 29 | 29 |
|
| 30 | 30 |
void ff_vdpau_add_data_chunk(MpegEncContext *s, const uint8_t *buf, |
| 31 | 31 |
int buf_size); |
| 32 |
+ |
|
| 33 |
+void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf, |
|
| 34 |
+ int buf_size, int slice_count); |
|
| 35 |
+ |
|
| 32 | 36 |
void ff_vdpau_h264_set_reference_frames(MpegEncContext *s); |
| 33 | 37 |
void ff_vdpau_h264_picture_complete(MpegEncContext *s); |
| 34 | 38 |
|
| ... | ... |
@@ -177,4 +177,59 @@ void ff_vdpau_h264_picture_complete(MpegEncContext *s) |
| 177 | 177 |
render->bitstream_buffers_used = 0; |
| 178 | 178 |
} |
| 179 | 179 |
|
| 180 |
+void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf, |
|
| 181 |
+ int buf_size, int slice_count) |
|
| 182 |
+{
|
|
| 183 |
+ struct vdpau_render_state * render, * last, * next; |
|
| 184 |
+ int i; |
|
| 185 |
+ |
|
| 186 |
+ render = (struct vdpau_render_state*)s->current_picture_ptr->data[0]; |
|
| 187 |
+ assert(render); |
|
| 188 |
+ |
|
| 189 |
+ /* fill VdpPictureInfoMPEG1Or2 struct */ |
|
| 190 |
+ render->info.mpeg.picture_structure = s->picture_structure; |
|
| 191 |
+ render->info.mpeg.picture_coding_type = s->pict_type; |
|
| 192 |
+ render->info.mpeg.intra_dc_precision = s->intra_dc_precision; |
|
| 193 |
+ render->info.mpeg.frame_pred_frame_dct = s->frame_pred_frame_dct; |
|
| 194 |
+ render->info.mpeg.concealment_motion_vectors = s->concealment_motion_vectors; |
|
| 195 |
+ render->info.mpeg.intra_vlc_format = s->intra_vlc_format; |
|
| 196 |
+ render->info.mpeg.alternate_scan = s->alternate_scan; |
|
| 197 |
+ render->info.mpeg.q_scale_type = s->q_scale_type; |
|
| 198 |
+ render->info.mpeg.top_field_first = s->top_field_first; |
|
| 199 |
+ render->info.mpeg.full_pel_forward_vector = s->full_pel[0]; // MPEG-1 only. Set 0 for MPEG-2 |
|
| 200 |
+ render->info.mpeg.full_pel_backward_vector = s->full_pel[1]; // MPEG-1 only. Set 0 for MPEG-2 |
|
| 201 |
+ render->info.mpeg.f_code[0][0] = s->mpeg_f_code[0][0]; // For MPEG-1 fill both horiz. & vert. |
|
| 202 |
+ render->info.mpeg.f_code[0][1] = s->mpeg_f_code[0][1]; |
|
| 203 |
+ render->info.mpeg.f_code[1][0] = s->mpeg_f_code[1][0]; |
|
| 204 |
+ render->info.mpeg.f_code[1][1] = s->mpeg_f_code[1][1]; |
|
| 205 |
+ for (i = 0; i < 64; ++i) {
|
|
| 206 |
+ render->info.mpeg.intra_quantizer_matrix[i] = s->intra_matrix[i]; |
|
| 207 |
+ render->info.mpeg.non_intra_quantizer_matrix[i] = s->inter_matrix[i]; |
|
| 208 |
+ } |
|
| 209 |
+ |
|
| 210 |
+ render->info.mpeg.forward_reference = VDP_INVALID_HANDLE; |
|
| 211 |
+ render->info.mpeg.backward_reference = VDP_INVALID_HANDLE; |
|
| 212 |
+ |
|
| 213 |
+ switch(s->pict_type){
|
|
| 214 |
+ case FF_B_TYPE: |
|
| 215 |
+ next = (struct vdpau_render_state*)s->next_picture.data[0]; |
|
| 216 |
+ assert(next); |
|
| 217 |
+ render->info.mpeg.backward_reference = next->surface; |
|
| 218 |
+ // no return here, going to set forward prediction |
|
| 219 |
+ case FF_P_TYPE: |
|
| 220 |
+ last = (struct vdpau_render_state*)s->last_picture.data[0]; |
|
| 221 |
+ if (!last) // FIXME: Does this test make sense? |
|
| 222 |
+ last = render; // predict second field from the first |
|
| 223 |
+ render->info.mpeg.forward_reference = last->surface; |
|
| 224 |
+ } |
|
| 225 |
+ |
|
| 226 |
+ ff_vdpau_add_data_chunk(s, buf, buf_size); |
|
| 227 |
+ |
|
| 228 |
+ render->info.mpeg.slice_count = slice_count; |
|
| 229 |
+ |
|
| 230 |
+ if (slice_count) |
|
| 231 |
+ ff_draw_horiz_band(s, 0, s->avctx->height); |
|
| 232 |
+ render->bitstream_buffers_used = 0; |
|
| 233 |
+} |
|
| 234 |
+ |
|
| 180 | 235 |
/* @}*/ |
| ... | ... |
@@ -122,6 +122,8 @@ enum PixelFormat {
|
| 122 | 122 |
PIX_FMT_YUVJ440P, ///< Planar YUV 4:4:0 full scale (jpeg) |
| 123 | 123 |
PIX_FMT_YUVA420P, ///< Planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) |
| 124 | 124 |
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 |
| 125 |
+ 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 |
|
| 126 |
+ 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 |
|
| 125 | 127 |
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 |
| 126 | 128 |
}; |
| 127 | 129 |
|