libs: decoder: jpeg: add support 400/411/422/444 chroma type

When create vaapi surface, it is better to use the chroma type get
from jpeg file instead of using fixed 420 format. And the correct
chroma type can be determined by horizontal_factor/vertical_factor
flags that get from jpegparse.
This commit is contained in:
Wangfei 2019-05-30 09:48:51 -04:00 committed by Víctor Manuel Jáquez Leal
parent 3b5c7aa688
commit 67ed67515b
5 changed files with 53 additions and 3 deletions

View file

@ -169,10 +169,55 @@ gst_vaapi_decoder_jpeg_reset (GstVaapiDecoder * base_decoder)
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static gboolean
get_chroma_type (GstJpegFrameHdr * frame_hdr, GstVaapiChromaType * chroma_type)
{
int h0 = frame_hdr->components[0].horizontal_factor;
int h1 = frame_hdr->components[1].horizontal_factor;
int h2 = frame_hdr->components[2].horizontal_factor;
int v0 = frame_hdr->components[0].vertical_factor;
int v1 = frame_hdr->components[1].vertical_factor;
int v2 = frame_hdr->components[2].vertical_factor;
if (frame_hdr->num_components == 1) {
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400;
return TRUE;
}
if (h1 != h2 || v1 != v2)
return FALSE;
if (h0 == h1) {
if (v0 == v1)
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
else if (v0 == 2 * v1)
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
else
return FALSE;
} else if (h0 == 2 * h1) {
if (v0 == v1)
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
else if (v0 == 2 * v1)
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
else
return FALSE;
} else if (h0 == 4 * h1) {
if (v0 == v1)
*chroma_type = GST_VAAPI_CHROMA_TYPE_YUV411;
else
return FALSE;
} else
return FALSE;
return TRUE;
}
static GstVaapiDecoderStatus
ensure_context (GstVaapiDecoderJpeg * decoder)
{
GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
GstJpegFrameHdr *const frame_hdr = &priv->frame_hdr;
GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
GstVaapiProfile profiles[2];
GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
guint i, n_profiles = 0;
@ -208,10 +253,13 @@ ensure_context (GstVaapiDecoderJpeg * decoder)
info.profile = priv->profile;
info.entrypoint = entrypoint;
info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
info.width = priv->width;
info.height = priv->height;
info.ref_frames = 2;
if (!get_chroma_type (frame_hdr, &chroma_type))
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
info.chroma_type = chroma_type;
reset_context =
gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info);
if (!reset_context)

View file

@ -100,6 +100,7 @@ vaapi_image_is_linear (const VAImage * va_image)
data_size = 2 * (width * height + 2 * width2 * height2);
break;
case VA_FOURCC ('R', 'G', '2', '4'):
case VA_FOURCC ('4', '4', '4', 'P'):
data_size = 3 * width * height;
break;
default:

View file

@ -67,6 +67,7 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = {
DEF_YUV (Y210, ('Y', '2', '1', '0'), 32, 422_10BPP),
DEF_YUV (Y410, ('Y', '4', '1', '0'), 32, 444_10BPP),
DEF_YUV (AYUV, ('A', 'Y', 'U', 'V'), 32, 444),
DEF_YUV (Y444, ('4', '4', '4', 'P'), 24, 444),
DEF_YUV (GRAY8, ('Y', '8', '0', '0'), 8, 400),
DEF_YUV (P010_10LE, ('P', '0', '1', '0'), 24, 420_10BPP),
/* RGB formats */

View file

@ -81,7 +81,7 @@ static const char gst_vaapidecode_src_caps_str[] =
#if (USE_GLX || USE_EGL)
GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";"
#endif
GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }") ";"
GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410, Y444 }") ";"
GST_VAAPI_MAKE_DMABUF_CAPS;
static GstStaticPadTemplate gst_vaapidecode_src_factory =

View file

@ -105,7 +105,7 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps,
#define GST_VAAPI_MAKE_SURFACE_CAPS \
GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \
GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }")
GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410, Y444 }")
#define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \
GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \