This allows user set hw_device_ctx instead of hw_frames_ctx for QSV decoders, hence we may remove the ad-hoc libmfx setup code from FFmpeg. "-hwaccel_output_format format" is applied to QSV decoders after removing the ad-hoc libmfx code. In order to keep compatibility with old commandlines, the default format is set to AV_PIX_FMT_QSV, but this behavior will be removed in the future. Please set "-hwaccel_output_format qsv" explicitly if AV_PIX_FMT_QSV is expected. The normal device stuff works for QSV decoders now, user may use "-init_hw_device args" to initialise device and "-hwaccel_device devicename" to select a device for QSV decoders. "-qsv_device device" which was added for workarounding device selection in the ad-hoc libmfx code still works For example: $> ffmpeg -init_hw_device qsv=qsv:hw_any,child_device=/dev/dri/card0 -hwaccel qsv -c:v h264_qsv -i input.h264 -f null - /dev/dri/renderD128 is actually open for h264_qsv decoder in the above command without this patch. After applying this patch, /dev/dri/card0 is used. $> ffmpeg -init_hw_device vaapi=va:/dev/dri/card0 -init_hw_device qsv=hw@va -hwaccel_device hw -hwaccel qsv -c:v h264_qsv -i input.h264 -f null - device hw of type qsv is not usable in the above command without this patch. After applying this patch, this command works as expected. Reviewed-by: Soft Works <softworkz@hotmail.com> Signed-off-by: James Almer <jamrial@gmail.com>pull/364/head
parent
35b1f46d79
commit
ecee3b07cd
6 changed files with 66 additions and 116 deletions
@ -1,109 +0,0 @@ |
|||||||
/*
|
|
||||||
* This file is part of FFmpeg. |
|
||||||
* |
|
||||||
* FFmpeg is free software; you can redistribute it and/or |
|
||||||
* modify it under the terms of the GNU Lesser General Public |
|
||||||
* License as published by the Free Software Foundation; either |
|
||||||
* version 2.1 of the License, or (at your option) any later version. |
|
||||||
* |
|
||||||
* FFmpeg is distributed in the hope that it will be useful, |
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||||
* Lesser General Public License for more details. |
|
||||||
* |
|
||||||
* You should have received a copy of the GNU Lesser General Public |
|
||||||
* License along with FFmpeg; if not, write to the Free Software |
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <mfx/mfxvideo.h> |
|
||||||
#include <stdlib.h> |
|
||||||
|
|
||||||
#include "libavutil/dict.h" |
|
||||||
#include "libavutil/hwcontext.h" |
|
||||||
#include "libavutil/hwcontext_qsv.h" |
|
||||||
#include "libavutil/opt.h" |
|
||||||
#include "libavcodec/qsv.h" |
|
||||||
|
|
||||||
#include "ffmpeg.h" |
|
||||||
|
|
||||||
static AVBufferRef *hw_device_ctx; |
|
||||||
char *qsv_device = NULL; |
|
||||||
|
|
||||||
static int qsv_get_buffer(AVCodecContext *s, AVFrame *frame, int flags) |
|
||||||
{ |
|
||||||
InputStream *ist = s->opaque; |
|
||||||
|
|
||||||
return av_hwframe_get_buffer(ist->hw_frames_ctx, frame, 0); |
|
||||||
} |
|
||||||
|
|
||||||
static void qsv_uninit(AVCodecContext *s) |
|
||||||
{ |
|
||||||
InputStream *ist = s->opaque; |
|
||||||
av_buffer_unref(&ist->hw_frames_ctx); |
|
||||||
} |
|
||||||
|
|
||||||
static int qsv_device_init(InputStream *ist) |
|
||||||
{ |
|
||||||
int err; |
|
||||||
AVDictionary *dict = NULL; |
|
||||||
|
|
||||||
if (qsv_device) { |
|
||||||
err = av_dict_set(&dict, "child_device", qsv_device, 0); |
|
||||||
if (err < 0) |
|
||||||
return err; |
|
||||||
} |
|
||||||
|
|
||||||
err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV, |
|
||||||
ist->hwaccel_device, dict, 0); |
|
||||||
if (err < 0) { |
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error creating a QSV device\n"); |
|
||||||
goto err_out; |
|
||||||
} |
|
||||||
|
|
||||||
err_out: |
|
||||||
if (dict) |
|
||||||
av_dict_free(&dict); |
|
||||||
|
|
||||||
return err; |
|
||||||
} |
|
||||||
|
|
||||||
int qsv_init(AVCodecContext *s) |
|
||||||
{ |
|
||||||
InputStream *ist = s->opaque; |
|
||||||
AVHWFramesContext *frames_ctx; |
|
||||||
AVQSVFramesContext *frames_hwctx; |
|
||||||
int ret; |
|
||||||
|
|
||||||
if (!hw_device_ctx) { |
|
||||||
ret = qsv_device_init(ist); |
|
||||||
if (ret < 0) |
|
||||||
return ret; |
|
||||||
} |
|
||||||
|
|
||||||
av_buffer_unref(&ist->hw_frames_ctx); |
|
||||||
ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx); |
|
||||||
if (!ist->hw_frames_ctx) |
|
||||||
return AVERROR(ENOMEM); |
|
||||||
|
|
||||||
frames_ctx = (AVHWFramesContext*)ist->hw_frames_ctx->data; |
|
||||||
frames_hwctx = frames_ctx->hwctx; |
|
||||||
|
|
||||||
frames_ctx->width = FFALIGN(s->coded_width, 32); |
|
||||||
frames_ctx->height = FFALIGN(s->coded_height, 32); |
|
||||||
frames_ctx->format = AV_PIX_FMT_QSV; |
|
||||||
frames_ctx->sw_format = s->sw_pix_fmt; |
|
||||||
frames_ctx->initial_pool_size = 64 + s->extra_hw_frames; |
|
||||||
frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; |
|
||||||
|
|
||||||
ret = av_hwframe_ctx_init(ist->hw_frames_ctx); |
|
||||||
if (ret < 0) { |
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n"); |
|
||||||
return ret; |
|
||||||
} |
|
||||||
|
|
||||||
ist->hwaccel_get_buffer = qsv_get_buffer; |
|
||||||
ist->hwaccel_uninit = qsv_uninit; |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
Loading…
Reference in new issue