libs: decoder: jpeg: add support 400/411/422/444 chroma type
authorWangfei <fei.w.wang@intel.com>
Thu, 30 May 2019 13:48:51 +0000 (09:48 -0400)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Wed, 26 Jun 2019 10:36:56 +0000 (10:36 +0000)
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.

gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c
gst-libs/gst/vaapi/gstvaapiimage.c
gst-libs/gst/vaapi/video-format.c
gst/vaapi/gstvaapidecode.c
gst/vaapi/gstvaapipluginutil.h

index baed198..8e22568 100644 (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)
index f5c3569..6c10b3b 100644 (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:
index db67cae..a798cd9 100644 (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 */
index cd3624d..5e348f7 100644 (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 =
index b59bbb0..293b409 100644 (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(                                 \