nvh264enc: Fix broken Y444 format encoding with system memory Y444 support
authorSeungha Yang <seungha.yang@navercorp.com>
Sat, 4 May 2019 11:56:38 +0000 (20:56 +0900)
committerSeungha Yang <seungha.yang@navercorp.com>
Mon, 6 May 2019 08:30:32 +0000 (17:30 +0900)
separateColourPlaneFlag is mapped to separate_colour_plane_flag which
means Y, U and V planes are separately processed as monochrome sampled pictures.
So encoder shouldn't set that flag for normal 4:4:4 encoding.

Also for 4:4:4 encoding, NV_ENC_H264_PROFILE_HIGH_444_GUID profile must be
explicitly set.

sys/nvenc/gstnvbaseenc.c
sys/nvenc/gstnvh264enc.c

index 42fe7ac92c1c06f8b7ce25d18cc59272fa978265..7dd7a468141e684f3bae37ed8c6b7377423ae889 100644 (file)
@@ -1862,6 +1862,29 @@ gst_nv_base_enc_handle_frame (GstVideoEncoder * enc, GstVideoCodecFrame * frame)
         dest += dest_stride;
         src += src_stride;
       }
+    } else if (GST_VIDEO_FRAME_FORMAT (&vframe) == GST_VIDEO_FORMAT_Y444) {
+      src = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 1);
+      src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 1);
+      dest = (guint8 *) in_buf_lock.bufferDataPtr +
+          GST_ROUND_UP_32 (height) * in_buf_lock.pitch;
+      dest_stride = in_buf_lock.pitch;
+
+      for (y = 0; y < height; ++y) {
+        memcpy (dest, src, width);
+        dest += dest_stride;
+        src += src_stride;
+      }
+
+      src = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 2);
+      src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 2);
+      dest = (guint8 *) in_buf_lock.bufferDataPtr +
+          2 * GST_ROUND_UP_32 (height) * in_buf_lock.pitch;
+
+      for (y = 0; y < height; ++y) {
+        memcpy (dest, src, width);
+        dest += dest_stride;
+        src += src_stride;
+      }
     } else {
       // FIXME: this only works for NV12 and I420
       g_assert_not_reached ();
index 5bae28095c76d3c1457d6cfe8d0d05ebbfaf38d5..c38e0322341641bc8688af2a948719271b7bf21d 100644 (file)
@@ -56,7 +56,7 @@ G_DEFINE_TYPE (GstNvH264Enc, gst_nv_h264_enc, GST_TYPE_NV_BASE_ENC);
 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-raw, " "format = (string) { NV12, I420 }, "       // TODO: YV12, Y444 support
+    GST_STATIC_CAPS ("video/x-raw, " "format = (string) { NV12, I420, Y444 }, "
         "width = (int) [ 16, 4096 ], height = (int) [ 16, 4096 ], "
         "framerate = (fraction) [0, MAX],"
         "interlace-mode = { progressive, mixed, interleaved } "
@@ -510,7 +510,7 @@ gst_nv_h264_enc_set_encoder_config (GstNvBaseEnc * nvenc,
   config->encodeCodecConfig.h264Config.chromaFormatIDC = 1;
   if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_Y444) {
     GST_DEBUG_OBJECT (h264enc, "have Y444 input, setting config accordingly");
-    config->encodeCodecConfig.h264Config.separateColourPlaneFlag = 1;
+    config->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
     config->encodeCodecConfig.h264Config.chromaFormatIDC = 3;
   }