Coverage Report

Created: 2025-09-05 06:29

/src/gstreamer/subprojects/gst-plugins-base/gst-libs/gst/video/video-info-dma.c
Line
Count
Source (jump to first uncovered line)
1
/* GStreamer
2
 * Copyright (C) 2022 Intel Corporation
3
 *     Author: He Junyan <junyan.he@intel.com>
4
 *     Author: Liu Yinhang <yinhang.liu@intel.com>
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Library General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Library General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Library General Public
17
 * License along with this library; if not, write to the
18
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19
 * Boston, MA 02110-1301, USA.
20
 */
21
22
/**
23
 * SECTION:video-info-dma-drm
24
 * @title: GstVideoInfoDmaDrm
25
 * @short_description: Structures and enumerations to describe DMA video
26
 *  format in DRM mode.
27
 */
28
29
30
#include "video-format.h"
31
#ifdef HAVE_CONFIG_H
32
#  include "config.h"
33
#endif
34
35
#include "video-info-dma.h"
36
#include "ext/drm_fourcc.h"
37
38
#include <gst/allocators/gstdmabuf.h>
39
40
#ifndef GST_DISABLE_GST_DEBUG
41
#define GST_CAT_DEFAULT ensure_debug_category()
42
static GstDebugCategory *
43
ensure_debug_category (void)
44
0
{
45
0
  static gsize cat_gonce = 0;
46
47
0
  if (g_once_init_enter (&cat_gonce)) {
48
0
    gsize cat_done;
49
50
0
    cat_done = (gsize) _gst_debug_category_new ("video-info-dma-drm", 0,
51
0
        "video-info-dma-drm structure");
52
53
0
    g_once_init_leave (&cat_gonce, cat_done);
54
0
  }
55
56
0
  return (GstDebugCategory *) cat_gonce;
57
0
}
58
#else
59
#define ensure_debug_category() /* NOOP */
60
#endif /* GST_DISABLE_GST_DEBUG */
61
62
static GstVideoInfoDmaDrm *
63
gst_video_info_dma_drm_copy (const GstVideoInfoDmaDrm * drm_info)
64
0
{
65
0
  return g_memdup2 (drm_info, sizeof (GstVideoInfoDmaDrm));
66
0
}
67
68
/**
69
 * gst_video_info_dma_drm_free:
70
 * @drm_info: a #GstVideoInfoDmaDrm
71
 *
72
 * Free a #GstVideoInfoDmaDrm structure previously allocated with
73
 * gst_video_info_dma_drm_new()
74
 *
75
 * Since: 1.24
76
 */
77
void
78
gst_video_info_dma_drm_free (GstVideoInfoDmaDrm * drm_info)
79
0
{
80
0
  g_free (drm_info);
81
0
}
82
83
G_DEFINE_BOXED_TYPE (GstVideoInfoDmaDrm, gst_video_info_dma_drm,
84
    (GBoxedCopyFunc) gst_video_info_dma_drm_copy,
85
    (GBoxedFreeFunc) gst_video_info_dma_drm_free);
86
87
/**
88
 * gst_video_info_dma_drm_init:
89
 * @drm_info: (out caller-allocates): a #GstVideoInfoDmaDrm
90
 *
91
 * Initialize @drm_info with default values.
92
 *
93
 * Since: 1.24
94
 */
95
void
96
gst_video_info_dma_drm_init (GstVideoInfoDmaDrm * drm_info)
97
0
{
98
0
  g_return_if_fail (drm_info != NULL);
99
100
0
  gst_video_info_init (&drm_info->vinfo);
101
102
0
  drm_info->drm_fourcc = DRM_FORMAT_INVALID;
103
0
  drm_info->drm_modifier = DRM_FORMAT_MOD_INVALID;
104
0
}
105
106
/**
107
 * gst_video_info_dma_drm_new:
108
 *
109
 * Allocate a new #GstVideoInfoDmaDrm that is also initialized with
110
 * gst_video_info_dma_drm_init().
111
 *
112
 * Returns: (transfer full): a new #GstVideoInfoDmaDrm.
113
 * Free it with gst_video_info_dma_drm_free().
114
 *
115
 * Since: 1.24
116
 */
117
GstVideoInfoDmaDrm *
118
gst_video_info_dma_drm_new (void)
119
0
{
120
0
  GstVideoInfoDmaDrm *info;
121
122
0
  info = g_new (GstVideoInfoDmaDrm, 1);
123
0
  gst_video_info_dma_drm_init (info);
124
125
0
  return info;
126
0
}
127
128
/**
129
 * gst_video_is_dma_drm_caps:
130
 * @caps: a #GstCaps
131
 *
132
 * Check whether the @caps is a dma drm kind caps. Please note that
133
 * the caps should be fixed.
134
 *
135
 * Returns: %TRUE if the caps is a dma drm caps.
136
 *
137
 * Since: 1.24
138
 */
139
gboolean
140
gst_video_is_dma_drm_caps (const GstCaps * caps)
141
0
{
142
0
  GstStructure *structure;
143
144
0
  g_return_val_if_fail (caps != NULL, FALSE);
145
146
0
  if (!gst_caps_is_fixed (caps))
147
0
    return FALSE;
148
149
0
  if (!gst_caps_features_contains (gst_caps_get_features (caps, 0),
150
0
          GST_CAPS_FEATURE_MEMORY_DMABUF))
151
0
    return FALSE;
152
153
0
  structure = gst_caps_get_structure (caps, 0);
154
155
0
  if (g_strcmp0 (gst_structure_get_string (structure, "format"),
156
0
          "DMA_DRM") != 0)
157
0
    return FALSE;
158
159
0
  return TRUE;
160
0
}
161
162
/**
163
 * gst_video_info_dma_drm_to_caps:
164
 * @drm_info: a #GstVideoInfoDmaDrm
165
 *
166
 * Convert the values of @drm_info into a #GstCaps. Please note that the
167
 * @caps returned will be a dma drm caps which sets format field to DMA_DRM,
168
 * and contains a new drm-format field. The value of drm-format field is
169
 * composed of a drm fourcc and a modifier, such as NV12:0x0100000000000002.
170
 *
171
 * Returns: (transfer full) (nullable): a new #GstCaps containing the
172
 * info in @drm_info.
173
 *
174
 * Since: 1.24
175
 */
176
GstCaps *
177
gst_video_info_dma_drm_to_caps (const GstVideoInfoDmaDrm * drm_info)
178
0
{
179
0
  GstCaps *caps;
180
0
  GstStructure *structure;
181
0
  gchar *str;
182
183
0
  g_return_val_if_fail (drm_info != NULL, NULL);
184
0
  g_return_val_if_fail (drm_info->drm_fourcc != DRM_FORMAT_INVALID, NULL);
185
0
  g_return_val_if_fail (drm_info->drm_modifier != DRM_FORMAT_MOD_INVALID, NULL);
186
187
0
  caps = gst_video_info_to_caps (&drm_info->vinfo);
188
0
  if (!caps) {
189
0
    GST_DEBUG ("Failed to create caps from video info");
190
0
    return NULL;
191
0
  }
192
193
0
  gst_caps_set_features_simple (caps,
194
0
      gst_caps_features_new_single_static_str (GST_CAPS_FEATURE_MEMORY_DMABUF));
195
196
0
  str = gst_video_dma_drm_fourcc_to_string (drm_info->drm_fourcc,
197
0
      drm_info->drm_modifier);
198
199
0
  structure = gst_caps_get_structure (caps, 0);
200
0
  gst_structure_set (structure, "format", G_TYPE_STRING, "DMA_DRM",
201
0
      "drm-format", G_TYPE_STRING, str, NULL);
202
203
0
  g_free (str);
204
205
0
  return caps;
206
0
}
207
208
/**
209
 * gst_video_info_dma_drm_from_caps:
210
 * @drm_info: (out caller-allocates): #GstVideoInfoDmaDrm
211
 * @caps: a #GstCaps
212
 *
213
 * Parse @caps and update @info. Please note that the @caps should be
214
 * a dma drm caps. The gst_video_is_dma_drm_caps() can be used to verify
215
 * it before calling this function.
216
 *
217
 * Returns: TRUE if @caps could be parsed
218
 *
219
 * Since: 1.24
220
 */
221
gboolean
222
gst_video_info_dma_drm_from_caps (GstVideoInfoDmaDrm * drm_info,
223
    const GstCaps * caps)
224
0
{
225
0
  GstStructure *structure;
226
0
  const gchar *str;
227
0
  guint32 fourcc;
228
0
  guint64 modifier;
229
0
  GstVideoFormat format;
230
0
  GstCaps *tmp_caps = NULL;
231
0
  gboolean ret;
232
233
0
  g_return_val_if_fail (drm_info != NULL, FALSE);
234
0
  g_return_val_if_fail (caps != NULL, FALSE);
235
236
0
  if (!gst_video_is_dma_drm_caps (caps))
237
0
    return FALSE;
238
239
0
  GST_DEBUG ("parsing caps %" GST_PTR_FORMAT, caps);
240
241
0
  tmp_caps = gst_caps_copy (caps);
242
0
  structure = gst_caps_get_structure (tmp_caps, 0);
243
244
0
  str = gst_structure_get_string (structure, "drm-format");
245
0
  if (!str) {
246
0
    GST_DEBUG ("drm caps %" GST_PTR_FORMAT "has no drm-format field", caps);
247
0
    ret = FALSE;
248
0
    goto out;
249
0
  }
250
251
0
  fourcc = gst_video_dma_drm_fourcc_from_string (str, &modifier);
252
0
  if (fourcc == DRM_FORMAT_INVALID) {
253
0
    GST_DEBUG ("Can not parse fourcc in caps %" GST_PTR_FORMAT, caps);
254
0
    ret = FALSE;
255
0
    goto out;
256
0
  }
257
0
  if (modifier == DRM_FORMAT_MOD_INVALID) {
258
0
    GST_DEBUG ("Can not parse modifier in caps %" GST_PTR_FORMAT, caps);
259
0
    ret = FALSE;
260
0
    goto out;
261
0
  }
262
263
  /* If the modifier is linear, set the according format in video info,
264
   * otherwise, just let the format to be GST_VIDEO_FORMAT_DMA_DRM. */
265
0
  format = gst_video_dma_drm_format_to_gst_format (fourcc, modifier);
266
0
  if (format != GST_VIDEO_FORMAT_UNKNOWN) {
267
0
    gst_structure_set (structure, "format", G_TYPE_STRING,
268
0
        gst_video_format_to_string (format), NULL);
269
0
  }
270
271
0
  gst_structure_remove_field (structure, "drm-format");
272
273
0
  if (!gst_video_info_from_caps (&drm_info->vinfo, tmp_caps)) {
274
0
    GST_DEBUG ("Can not parse video info for caps %" GST_PTR_FORMAT, tmp_caps);
275
0
    ret = FALSE;
276
0
    goto out;
277
0
  }
278
279
0
  drm_info->drm_fourcc = fourcc;
280
0
  drm_info->drm_modifier = modifier;
281
0
  ret = TRUE;
282
283
0
out:
284
0
  gst_clear_caps (&tmp_caps);
285
0
  return ret;
286
0
}
287
288
/**
289
 * gst_video_info_dma_drm_new_from_caps:
290
 * @caps: a #GstCaps
291
 *
292
 * Parse @caps to generate a #GstVideoInfoDmaDrm. Please note that the
293
 * @caps should be a dma drm caps. The gst_video_is_dma_drm_caps() can
294
 * be used to verify it before calling this function.
295
 *
296
 * Returns: (transfer full) (nullable): A #GstVideoInfoDmaDrm,
297
 *   or %NULL if @caps couldn't be parsed.
298
 *
299
 * Since: 1.24
300
 */
301
GstVideoInfoDmaDrm *
302
gst_video_info_dma_drm_new_from_caps (const GstCaps * caps)
303
0
{
304
0
  GstVideoInfoDmaDrm *ret;
305
306
0
  g_return_val_if_fail (caps != NULL, NULL);
307
308
0
  if (!gst_video_is_dma_drm_caps (caps))
309
0
    return NULL;
310
311
0
  ret = gst_video_info_dma_drm_new ();
312
313
0
  if (gst_video_info_dma_drm_from_caps (ret, caps)) {
314
0
    return ret;
315
0
  } else {
316
0
    gst_video_info_dma_drm_free (ret);
317
0
    return NULL;
318
0
  }
319
0
}
320
321
/**
322
 * gst_video_info_dma_drm_from_video_info:
323
 * @drm_info: (out caller-allocates): #GstVideoInfoDmaDrm
324
 * @info: a #GstVideoInfo
325
 * @modifier: the associated modifier value.
326
 *
327
 * Fills @drm_info if @info's format has a valid drm format and @modifier is also
328
 * valid
329
 *
330
 * Returns: %TRUE if @drm_info is filled correctly.
331
 *
332
 * Since: 1.24
333
 */
334
gboolean
335
gst_video_info_dma_drm_from_video_info (GstVideoInfoDmaDrm * drm_info,
336
    const GstVideoInfo * info, guint64 modifier)
337
0
{
338
0
  GstVideoFormat format;
339
0
  guint32 fourcc;
340
341
0
  g_return_val_if_fail (drm_info != NULL, FALSE);
342
0
  g_return_val_if_fail (info != NULL, FALSE);
343
344
0
  if (modifier == DRM_FORMAT_MOD_INVALID)
345
0
    return FALSE;
346
0
  format = GST_VIDEO_INFO_FORMAT (info);
347
0
  fourcc = gst_video_dma_drm_fourcc_from_format (format);
348
0
  if (fourcc == DRM_FORMAT_INVALID)
349
0
    return FALSE;
350
351
0
  drm_info->vinfo = *info;
352
0
  drm_info->drm_fourcc = fourcc;
353
0
  drm_info->drm_modifier = modifier;
354
355
  /* no need to change format to GST_VIDEO_INFO_DMA_DRM since its modifier is
356
   * linear */
357
0
  if (modifier == DRM_FORMAT_MOD_LINEAR)
358
0
    return TRUE;
359
360
0
  return gst_video_info_set_interlaced_format (&drm_info->vinfo,
361
0
      GST_VIDEO_FORMAT_DMA_DRM, GST_VIDEO_INFO_INTERLACE_MODE (info),
362
0
      GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info));
363
0
}
364
365
/**
366
 * gst_video_info_dma_drm_to_video_info:
367
 * @drm_info: a #GstVideoInfoDmaDrm
368
 * @info: (out caller-allocates): #GstVideoInfo
369
 *
370
 * Convert the #GstVideoInfoDmaDrm into a traditional #GstVideoInfo with
371
 * recognized video format. For DMA kind memory, the non linear DMA format
372
 * should be recognized as #GST_VIDEO_FORMAT_DMA_DRM. This helper function
373
 * sets @info's video format into the default value according to @drm_info's
374
 * drm_fourcc field.
375
 *
376
 * Returns: %TRUE if @info is converted correctly.
377
 *
378
 * Since: 1.24
379
 */
380
gboolean
381
gst_video_info_dma_drm_to_video_info (const GstVideoInfoDmaDrm * drm_info,
382
    GstVideoInfo * info)
383
0
{
384
0
  GstVideoFormat video_format;
385
0
  GstVideoInfo tmp_info;
386
0
  guint i;
387
388
0
  g_return_val_if_fail (drm_info, FALSE);
389
0
  g_return_val_if_fail (info, FALSE);
390
391
0
  if (GST_VIDEO_INFO_FORMAT (&drm_info->vinfo) != GST_VIDEO_FORMAT_DMA_DRM) {
392
0
    *info = drm_info->vinfo;
393
0
    return TRUE;
394
0
  }
395
396
0
  video_format = gst_video_dma_drm_fourcc_to_format (drm_info->drm_fourcc);
397
0
  if (video_format == GST_VIDEO_FORMAT_UNKNOWN)
398
0
    return FALSE;
399
400
0
  if (!gst_video_info_set_format (&tmp_info, video_format,
401
0
          GST_VIDEO_INFO_WIDTH (&drm_info->vinfo),
402
0
          GST_VIDEO_INFO_HEIGHT (&drm_info->vinfo)))
403
0
    return FALSE;
404
405
0
  *info = drm_info->vinfo;
406
0
  info->finfo = tmp_info.finfo;
407
0
  for (i = 0; i < GST_VIDEO_MAX_PLANES; i++)
408
0
    info->stride[i] = tmp_info.stride[i];
409
0
  for (i = 0; i < GST_VIDEO_MAX_PLANES; i++)
410
0
    info->offset[i] = tmp_info.offset[i];
411
0
  info->size = tmp_info.size;
412
413
0
  return TRUE;
414
0
}
415
416
/**
417
 * gst_video_dma_drm_fourcc_from_string:
418
 * @format_str: a drm format string
419
 * @modifier: (out) (optional): Return the modifier in @format or %NULL
420
 * to ignore.
421
 *
422
 * Convert the @format_str string into the drm fourcc value. The @modifier is
423
 * also parsed if we want. Please note that the @format_str should follow the
424
 * fourcc:modifier kind style, such as NV12:0x0100000000000002
425
 *
426
 * Returns: The drm fourcc value or DRM_FORMAT_INVALID if @format_str is
427
 * invalid.
428
 *
429
 * Since: 1.24
430
 */
431
guint32
432
gst_video_dma_drm_fourcc_from_string (const gchar * format_str,
433
    guint64 * modifier)
434
0
{
435
0
  const gchar *mod_str;
436
0
  guint32 fourcc = DRM_FORMAT_INVALID;
437
0
  guint64 m = DRM_FORMAT_MOD_INVALID;
438
0
  gboolean big_endian = FALSE;
439
440
0
  g_return_val_if_fail (format_str != NULL, 0);
441
442
0
  mod_str = strchr (format_str, ':');
443
0
  if (mod_str) {
444
0
    gint fmt_len = mod_str - format_str;
445
446
    /* Handle big endian (FOURCC_BE) case */
447
0
    if (fmt_len == 7 && strstr (format_str + 4, "_BE")) {
448
0
      big_endian = TRUE;
449
0
    } else if (fmt_len != 4) {
450
      /* fourcc always has 4 characters. */
451
0
      GST_DEBUG ("%s is not a drm string", format_str);
452
0
      return DRM_FORMAT_INVALID;
453
0
    }
454
455
0
    mod_str++;
456
    /* modifier should in hex mode. */
457
0
    if (!(mod_str[0] == '0' && (mod_str[1] == 'X' || mod_str[1] == 'x'))) {
458
0
      GST_DEBUG ("Invalid modifier string");
459
0
      return DRM_FORMAT_INVALID;
460
0
    }
461
462
0
    m = g_ascii_strtoull (mod_str, NULL, 16);
463
0
    if (m == DRM_FORMAT_MOD_LINEAR) {
464
0
      GST_DEBUG ("Unrecognized modifier string %s", mod_str);
465
0
      return DRM_FORMAT_INVALID;
466
0
    }
467
0
  } else {
468
0
    gint fmt_len = strlen (format_str);
469
470
    /* Handle big endian (FOURCC_BE) case */
471
0
    if (fmt_len == 7 && strstr (format_str + 4, "_BE")) {
472
0
      big_endian = TRUE;
473
0
    } else if (fmt_len != 4) {
474
      /* fourcc always has 4 characters. */
475
0
      GST_DEBUG ("%s is not a drm string", format_str);
476
0
      return DRM_FORMAT_INVALID;
477
0
    }
478
479
0
    m = DRM_FORMAT_MOD_LINEAR;
480
0
  }
481
482
0
  fourcc = GST_MAKE_FOURCC (format_str[0], format_str[1],
483
0
      format_str[2], format_str[3]);
484
485
0
  if (big_endian)
486
0
    fourcc |= DRM_FORMAT_BIG_ENDIAN;
487
488
0
  if (modifier)
489
0
    *modifier = m;
490
491
0
  return fourcc;
492
0
}
493
494
/**
495
 * gst_video_dma_drm_fourcc_to_string:
496
 * @fourcc: a drm fourcc value.
497
 * @modifier: the associated modifier value.
498
 *
499
 * Returns a string containing drm kind format, such as
500
 * NV12:0x0100000000000002, or NULL otherwise.
501
 *
502
 * Returns: (transfer full) (nullable): the drm kind string composed
503
 *   of to @fourcc and @modifier.
504
 *
505
 * Since: 1.24
506
 */
507
gchar *
508
gst_video_dma_drm_fourcc_to_string (guint32 fourcc, guint64 modifier)
509
0
{
510
0
  gboolean big_endian = FALSE;
511
0
  gchar *s;
512
513
0
  g_return_val_if_fail (fourcc != DRM_FORMAT_INVALID, NULL);
514
0
  g_return_val_if_fail (modifier != DRM_FORMAT_MOD_INVALID, NULL);
515
516
0
  if (fourcc & DRM_FORMAT_BIG_ENDIAN) {
517
0
    big_endian = TRUE;
518
0
    fourcc &= ~DRM_FORMAT_BIG_ENDIAN;
519
0
  }
520
521
0
  if (modifier == DRM_FORMAT_MOD_LINEAR) {
522
0
    s = g_strdup_printf ("%" GST_FOURCC_FORMAT "%s", GST_FOURCC_ARGS (fourcc),
523
0
        big_endian ? "_BE" : "");
524
0
  } else {
525
0
    s = g_strdup_printf ("%" GST_FOURCC_FORMAT "%s:0x%016" G_GINT64_MODIFIER
526
0
        "x", GST_FOURCC_ARGS (fourcc), big_endian ? "_BE" : "", modifier);
527
0
  }
528
529
0
  return s;
530
0
}
531
532
/* *INDENT-OFF* */
533
static const struct FormatMap
534
{
535
  GstVideoFormat format;
536
  guint32 fourcc;
537
  guint64 modifier;
538
} format_map[] = {
539
  {GST_VIDEO_FORMAT_YUY2, DRM_FORMAT_YUYV, DRM_FORMAT_MOD_LINEAR},
540
  {GST_VIDEO_FORMAT_YVYU, DRM_FORMAT_YVYU, DRM_FORMAT_MOD_LINEAR},
541
  {GST_VIDEO_FORMAT_UYVY, DRM_FORMAT_UYVY, DRM_FORMAT_MOD_LINEAR},
542
  {GST_VIDEO_FORMAT_VYUY, DRM_FORMAT_VYUY, DRM_FORMAT_MOD_LINEAR},
543
  /* No VUYA fourcc define, just mapping it as AYUV. */
544
  {GST_VIDEO_FORMAT_VUYA, DRM_FORMAT_AYUV, DRM_FORMAT_MOD_LINEAR},
545
  {GST_VIDEO_FORMAT_NV12, DRM_FORMAT_NV12, DRM_FORMAT_MOD_LINEAR},
546
  {GST_VIDEO_FORMAT_NV12_4L4, DRM_FORMAT_NV12, DRM_FORMAT_MOD_VIVANTE_TILED},
547
  {GST_VIDEO_FORMAT_NV12_64Z32, DRM_FORMAT_NV12, DRM_FORMAT_MOD_SAMSUNG_64_32_TILE},
548
  {GST_VIDEO_FORMAT_NV12_16L32S, DRM_FORMAT_NV12, DRM_FORMAT_MOD_MTK_16L_32S_TILE},
549
  {GST_VIDEO_FORMAT_MT2110T, DRM_FORMAT_NV15, DRM_FORMAT_MOD_MTK(MTK_FMT_MOD_TILE_16L32S | MTK_FMT_MOD_10BIT_LAYOUT_LSBTILED)},
550
  {GST_VIDEO_FORMAT_MT2110R, DRM_FORMAT_NV15, DRM_FORMAT_MOD_MTK(MTK_FMT_MOD_TILE_16L32S | MTK_FMT_MOD_10BIT_LAYOUT_LSBRASTER)},
551
  {GST_VIDEO_FORMAT_NV21, DRM_FORMAT_NV21, DRM_FORMAT_MOD_LINEAR},
552
  {GST_VIDEO_FORMAT_NV16, DRM_FORMAT_NV16, DRM_FORMAT_MOD_LINEAR},
553
  {GST_VIDEO_FORMAT_NV61, DRM_FORMAT_NV61, DRM_FORMAT_MOD_LINEAR},
554
  {GST_VIDEO_FORMAT_NV24, DRM_FORMAT_NV24, DRM_FORMAT_MOD_LINEAR},
555
  {GST_VIDEO_FORMAT_YUV9, DRM_FORMAT_YUV410, DRM_FORMAT_MOD_LINEAR},
556
  {GST_VIDEO_FORMAT_YVU9, DRM_FORMAT_YVU410, DRM_FORMAT_MOD_LINEAR},
557
  {GST_VIDEO_FORMAT_Y41B, DRM_FORMAT_YUV411, DRM_FORMAT_MOD_LINEAR},
558
  {GST_VIDEO_FORMAT_I420, DRM_FORMAT_YUV420, DRM_FORMAT_MOD_LINEAR},
559
  {GST_VIDEO_FORMAT_I420_10LE, DRM_FORMAT_S010, DRM_FORMAT_MOD_LINEAR},
560
  {GST_VIDEO_FORMAT_I422_10LE, DRM_FORMAT_S210, DRM_FORMAT_MOD_LINEAR},
561
  {GST_VIDEO_FORMAT_Y444_10LE, DRM_FORMAT_S410, DRM_FORMAT_MOD_LINEAR},
562
  {GST_VIDEO_FORMAT_I420_12LE, DRM_FORMAT_S012, DRM_FORMAT_MOD_LINEAR},
563
  {GST_VIDEO_FORMAT_I422_12LE, DRM_FORMAT_S212, DRM_FORMAT_MOD_LINEAR},
564
  {GST_VIDEO_FORMAT_Y444_12LE, DRM_FORMAT_S412, DRM_FORMAT_MOD_LINEAR},
565
  {GST_VIDEO_FORMAT_Y444_16LE, DRM_FORMAT_S416, DRM_FORMAT_MOD_LINEAR},
566
  {GST_VIDEO_FORMAT_YV12, DRM_FORMAT_YVU420, DRM_FORMAT_MOD_LINEAR},
567
  {GST_VIDEO_FORMAT_Y42B, DRM_FORMAT_YUV422, DRM_FORMAT_MOD_LINEAR},
568
  {GST_VIDEO_FORMAT_Y444, DRM_FORMAT_YUV444, DRM_FORMAT_MOD_LINEAR},
569
  {GST_VIDEO_FORMAT_RGB15, DRM_FORMAT_XRGB1555, DRM_FORMAT_MOD_LINEAR},
570
  {GST_VIDEO_FORMAT_RGB16, DRM_FORMAT_RGB565, DRM_FORMAT_MOD_LINEAR},
571
  {GST_VIDEO_FORMAT_BGR16, DRM_FORMAT_BGR565, DRM_FORMAT_MOD_LINEAR},
572
  {GST_VIDEO_FORMAT_RGB, DRM_FORMAT_BGR888, DRM_FORMAT_MOD_LINEAR},
573
  {GST_VIDEO_FORMAT_BGR, DRM_FORMAT_RGB888, DRM_FORMAT_MOD_LINEAR},
574
  {GST_VIDEO_FORMAT_RGBA, DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_LINEAR},
575
  {GST_VIDEO_FORMAT_RGBx, DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_LINEAR},
576
  {GST_VIDEO_FORMAT_BGRA, DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_LINEAR},
577
  {GST_VIDEO_FORMAT_BGRx, DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR},
578
  {GST_VIDEO_FORMAT_ARGB, DRM_FORMAT_BGRA8888, DRM_FORMAT_MOD_LINEAR},
579
  {GST_VIDEO_FORMAT_xRGB, DRM_FORMAT_BGRX8888, DRM_FORMAT_MOD_LINEAR},
580
  {GST_VIDEO_FORMAT_ABGR, DRM_FORMAT_RGBA8888, DRM_FORMAT_MOD_LINEAR},
581
  {GST_VIDEO_FORMAT_xBGR, DRM_FORMAT_RGBX8888, DRM_FORMAT_MOD_LINEAR},
582
  {GST_VIDEO_FORMAT_Y410, DRM_FORMAT_Y410, DRM_FORMAT_MOD_LINEAR},
583
  {GST_VIDEO_FORMAT_Y412_LE, DRM_FORMAT_Y412, DRM_FORMAT_MOD_LINEAR},
584
  {GST_VIDEO_FORMAT_Y210, DRM_FORMAT_Y210, DRM_FORMAT_MOD_LINEAR},
585
  {GST_VIDEO_FORMAT_Y212_LE, DRM_FORMAT_Y212, DRM_FORMAT_MOD_LINEAR},
586
  {GST_VIDEO_FORMAT_NV12_10LE40, DRM_FORMAT_NV15, DRM_FORMAT_MOD_LINEAR},
587
  {GST_VIDEO_FORMAT_NV12_10LE40_4L4, DRM_FORMAT_NV15, DRM_FORMAT_MOD_VIVANTE_TILED},
588
  {GST_VIDEO_FORMAT_P010_10LE, DRM_FORMAT_P010, DRM_FORMAT_MOD_LINEAR},
589
  {GST_VIDEO_FORMAT_P012_LE, DRM_FORMAT_P012, DRM_FORMAT_MOD_LINEAR},
590
  {GST_VIDEO_FORMAT_BGR10A2_LE, DRM_FORMAT_ARGB2101010, DRM_FORMAT_MOD_LINEAR},
591
  {GST_VIDEO_FORMAT_RGB10A2_LE, DRM_FORMAT_ABGR2101010, DRM_FORMAT_MOD_LINEAR},
592
  {GST_VIDEO_FORMAT_BGR10x2_LE, DRM_FORMAT_XRGB2101010, DRM_FORMAT_MOD_LINEAR},
593
  {GST_VIDEO_FORMAT_RGB10x2_LE, DRM_FORMAT_XBGR2101010, DRM_FORMAT_MOD_LINEAR},
594
  {GST_VIDEO_FORMAT_GRAY8, DRM_FORMAT_R8, DRM_FORMAT_MOD_LINEAR},
595
  {GST_VIDEO_FORMAT_GRAY16_LE, DRM_FORMAT_R16, DRM_FORMAT_MOD_LINEAR},
596
  {GST_VIDEO_FORMAT_GRAY16_BE, DRM_FORMAT_R16 | DRM_FORMAT_BIG_ENDIAN, DRM_FORMAT_MOD_LINEAR},
597
  {GST_VIDEO_FORMAT_NV16_10LE40, DRM_FORMAT_NV20, DRM_FORMAT_MOD_LINEAR},
598
  {GST_VIDEO_FORMAT_P016_LE, DRM_FORMAT_P016, DRM_FORMAT_MOD_LINEAR},
599
};
600
/* *INDENT-ON* */
601
602
/**
603
 * gst_video_dma_drm_fourcc_from_format:
604
 * @format: a #GstVideoFormat
605
 *
606
 * Converting the video format into dma drm fourcc. If no
607
 * matching fourcc found, then DRM_FORMAT_INVALID is returned.
608
 *
609
 * Returns: the DRM_FORMAT_* corresponding to the @format.
610
 *
611
 * Since: 1.24
612
 */
613
guint32
614
gst_video_dma_drm_fourcc_from_format (GstVideoFormat format)
615
0
{
616
0
  guint64 modifier;
617
0
  guint32 fourcc;
618
619
0
  fourcc = gst_video_dma_drm_format_from_gst_format (format, &modifier);
620
621
0
  if (fourcc == DRM_FORMAT_INVALID)
622
0
    return DRM_FORMAT_INVALID;
623
624
0
  if (modifier != DRM_FORMAT_MOD_LINEAR)
625
0
    return DRM_FORMAT_INVALID;
626
627
0
  return fourcc;
628
0
}
629
630
/**
631
 * gst_video_dma_drm_format_from_gst_format:
632
 * @format: a #GstVideoFormat
633
 * @modifier: (nullable): return location for the modifier
634
 *
635
 * Converting the video format into dma drm fourcc/modifier pair.
636
 * If no matching fourcc found, then DRM_FORMAT_INVALID is returned
637
 * and @modifier will be set to DRM_FORMAT_MOD_INVALID.
638
 *
639
 * Returns: the DRM_FORMAT_* corresponding to @format.
640
 *
641
 * Since: 1.26
642
 */
643
guint32
644
gst_video_dma_drm_format_from_gst_format (GstVideoFormat format,
645
    guint64 * modifier)
646
0
{
647
0
  guint i;
648
649
0
  for (i = 0; i < G_N_ELEMENTS (format_map); i++) {
650
0
    if (format_map[i].format == format) {
651
0
      if (modifier)
652
0
        *modifier = format_map[i].modifier;
653
0
      return format_map[i].fourcc;
654
0
    }
655
0
  }
656
657
0
  GST_INFO ("No supported fourcc/modifier for video format %s",
658
0
      gst_video_format_to_string (format));
659
660
0
  *modifier = DRM_FORMAT_MOD_INVALID;
661
0
  return DRM_FORMAT_INVALID;
662
0
}
663
664
/**
665
 * gst_video_dma_drm_fourcc_to_format:
666
 * @fourcc: the dma drm value.
667
 *
668
 * Converting a dma drm fourcc into the video format. If no matching
669
 * video format found, then GST_VIDEO_FORMAT_UNKNOWN is returned.
670
 *
671
 * Returns: the GST_VIDEO_FORMAT_* corresponding to the @fourcc.
672
 *
673
 * Since: 1.24
674
 */
675
GstVideoFormat
676
gst_video_dma_drm_fourcc_to_format (guint32 fourcc)
677
0
{
678
0
  guint i;
679
680
0
  for (i = 0; i < G_N_ELEMENTS (format_map); i++) {
681
0
    if (format_map[i].fourcc == fourcc)
682
0
      return format_map[i].format;
683
0
  }
684
685
0
  GST_INFO ("No supported video format for fourcc %" GST_FOURCC_FORMAT,
686
0
      GST_FOURCC_ARGS (fourcc));
687
0
  return GST_VIDEO_FORMAT_UNKNOWN;
688
0
}
689
690
/**
691
 * gst_video_dma_drm_format_to_gst_format:
692
 * @fourcc: the dma drm fourcc value.
693
 * @modifier: the dma drm modifier.
694
 *
695
 * Converting a dma drm fourcc and modifier pair into a #GstVideoFormat. If
696
 * no matching video format is found, then GST_VIDEO_FORMAT_UNKNOWN is returned.
697
 *
698
 * Returns: the GST_VIDEO_FORMAT_* corresponding to the @fourcc and @modifier
699
 *          pair.
700
 *
701
 * Since: 1.26
702
 */
703
GstVideoFormat
704
gst_video_dma_drm_format_to_gst_format (guint32 fourcc, guint64 modifier)
705
0
{
706
0
  guint i;
707
708
0
  for (i = 0; i < G_N_ELEMENTS (format_map); i++) {
709
0
    if (format_map[i].fourcc == fourcc && format_map[i].modifier == modifier)
710
0
      return format_map[i].format;
711
0
  }
712
713
0
  gchar *drm_format_str = gst_video_dma_drm_fourcc_to_string (fourcc, modifier);
714
0
  GST_INFO ("No support for DRM format %s", drm_format_str);
715
0
  g_free (drm_format_str);
716
717
0
  return GST_VIDEO_FORMAT_UNKNOWN;
718
0
}