Skip to content

Commit c4bc3e9

Browse files
author
Mark Kendall
committed
Add VAAPI support.
This seems to be pretty stable here although only tested using the xorg edgers ubuntu PPA on an Intel i3 530. - you must be using OpenGL to draw the main UI (otherwise initialisation will fail). - rendering is subclassed from the standard OpenGL video renderer, so OSD, subtitles etc all work as expected. - there is no deinterlacing support. - picture adjustments will follow. - there are some still frame issues with DVD playback. I haven't yet found a file that VAAPI won't accelerate for H.264 and MPEG2, including flawless playback of killa_sampla. Refs #8593
1 parent 0e2c507 commit c4bc3e9

14 files changed

+1033
-6
lines changed

mythtv/configure

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ Advanced options (experts only):
122122
--disable-xv disable XVideo (X11 video output accel.)
123123
--enable-vdpau enable NVidia VDPAU hardware acceleration.
124124
--enable-crystalhd enable Broadcom CrystalHD hardware decoder support
125+
--enablevaapi enable VAAPI hardware accelerated video decoding
125126
--enable-dxva2 enable hardware accelerated decoding on windows
126127
--disable-opengl-video disable OpenGL based video display
127128
--disable-quartz-video disable Mac OS X CoreVideo based video display
@@ -1399,6 +1400,7 @@ USING_LIST='
13991400
dxva2
14001401
opengl
14011402
opengles
1403+
vaapi
14021404
vdpau
14031405
'
14041406

@@ -1775,6 +1777,7 @@ v4l1_deps="backend v4l2 linux_videodev_h"
17751777
vdpau_deps="opengl vdpau_vdpau_h vdpau_vdpau_x11_h"
17761778
xrandr_deps="x11"
17771779
xv_deps="x11"
1780+
vaapi_deps="x11 opengl"
17781781
asi_deps="backend"
17791782

17801783
<<BLOCKQUOTE
@@ -3635,6 +3638,9 @@ check_header sys/select.h
36353638
check_header termios.h
36363639
check_header vdpau/vdpau.h
36373640
check_header vdpau/vdpau_x11.h
3641+
check_header va/va.h
3642+
check_header va/va_x11.h
3643+
check_header va/va_glx.h
36383644

36393645
check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex
36403646

@@ -3914,6 +3920,16 @@ if enabled crystalhd; then
39143920
disable crystalhd;
39153921
fi
39163922

3923+
if enabled vaapi; then
3924+
enabled va_va_h && enabled va_va_glx_h && enabled va_va_x11_h || disable vaapi
3925+
if enabled vaapi; then
3926+
check_cpp_condition va/va.h "VA_VERSION_HEX >= 0x001F0000" ||
3927+
{ echolog "VAAPI requires libva >= 0.31.1" && disable vaapi; }
3928+
fi
3929+
else
3930+
disable vaapi
3931+
fi
3932+
39173933
if enabled dxva2; then
39183934
enabled dxva2api_h && enabled windows || disable dxva2
39193935
else
@@ -4473,6 +4489,7 @@ if enabled x11 ; then
44734489
echo "xrandr support ${xrandr-no}"
44744490
echo "xv support ${xv-no}"
44754491
echo "VDPAU support ${vdpau-no}"
4492+
echo "VAAPI support ${vaapi-no}"
44764493
echo "CrystalHD support ${crystalhd-no}"
44774494
fi
44784495
echo "OpenGL video ${opengl_video-no}"

mythtv/libs/libmythtv/avformatdecoder.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ extern "C" {
5353
#include "videoout_d3d.h"
5454
#endif
5555

56+
#ifdef USING_VAAPI
57+
#include "videoout_openglvaapi.h"
58+
#include "vaapicontext.h"
59+
#endif // USING_VAAPI
60+
5661
extern "C" {
5762
#include "libavutil/avutil.h"
5863
#include "libavcodec/ac3_parser.h"
@@ -125,6 +130,7 @@ void release_avf_buffer_vdpau(struct AVCodecContext *c, AVFrame *pic);
125130
void render_slice_vdpau(struct AVCodecContext *s, const AVFrame *src,
126131
int offset[4], int y, int type, int height);
127132
int get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic);
133+
int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic);
128134

129135
static AVCodec *find_vdpau_decoder(AVCodec *c, enum CodecID id)
130136
{
@@ -238,6 +244,11 @@ void AvFormatDecoder::GetDecoders(render_opts &opts)
238244
(*opts.equiv_decoders)["dxva2"].append("dummy");
239245
#endif
240246

247+
#ifdef USING_VAAPI
248+
opts.decoders->append("vaapi");
249+
(*opts.equiv_decoders)["vaapi"].append("dummy");
250+
#endif
251+
241252
PrivateDecoder::GetDecoders(opts);
242253
}
243254

@@ -1270,6 +1281,13 @@ void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc,
12701281
enc->get_format = get_format_dxva2;
12711282
enc->release_buffer = release_avf_buffer;
12721283
}
1284+
else if (CODEC_IS_VAAPI(codec, enc))
1285+
{
1286+
enc->get_buffer = get_avf_buffer_vaapi;
1287+
enc->get_format = get_format_vaapi;
1288+
enc->release_buffer = release_avf_buffer;
1289+
enc->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
1290+
}
12731291
else if (codec && codec->capabilities & CODEC_CAP_DR1)
12741292
{
12751293
enc->flags |= CODEC_FLAG_EMU_EDGE;
@@ -1805,6 +1823,25 @@ int AvFormatDecoder::ScanStreams(bool novideo)
18051823
handled = true;
18061824
}
18071825
#endif // USING_VDPAU
1826+
#ifdef USING_VAAPI
1827+
MythCodecID vaapi_mcid;
1828+
PixelFormat pix_fmt = PIX_FMT_YUV420P;
1829+
vaapi_mcid = VideoOutputOpenGLVAAPI::GetBestSupportedCodec(
1830+
width, height, mpeg_version(enc->codec_id),
1831+
no_hardware_decoders, pix_fmt);
1832+
1833+
if (vaapi_mcid >= video_codec_id)
1834+
{
1835+
enc->codec_id = (CodecID)myth2av_codecid(vaapi_mcid);
1836+
video_codec_id = vaapi_mcid;
1837+
handled = true;
1838+
if (!no_hardware_decoders &&
1839+
codec_is_vaapi(video_codec_id))
1840+
{
1841+
enc->pix_fmt = pix_fmt;
1842+
}
1843+
}
1844+
#endif // USING_VAAPI
18081845
#ifdef USING_DXVA2
18091846
MythCodecID dxva2_mcid;
18101847
PixelFormat pix_fmt = PIX_FMT_YUV420P;
@@ -2391,6 +2428,32 @@ int get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic)
23912428
return 0;
23922429
}
23932430

2431+
int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic)
2432+
{
2433+
AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque);
2434+
VideoFrame *frame = nd->GetPlayer()->GetNextVideoFrame();
2435+
2436+
pic->data[0] = frame->buf;
2437+
pic->data[1] = NULL;
2438+
pic->data[2] = NULL;
2439+
pic->data[3] = NULL;
2440+
pic->linesize[0] = 0;
2441+
pic->linesize[1] = 0;
2442+
pic->linesize[2] = 0;
2443+
pic->linesize[3] = 0;
2444+
pic->opaque = frame;
2445+
pic->type = FF_BUFFER_TYPE_USER;
2446+
pic->age = 256 * 256 * 256 * 64;
2447+
frame->pix_fmt = c->pix_fmt;
2448+
2449+
#ifdef USING_VAAPI
2450+
if (nd->GetPlayer())
2451+
c->hwaccel_context = (vaapi_context*)nd->GetPlayer()->GetDecoderContext(frame->buf, pic->data[3]);
2452+
#endif
2453+
2454+
return 0;
2455+
}
2456+
23942457
void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
23952458
{
23962459
if (!len)

mythtv/libs/libmythtv/libmythtv.pro

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,11 @@ using_frontend {
370370
using_opengl_video:HEADERS += openglvideo.h videoout_opengl.h
371371
using_opengl_video:SOURCES += openglvideo.cpp videoout_opengl.cpp
372372

373+
using_vaapi: DEFINES += USING_VAAPI
374+
using_vaapi: DEFINES += vaapicontext.h videoout_openglvaapi.h
375+
using_vaapi: SOURCES += vaapicontext.cpp videoout_openglvaapi.cpp
376+
using_vaapi: LIBS += -lva -lva-x11 -lva-glx
377+
373378
# Misc. frontend
374379
HEADERS += DetectLetterbox.h
375380
SOURCES += DetectLetterbox.cpp

mythtv/libs/libmythtv/mythplayer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,10 +1157,10 @@ void MythPlayer::DrawSlice(VideoFrame *frame, int x, int y, int w, int h)
11571157
videoOutput->DrawSlice(frame, x, y, w, h);
11581158
}
11591159

1160-
void* MythPlayer::GetDecoderContext(void)
1160+
void* MythPlayer::GetDecoderContext(unsigned char* buf, uint8_t*& id)
11611161
{
11621162
if (videoOutput)
1163-
return videoOutput->GetDecoderContext();
1163+
return videoOutput->GetDecoderContext(buf, id);
11641164
return NULL;
11651165
}
11661166

mythtv/libs/libmythtv/mythplayer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class MTV_PUBLIC MythPlayer
237237
void DrawSlice(VideoFrame *frame, int x, int y, int w, int h);
238238
/// Returns the stream decoder currently in use.
239239
DecoderBase *GetDecoder(void) { return decoder; }
240-
void *GetDecoderContext(void);
240+
void *GetDecoderContext(unsigned char* buf, uint8_t*& id);
241241

242242
// Preview Image stuff
243243
void SaveScreenshot(void);

0 commit comments

Comments
 (0)