mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
msdkenc: add need_conversion method
In future, a sub class of GstMsdkEncClass may decide a native format by using this method, e.g. JPEG encoder may accept YUY2 input, however the current implemation needs a conversion from YUY2 to NV12 before encoding. In addtion, a sub class may choose a format for encoding if the input format is not supported by MSDK, e.g. the current implemation does UYVY->NV12 if the input format is UYVY. We may do UYVY->YUY2 for JPEG encoder in future
This commit is contained in:
parent
afce02b392
commit
fbeaa37b79
2 changed files with 67 additions and 37 deletions
|
@ -247,6 +247,7 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
|||
mfxFrameAllocRequest request[2];
|
||||
guint i;
|
||||
gboolean need_vpp = TRUE;
|
||||
GstVideoFormat encoder_input_fmt;
|
||||
|
||||
if (thiz->initialized) {
|
||||
GST_DEBUG_OBJECT (thiz, "Already initialized");
|
||||
|
@ -271,15 +272,11 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
|||
if (thiz->use_video_memory)
|
||||
gst_msdk_set_frame_allocator (thiz->context);
|
||||
|
||||
encoder_input_fmt = GST_VIDEO_INFO_FORMAT (info);
|
||||
need_vpp = klass->need_conversion (thiz, info, &encoder_input_fmt);
|
||||
|
||||
if (need_vpp) {
|
||||
switch (GST_VIDEO_INFO_FORMAT (info)) {
|
||||
case GST_VIDEO_FORMAT_NV12:
|
||||
case GST_VIDEO_FORMAT_P010_10LE:
|
||||
case GST_VIDEO_FORMAT_VUYA:
|
||||
#if (MFX_VERSION >= 1027)
|
||||
case GST_VIDEO_FORMAT_Y410:
|
||||
#endif
|
||||
need_vpp = FALSE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_YV12:
|
||||
case GST_VIDEO_FORMAT_I420:
|
||||
thiz->vpp_param.vpp.In.FourCC = MFX_FOURCC_YV12;
|
||||
|
@ -302,7 +299,6 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
|||
break;
|
||||
}
|
||||
|
||||
if (need_vpp) {
|
||||
if (thiz->use_video_memory)
|
||||
thiz->vpp_param.IOPattern =
|
||||
MFX_IOPATTERN_IN_VIDEO_MEMORY | MFX_IOPATTERN_OUT_VIDEO_MEMORY;
|
||||
|
@ -326,7 +322,7 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
|||
|
||||
thiz->vpp_param.vpp.Out = thiz->vpp_param.vpp.In;
|
||||
|
||||
if ((GST_VIDEO_INFO_COMP_DEPTH (info, 0)) == 10) {
|
||||
if (encoder_input_fmt == GST_VIDEO_FORMAT_P010_10LE) {
|
||||
thiz->vpp_param.vpp.Out.FourCC = MFX_FOURCC_P010;
|
||||
thiz->vpp_param.vpp.Out.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
|
||||
} else {
|
||||
|
@ -418,7 +414,7 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
|||
thiz->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
|
||||
thiz->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
|
||||
|
||||
switch (GST_VIDEO_INFO_FORMAT (info)) {
|
||||
switch (encoder_input_fmt) {
|
||||
case GST_VIDEO_FORMAT_P010_10LE:
|
||||
thiz->param.mfx.FrameInfo.FourCC = MFX_FOURCC_P010;
|
||||
thiz->param.mfx.FrameInfo.BitDepthLuma = 10;
|
||||
|
@ -1133,14 +1129,17 @@ gst_msdkenc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
|
|||
/* Create another bufferpool if VPP requires */
|
||||
if (thiz->has_vpp) {
|
||||
GstVideoInfo *info = &thiz->input_state->info;
|
||||
GstVideoInfo nv12_info;
|
||||
GstVideoInfo out_info;
|
||||
GstVideoFormat out_fmt;
|
||||
GstCaps *caps;
|
||||
GstBufferPool *pool = NULL;
|
||||
|
||||
gst_video_info_init (&nv12_info);
|
||||
gst_video_info_set_format (&nv12_info, GST_VIDEO_FORMAT_NV12, info->width,
|
||||
info->height);
|
||||
caps = gst_video_info_to_caps (&nv12_info);
|
||||
gst_video_info_init (&out_info);
|
||||
out_fmt =
|
||||
gst_msdk_get_video_format_from_mfx_fourcc (thiz->vpp_param.vpp.
|
||||
Out.FourCC);
|
||||
gst_video_info_set_format (&out_info, out_fmt, info->width, info->height);
|
||||
caps = gst_video_info_to_caps (&out_info);
|
||||
|
||||
/* If there's an existing pool try to reuse it when is compatible */
|
||||
if (thiz->msdk_converted_pool) {
|
||||
|
@ -1634,6 +1633,28 @@ gst_msdkenc_finalize (GObject * object)
|
|||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_msdkenc_need_conversion (GstMsdkEnc * encoder, GstVideoInfo * info,
|
||||
GstVideoFormat * out_format)
|
||||
{
|
||||
switch (GST_VIDEO_INFO_FORMAT (info)) {
|
||||
case GST_VIDEO_FORMAT_NV12:
|
||||
case GST_VIDEO_FORMAT_P010_10LE:
|
||||
case GST_VIDEO_FORMAT_VUYA:
|
||||
#if (MFX_VERSION >= 1027)
|
||||
case GST_VIDEO_FORMAT_Y410:
|
||||
#endif
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
if (GST_VIDEO_INFO_COMP_DEPTH (info, 0) == 10)
|
||||
*out_format = GST_VIDEO_FORMAT_P010_10LE;
|
||||
else
|
||||
*out_format = GST_VIDEO_FORMAT_NV12;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_msdkenc_class_init (GstMsdkEncClass * klass)
|
||||
{
|
||||
|
@ -1645,6 +1666,8 @@ gst_msdkenc_class_init (GstMsdkEncClass * klass)
|
|||
element_class = GST_ELEMENT_CLASS (klass);
|
||||
gstencoder_class = GST_VIDEO_ENCODER_CLASS (klass);
|
||||
|
||||
klass->need_conversion = gst_msdkenc_need_conversion;
|
||||
|
||||
gobject_class->finalize = gst_msdkenc_finalize;
|
||||
|
||||
element_class->set_context = gst_msdkenc_set_context;
|
||||
|
|
|
@ -167,6 +167,13 @@ struct _GstMsdkEncClass
|
|||
gboolean (*set_format) (GstMsdkEnc * encoder);
|
||||
gboolean (*configure) (GstMsdkEnc * encoder);
|
||||
GstCaps *(*set_src_caps) (GstMsdkEnc * encoder);
|
||||
/* Return TRUE if vpp is required before encoding
|
||||
* @info (in), input video info
|
||||
* @out_format (out), a pointer to the output format of vpp, which is set
|
||||
* when return TRUE
|
||||
*/
|
||||
gboolean (*need_conversion) (GstMsdkEnc * encoder, GstVideoInfo * info,
|
||||
GstVideoFormat * out_format);
|
||||
};
|
||||
|
||||
struct _MsdkEncTask
|
||||
|
|
Loading…
Reference in a new issue