mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 22:46:24 +00:00
v4l2codecs: Sort formats to avoid quality lost
When the driver prefered format is not picked by downstream, the decoders needs to select another format from the list. The selection was currently unsorted, resulting in 10bit data often being stripped to 8bit. To solve this, reorder the formats in an HW preference order. This order deviates slightly from the preferred order in libgstvideo. This is to prefer bandwidth saving over better CPU alignment. As an example NV15 is prefered over P010. We also prefer tiled over linear. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8522>
This commit is contained in:
parent
5e48b89686
commit
33aafc4a91
4 changed files with 76 additions and 15 deletions
|
@ -249833,7 +249833,7 @@
|
|||
"presence": "always"
|
||||
},
|
||||
"src": {
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12_10LE40, P010_10LE, NV12_10LE40_4L4, MT2110T, MT2110R, NV12, YUY2, NV12_4L4, NV12_32L32, NV12_16L32S, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { MT2110R, MT2110T, NV12_10LE40_4L4, NV12_10LE40, P010_10LE, YUY2, NV12_16L32S, NV12_32L32, NV12_4L4, NV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"direction": "src",
|
||||
"presence": "always"
|
||||
}
|
||||
|
@ -249886,7 +249886,7 @@
|
|||
"presence": "always"
|
||||
},
|
||||
"src": {
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12_10LE40, P010_10LE, NV12_10LE40_4L4, MT2110T, MT2110R, NV12, YUY2, NV12_4L4, NV12_32L32, NV12_16L32S, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { MT2110R, MT2110T, NV12_10LE40_4L4, NV12_10LE40, P010_10LE, YUY2, NV12_16L32S, NV12_32L32, NV12_4L4, NV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"direction": "src",
|
||||
"presence": "always"
|
||||
}
|
||||
|
@ -249939,7 +249939,7 @@
|
|||
"presence": "always"
|
||||
},
|
||||
"src": {
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12_10LE40, P010_10LE, NV12_10LE40_4L4, MT2110T, MT2110R, NV12, YUY2, NV12_4L4, NV12_32L32, NV12_16L32S, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { MT2110R, MT2110T, NV12_10LE40_4L4, NV12_10LE40, P010_10LE, YUY2, NV12_16L32S, NV12_32L32, NV12_4L4, NV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"direction": "src",
|
||||
"presence": "always"
|
||||
}
|
||||
|
@ -249992,7 +249992,7 @@
|
|||
"presence": "always"
|
||||
},
|
||||
"src": {
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12_10LE40, P010_10LE, NV12_10LE40_4L4, MT2110T, MT2110R, NV12, YUY2, NV12_4L4, NV12_32L32, NV12_16L32S, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { MT2110R, MT2110T, NV12_10LE40_4L4, NV12_10LE40, P010_10LE, YUY2, NV12_16L32S, NV12_32L32, NV12_4L4, NV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"direction": "src",
|
||||
"presence": "always"
|
||||
}
|
||||
|
@ -250075,7 +250075,7 @@
|
|||
"presence": "always"
|
||||
},
|
||||
"src": {
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12_10LE40, P010_10LE, NV12_10LE40_4L4, MT2110T, MT2110R, NV12, YUY2, NV12_4L4, NV12_32L32, NV12_16L32S, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { MT2110R, MT2110T, NV12_10LE40_4L4, NV12_10LE40, P010_10LE, YUY2, NV12_16L32S, NV12_32L32, NV12_4L4, NV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"direction": "src",
|
||||
"presence": "always"
|
||||
}
|
||||
|
@ -250158,7 +250158,7 @@
|
|||
"presence": "always"
|
||||
},
|
||||
"src": {
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12_10LE40, P010_10LE, NV12_10LE40_4L4, MT2110T, MT2110R, NV12, YUY2, NV12_4L4, NV12_32L32, NV12_16L32S, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"caps": "video/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { MT2110R, MT2110T, NV12_10LE40_4L4, NV12_10LE40, P010_10LE, YUY2, NV12_16L32S, NV12_32L32, NV12_4L4, NV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"direction": "src",
|
||||
"presence": "always"
|
||||
}
|
||||
|
|
|
@ -680,6 +680,7 @@ gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
|
|||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Original caps: %" GST_PTR_FORMAT, caps);
|
||||
caps = gst_v4l2_format_sort_caps (caps);
|
||||
caps = gst_caps_fixate (caps);
|
||||
GST_DEBUG_OBJECT (self, "Fixated caps: %" GST_PTR_FORMAT, caps);
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <gst/allocators/allocators.h>
|
||||
|
||||
#include "gstv4l2format.h"
|
||||
|
||||
#include "linux/drm_fourcc.h"
|
||||
|
@ -42,19 +44,20 @@ typedef struct
|
|||
} GstV4l2FormatDesc;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
/* Keep the same order as GST_V4L2_DEFAULT_VIDEO_FORMATS */
|
||||
static const GstV4l2FormatDesc gst_v4l2_descriptions[] = {
|
||||
{V4L2_PIX_FMT_MM21, GST_VIDEO_FORMAT_NV12_16L32S, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_MT2110T, GST_VIDEO_FORMAT_MT2110T, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_MT2110R, GST_VIDEO_FORMAT_MT2110R, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_NV12, GST_VIDEO_FORMAT_NV12, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_NV12_4L4, GST_VIDEO_FORMAT_NV12_4L4, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_MT2110T, GST_VIDEO_FORMAT_MT2110T, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_NV15_4L4, GST_VIDEO_FORMAT_NV12_10LE40_4L4, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_NV15, GST_VIDEO_FORMAT_NV12_10LE40, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_P010, GST_VIDEO_FORMAT_P010_10LE, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_SUNXI_TILED_NV12, GST_VIDEO_FORMAT_NV12_32L32, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_YUV420M, GST_VIDEO_FORMAT_I420, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_YUYV, GST_VIDEO_FORMAT_YUY2, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_MM21, GST_VIDEO_FORMAT_NV12_16L32S, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_SUNXI_TILED_NV12, GST_VIDEO_FORMAT_NV12_32L32, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_NV12_4L4, GST_VIDEO_FORMAT_NV12_4L4, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_NC12, GST_VIDEO_FORMAT_UNKNOWN, DRM_FORMAT_NV12, DRM_FORMAT_MOD_BROADCOM_SAND128, 2},
|
||||
{V4L2_PIX_FMT_NV12, GST_VIDEO_FORMAT_NV12, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
{V4L2_PIX_FMT_YUV420M, GST_VIDEO_FORMAT_I420, DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID, 0},
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
#define GST_V4L2_FORMAT_DESC_COUNT (G_N_ELEMENTS (gst_v4l2_descriptions))
|
||||
|
@ -337,3 +340,44 @@ gst_v4l2_format_get_n_planes (GstVideoInfoDmaDrm * info)
|
|||
g_warn_if_reached ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
GstCaps *
|
||||
gst_v4l2_format_sort_caps (GstCaps * caps)
|
||||
{
|
||||
const GstV4l2FormatDesc *fmt_descs = gst_v4l2_format_get_descriptions ();
|
||||
GstCaps *sorted_caps = gst_caps_new_empty ();
|
||||
|
||||
for (int i = 0; i < GST_V4L2_FORMAT_DESC_COUNT; i++) {
|
||||
if (fmt_descs[i].drm_fourcc != DRM_FORMAT_INVALID) {
|
||||
guint32 drm_fourcc = fmt_descs[i].drm_fourcc;
|
||||
guint64 drm_modifier = fmt_descs[i].drm_modifier;
|
||||
GValue fmt = G_VALUE_INIT;
|
||||
g_value_init (&fmt, G_TYPE_STRING);
|
||||
g_value_take_string (&fmt,
|
||||
gst_video_dma_drm_fourcc_to_string (drm_fourcc, drm_modifier));
|
||||
|
||||
GstStructure *dma_s = gst_structure_new ("video/x-raw",
|
||||
"format", G_TYPE_STRING, "DMA_DRM", NULL);
|
||||
gst_structure_take_value (dma_s, "drm-format", &fmt);
|
||||
gst_caps_append_structure_full (sorted_caps, dma_s,
|
||||
gst_caps_features_new_static_str (GST_CAPS_FEATURE_MEMORY_DMABUF,
|
||||
NULL));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < GST_V4L2_FORMAT_DESC_COUNT; i++) {
|
||||
if (fmt_descs[i].gst_fmt != GST_VIDEO_FORMAT_UNKNOWN) {
|
||||
GstStructure *s = gst_structure_new ("video/x-raw",
|
||||
"format", G_TYPE_STRING,
|
||||
gst_video_format_to_string (fmt_descs[i].gst_fmt), NULL);
|
||||
gst_caps_append_structure (sorted_caps, s);
|
||||
}
|
||||
}
|
||||
|
||||
GstCaps *ret =
|
||||
gst_caps_intersect_full (sorted_caps, caps, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (sorted_caps);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,24 @@
|
|||
#include <gst/video/video.h>
|
||||
#include "linux/videodev2.h"
|
||||
|
||||
/*
|
||||
* Ordered similar to what libgstvideo does, but keeping tiled formats first,
|
||||
* and prefering bandwidth over alignment (NV12_10LE40 over P010_LE).
|
||||
*/
|
||||
#define GST_V4L2_DEFAULT_VIDEO_FORMATS "{ " \
|
||||
"NV12_10LE40, P010_10LE, NV12_10LE40_4L4, MT2110T, MT2110R," \
|
||||
"NV12, YUY2, NV12_4L4, NV12_32L32, NV12_16L32S, I420" \
|
||||
"}"
|
||||
"MT2110R, " \
|
||||
"MT2110T, " \
|
||||
"NV12_10LE40_4L4, " \
|
||||
"NV12_10LE40, " \
|
||||
"P010_10LE, " \
|
||||
"YUY2, " \
|
||||
"NV12_16L32S, " \
|
||||
"NV12_32L32, " \
|
||||
"NV12_4L4, " \
|
||||
"NV12, " \
|
||||
"I420, " \
|
||||
"}"
|
||||
|
||||
|
||||
gboolean gst_v4l2_format_to_dma_drm_info (struct v4l2_format * fmt,
|
||||
GstVideoInfoDmaDrm * out_drm_info);
|
||||
|
@ -46,3 +60,5 @@ gboolean gst_v4l2_format_from_drm_format (guint32 drm_fourcc,
|
|||
guint32 * out_pix_fmt);
|
||||
|
||||
guint gst_v4l2_format_get_n_planes (GstVideoInfoDmaDrm * info);
|
||||
|
||||
GstCaps * gst_v4l2_format_sort_caps (GstCaps * caps);
|
||||
|
|
Loading…
Reference in a new issue