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 baed198712e0745449210fc242ba4dacc4b91688..8e22568e40c7808c97c7f2a7dfead142bc511bf7 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 f5c3569b60c069040c0605236d42e81d899292e5..6c10b3b9524d9eaba643256a021272a32f24106c 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 db67cae4725ab66b1eca3fa09465838c8c425e95..a798cd995d5a18c23f8173f74bb85ecfd1970723 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 cd3624d8d1a1a867007761bf9236fedf822af241..5e348f78d2f9449b8dd9310d2d71837f3b016f08 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 b59bbb041b3809f557e8ca303b9a9c032b368601..293b40924f259e63871a38e61d87961332d51dfd 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(                                 \