diff options
author | Torsten Jager <t.jager@gmx.de> | 2013-07-27 16:10:12 +0300 |
---|---|---|
committer | Torsten Jager <t.jager@gmx.de> | 2013-07-27 16:10:12 +0300 |
commit | a771cb809c8f14057536f28f62930d32c2d4f088 (patch) | |
tree | 33dfa0db6eee2ec43954c0ad7a64a3bedbf26a06 | |
parent | b5862770bdc41aa4d5501bf7cc3a620ef9d69bb6 (diff) | |
download | xine-lib-a771cb809c8f14057536f28f62930d32c2d4f088.tar.gz xine-lib-a771cb809c8f14057536f28f62930d32c2d4f088.tar.bz2 |
Reinitialize VAAPI in get_buffer() when image size changes
-rw-r--r-- | src/combined/ffmpeg/ff_video_decoder.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index 94a0d251d..662c52a71 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -157,6 +157,8 @@ struct ff_video_decoder_s { uint8_t set_stream_info; #ifdef ENABLE_VAAPI + int vaapi_width, vaapi_height; + int vaapi_profile; struct vaapi_context vaapi_context; vaapi_accel_t *accel; vo_frame_t *accel_img; @@ -257,6 +259,26 @@ static int get_buffer(AVCodecContext *context, AVFrame *av_frame){ #endif av_frame->reordered_opaque = context->reordered_opaque; + /* reinitialize vaapi for new image size */ + if (context->width != this->vaapi_width || context->height != this->vaapi_height) { + VAStatus status; + + this->vaapi_width = context->width; + this->vaapi_height = context->height; + status = this->accel->vaapi_init (this->accel_img, this->vaapi_profile, + context->width, context->height, 0); + + if (status == VA_STATUS_SUCCESS) { + ff_vaapi_context_t *va_context = this->accel->get_context (this->accel_img); + + if (va_context) { + this->vaapi_context.config_id = va_context->va_config_id; + this->vaapi_context.context_id = va_context->va_context_id; + this->vaapi_context.display = va_context->va_display; + } + } + } + if(!this->accel->guarded_render(this->accel_img)) { img = this->stream->video_out->get_frame (this->stream->video_out, width, @@ -436,9 +458,14 @@ static const int skip_loop_filter_enum_values[] = { }; #ifdef ENABLE_VAAPI +/* TJ. libavcodec calls this with a list of supported pixel formats and lets us choose 1. + Returning PIX_FMT_VAAPI_VLD enables VAAPI. + However, at this point we only got image width and height from container, being unreliable + or zero (MPEG-TS). Thus we repeat vaapi_context initialization in get_buffer when needed. + This should be OK since NAL unit parsing is always done in software. */ static enum PixelFormat get_format(struct AVCodecContext *context, const enum PixelFormat *fmt) { - int i, profile; + int i; ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; if(!this->class->enable_vaapi || !this->accel_img) @@ -450,12 +477,21 @@ static enum PixelFormat get_format(struct AVCodecContext *context, const enum Pi if (fmt[i] != PIX_FMT_VAAPI_VLD) continue; - profile = accel->profile_from_imgfmt(this->accel_img, fmt[i], context->codec_id, this->class->vaapi_mpeg_softdec); + this->vaapi_profile = accel->profile_from_imgfmt (this->accel_img, fmt[i], + context->codec_id, this->class->vaapi_mpeg_softdec); - if (profile >= 0) { + if (this->vaapi_profile >= 0) { + int width = context->width; + int height = context->height; VAStatus status; - status = accel->vaapi_init(this->accel_img, profile, context->width, context->height, 0); + if (!width || !height) { + width = 1920; + height = 1080; + } + this->vaapi_width = width; + this->vaapi_height = height; + status = accel->vaapi_init (this->accel_img, this->vaapi_profile, width, height, 0); if( status == VA_STATUS_SUCCESS ) { ff_vaapi_context_t *va_context = accel->get_context(this->accel_img); |