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];
|
mfxFrameAllocRequest request[2];
|
||||||
guint i;
|
guint i;
|
||||||
gboolean need_vpp = TRUE;
|
gboolean need_vpp = TRUE;
|
||||||
|
GstVideoFormat encoder_input_fmt;
|
||||||
|
|
||||||
if (thiz->initialized) {
|
if (thiz->initialized) {
|
||||||
GST_DEBUG_OBJECT (thiz, "Already initialized");
|
GST_DEBUG_OBJECT (thiz, "Already initialized");
|
||||||
|
@ -271,15 +272,11 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
||||||
if (thiz->use_video_memory)
|
if (thiz->use_video_memory)
|
||||||
gst_msdk_set_frame_allocator (thiz->context);
|
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)) {
|
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_YV12:
|
||||||
case GST_VIDEO_FORMAT_I420:
|
case GST_VIDEO_FORMAT_I420:
|
||||||
thiz->vpp_param.vpp.In.FourCC = MFX_FOURCC_YV12;
|
thiz->vpp_param.vpp.In.FourCC = MFX_FOURCC_YV12;
|
||||||
|
@ -302,7 +299,6 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_vpp) {
|
|
||||||
if (thiz->use_video_memory)
|
if (thiz->use_video_memory)
|
||||||
thiz->vpp_param.IOPattern =
|
thiz->vpp_param.IOPattern =
|
||||||
MFX_IOPATTERN_IN_VIDEO_MEMORY | MFX_IOPATTERN_OUT_VIDEO_MEMORY;
|
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;
|
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.FourCC = MFX_FOURCC_P010;
|
||||||
thiz->vpp_param.vpp.Out.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
|
thiz->vpp_param.vpp.Out.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
|
||||||
} else {
|
} else {
|
||||||
|
@ -418,7 +414,7 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
||||||
thiz->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
|
thiz->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
|
||||||
thiz->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
|
thiz->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
|
||||||
|
|
||||||
switch (GST_VIDEO_INFO_FORMAT (info)) {
|
switch (encoder_input_fmt) {
|
||||||
case GST_VIDEO_FORMAT_P010_10LE:
|
case GST_VIDEO_FORMAT_P010_10LE:
|
||||||
thiz->param.mfx.FrameInfo.FourCC = MFX_FOURCC_P010;
|
thiz->param.mfx.FrameInfo.FourCC = MFX_FOURCC_P010;
|
||||||
thiz->param.mfx.FrameInfo.BitDepthLuma = 10;
|
thiz->param.mfx.FrameInfo.BitDepthLuma = 10;
|
||||||
|
@ -1133,14 +1129,17 @@ gst_msdkenc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
|
||||||
/* Create another bufferpool if VPP requires */
|
/* Create another bufferpool if VPP requires */
|
||||||
if (thiz->has_vpp) {
|
if (thiz->has_vpp) {
|
||||||
GstVideoInfo *info = &thiz->input_state->info;
|
GstVideoInfo *info = &thiz->input_state->info;
|
||||||
GstVideoInfo nv12_info;
|
GstVideoInfo out_info;
|
||||||
|
GstVideoFormat out_fmt;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstBufferPool *pool = NULL;
|
GstBufferPool *pool = NULL;
|
||||||
|
|
||||||
gst_video_info_init (&nv12_info);
|
gst_video_info_init (&out_info);
|
||||||
gst_video_info_set_format (&nv12_info, GST_VIDEO_FORMAT_NV12, info->width,
|
out_fmt =
|
||||||
info->height);
|
gst_msdk_get_video_format_from_mfx_fourcc (thiz->vpp_param.vpp.
|
||||||
caps = gst_video_info_to_caps (&nv12_info);
|
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 there's an existing pool try to reuse it when is compatible */
|
||||||
if (thiz->msdk_converted_pool) {
|
if (thiz->msdk_converted_pool) {
|
||||||
|
@ -1634,6 +1633,28 @@ gst_msdkenc_finalize (GObject * object)
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (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
|
static void
|
||||||
gst_msdkenc_class_init (GstMsdkEncClass * klass)
|
gst_msdkenc_class_init (GstMsdkEncClass * klass)
|
||||||
{
|
{
|
||||||
|
@ -1645,6 +1666,8 @@ gst_msdkenc_class_init (GstMsdkEncClass * klass)
|
||||||
element_class = GST_ELEMENT_CLASS (klass);
|
element_class = GST_ELEMENT_CLASS (klass);
|
||||||
gstencoder_class = GST_VIDEO_ENCODER_CLASS (klass);
|
gstencoder_class = GST_VIDEO_ENCODER_CLASS (klass);
|
||||||
|
|
||||||
|
klass->need_conversion = gst_msdkenc_need_conversion;
|
||||||
|
|
||||||
gobject_class->finalize = gst_msdkenc_finalize;
|
gobject_class->finalize = gst_msdkenc_finalize;
|
||||||
|
|
||||||
element_class->set_context = gst_msdkenc_set_context;
|
element_class->set_context = gst_msdkenc_set_context;
|
||||||
|
|
|
@ -167,6 +167,13 @@ struct _GstMsdkEncClass
|
||||||
gboolean (*set_format) (GstMsdkEnc * encoder);
|
gboolean (*set_format) (GstMsdkEnc * encoder);
|
||||||
gboolean (*configure) (GstMsdkEnc * encoder);
|
gboolean (*configure) (GstMsdkEnc * encoder);
|
||||||
GstCaps *(*set_src_caps) (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
|
struct _MsdkEncTask
|
||||||
|
|
Loading…
Reference in a new issue