rtsp-server:wfd: Fix build error for gcc upgrade
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / gst / mxf / mxfup.c
1 /* GStreamer
2  * Copyright (C) 2008-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /* Implementation of SMPTE 384M - Mapping of Uncompressed Pictures into the MXF
21  * Generic Container
22  */
23
24 /* TODO:
25  *   - Handle CDCI essence
26  *   - Handle more formats with RGBA descriptor (4:4:4 / 4:4:4:4 YUV, RGB656, ...)
27  *   - Handle all the dimensions and other properties in the picture
28  *     essence descriptors correctly according to S377M Annex E
29  *   - Handle interlaced correctly, i.e. weave until we support one-field-per-buffer
30  */
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <gst/gst.h>
37 #include <string.h>
38
39 #include <gst/video/video.h>
40
41 #include "mxfup.h"
42 #include "mxfessence.h"
43
44 GST_DEBUG_CATEGORY_EXTERN (mxf_debug);
45 #define GST_CAT_DEFAULT mxf_debug
46
47 static const struct
48 {
49   const gchar *format;
50   guint32 n_pixel_layout;
51   guint8 pixel_layout[10];
52   const gchar *caps_string;
53 } _rgba_mapping_table[] = {
54   {
55     "RGB", 3, {
56   'R', 8, 'G', 8, 'B', 8}, GST_VIDEO_CAPS_MAKE ("RGB")}, {
57     "BGR", 3, {
58   'B', 8, 'G', 8, 'R', 8}, GST_VIDEO_CAPS_MAKE ("BGR")}, {
59     "v308", 3, {
60   'Y', 8, 'U', 8, 'V', 8}, GST_VIDEO_CAPS_MAKE ("v308")}, {
61     "xRGB", 4, {
62   'F', 8, 'R', 8, 'G', 8, 'B', 8}, GST_VIDEO_CAPS_MAKE ("xRGB")}, {
63     "RGBx", 4, {
64   'R', 8, 'G', 8, 'B', 8, 'F', 8}, GST_VIDEO_CAPS_MAKE ("RGBx")}, {
65     "xBGR", 4, {
66   'F', 8, 'B', 8, 'G', 8, 'R', 8}, GST_VIDEO_CAPS_MAKE ("xBGR")}, {
67     "BGRx", 4, {
68   'B', 8, 'G', 8, 'R', 8, 'F', 8}, GST_VIDEO_CAPS_MAKE ("BGRx")}, {
69     "RGBA", 4, {
70   'R', 8, 'G', 8, 'B', 8, 'A', 8}, GST_VIDEO_CAPS_MAKE ("RGBA")}, {
71     "ARGB", 4, {
72   'A', 8, 'R', 8, 'G', 8, 'B', 8}, GST_VIDEO_CAPS_MAKE ("RGBA")}, {
73     "BGRA", 4, {
74   'B', 8, 'G', 8, 'R', 8, 'A', 8}, GST_VIDEO_CAPS_MAKE ("BGRA")}, {
75     "ABGR", 4, {
76   'A', 8, 'B', 8, 'G', 8, 'R', 8}, GST_VIDEO_CAPS_MAKE ("ABGR")}, {
77     "AYUV", 4, {
78   'A', 8, 'Y', 8, 'U', 8, 'V', 8}, GST_VIDEO_CAPS_MAKE ("AYUV")}
79 };
80
81 static const struct
82 {
83   const gchar *format;
84   guint bpp;
85   guint horizontal_subsampling;
86   guint vertical_subsampling;
87   gboolean reversed_byte_order;
88   const gchar *caps_string;
89 } _cdci_mapping_table[] = {
90   {
91   "YUY2", 2, 1, 0, TRUE, GST_VIDEO_CAPS_MAKE ("YUY2")}, {
92 "UYVY", 2, 1, 0, FALSE, GST_VIDEO_CAPS_MAKE ("UYVY")},};
93
94 typedef struct
95 {
96   const gchar *format;          /* video format string */
97   gint width, height;
98   guint bpp;
99   guint32 image_start_offset;
100   guint32 image_end_offset;
101 } MXFUPMappingData;
102
103 static gboolean
104 mxf_is_up_essence_track (const MXFMetadataTimelineTrack * track)
105 {
106   guint i;
107
108   g_return_val_if_fail (track != NULL, FALSE);
109
110   if (track->parent.descriptor == NULL)
111     return FALSE;
112
113   for (i = 0; i < track->parent.n_descriptor; i++) {
114     MXFMetadataFileDescriptor *d = track->parent.descriptor[i];
115     MXFUL *key;
116
117     if (!d)
118       continue;
119
120     key = &d->essence_container;
121     /* SMPTE 384M 8 */
122     if (mxf_is_generic_container_essence_container_label (key) &&
123         key->u[12] == 0x02 && key->u[13] == 0x05 && key->u[15] <= 0x03)
124       return TRUE;
125   }
126
127   return FALSE;
128 }
129
130 static GstFlowReturn
131 mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
132     GstCaps * caps,
133     MXFMetadataTimelineTrack * track,
134     gpointer mapping_data, GstBuffer ** outbuf)
135 {
136   MXFUPMappingData *data = mapping_data;
137   gsize expected_in_stride = 0, out_stride = 0;
138   gsize expected_in_size = 0, out_size = 0;
139
140   /* SMPTE 384M 7.1 */
141   if (key->u[12] != 0x15 || (key->u[14] != 0x01 && key->u[14] != 0x02
142           && key->u[14] != 0x03 && key->u[14] != 0x04)) {
143     GST_ERROR ("Invalid uncompressed picture essence element");
144     gst_buffer_unref (buffer);
145     return GST_FLOW_ERROR;
146   }
147
148   if (!data) {
149     GST_ERROR ("Invalid mapping data");
150     gst_buffer_unref (buffer);
151     return GST_FLOW_ERROR;
152   }
153
154   if (data->image_start_offset == 0 && data->image_end_offset == 0) {
155   } else {
156     if (data->image_start_offset + data->image_end_offset
157         > gst_buffer_get_size (buffer)) {
158       gst_buffer_unref (buffer);
159       GST_ERROR ("Invalid buffer size");
160       return GST_FLOW_ERROR;
161     } else {
162       gst_buffer_resize (buffer, data->image_start_offset,
163           data->image_end_offset - data->image_start_offset);
164     }
165   }
166
167   // Checked for overflows when parsing the descriptor
168   expected_in_stride = data->bpp * data->width;
169   out_stride = GST_ROUND_UP_4 (expected_in_stride);
170   expected_in_size = expected_in_stride * data->height;
171   out_size = out_stride * data->height;
172
173   if (gst_buffer_get_size (buffer) != expected_in_size) {
174     GST_ERROR ("Invalid buffer size");
175     gst_buffer_unref (buffer);
176     return GST_FLOW_ERROR;
177   }
178
179   if (data->bpp != 4 || out_stride != expected_in_stride) {
180     guint y;
181     GstBuffer *ret;
182     GstMapInfo inmap, outmap;
183     guint8 *indata, *outdata;
184
185     ret = gst_buffer_new_and_alloc (out_size);
186     gst_buffer_map (buffer, &inmap, GST_MAP_READ);
187     gst_buffer_map (ret, &outmap, GST_MAP_WRITE);
188     indata = inmap.data;
189     outdata = outmap.data;
190
191     for (y = 0; y < data->height; y++) {
192       memcpy (outdata, indata, data->width * data->bpp);
193       outdata += out_stride;
194       indata += expected_in_stride;
195     }
196
197     gst_buffer_unmap (buffer, &inmap);
198     gst_buffer_unmap (ret, &outmap);
199
200     gst_buffer_unref (buffer);
201     *outbuf = ret;
202   } else {
203     *outbuf = buffer;
204   }
205
206   return GST_FLOW_OK;
207 }
208
209 static MXFEssenceWrapping
210 mxf_up_get_track_wrapping (const MXFMetadataTimelineTrack * track)
211 {
212   guint i;
213
214   g_return_val_if_fail (track != NULL, MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING);
215
216   if (track->parent.descriptor == NULL) {
217     GST_ERROR ("No descriptor found for this track");
218     return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
219   }
220
221   for (i = 0; i < track->parent.n_descriptor; i++) {
222     if (!track->parent.descriptor[i])
223       continue;
224
225     if (!MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->
226             parent.descriptor[i]))
227       continue;
228
229     switch (track->parent.descriptor[i]->essence_container.u[15]) {
230       case 0x01:
231         return MXF_ESSENCE_WRAPPING_FRAME_WRAPPING;
232         break;
233       case 0x02:
234         return MXF_ESSENCE_WRAPPING_CLIP_WRAPPING;
235         break;
236       default:
237         return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
238         break;
239     }
240   }
241
242   return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
243 }
244
245 static GstCaps *
246 mxf_up_rgba_create_caps (MXFMetadataTimelineTrack * track,
247     MXFMetadataRGBAPictureEssenceDescriptor * d, GstTagList ** tags,
248     gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
249     gpointer * mapping_data)
250 {
251   GstCaps *caps = NULL;
252   guint i;
253   const gchar *format = NULL;
254   guint bpp;
255
256   if (!d->pixel_layout) {
257     GST_ERROR ("No pixel layout");
258     return NULL;
259   }
260
261   for (i = 0; i < G_N_ELEMENTS (_rgba_mapping_table); i++) {
262     if (d->n_pixel_layout != _rgba_mapping_table[i].n_pixel_layout)
263       continue;
264
265     if (memcmp (d->pixel_layout, &_rgba_mapping_table[i].pixel_layout,
266             _rgba_mapping_table[i].n_pixel_layout * 2) == 0) {
267       caps = gst_caps_from_string (_rgba_mapping_table[i].caps_string);
268       format = _rgba_mapping_table[i].format;
269       bpp = _rgba_mapping_table[i].n_pixel_layout;
270       break;
271     }
272   }
273
274   if (caps) {
275     MXFUPMappingData *data = g_new0 (MXFUPMappingData, 1);
276
277     mxf_metadata_generic_picture_essence_descriptor_set_caps (&d->parent, caps);
278
279     data->width = d->parent.stored_width;
280     data->height = d->parent.stored_height;
281     data->format = format;
282     data->bpp = bpp;
283     data->image_start_offset =
284         ((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_start_offset;
285     data->image_end_offset =
286         ((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_end_offset;
287
288     *mapping_data = data;
289     *intra_only = TRUE;
290   } else {
291     GST_WARNING ("Unsupported pixel layout");
292   }
293
294   return caps;
295 }
296
297 static GstCaps *
298 mxf_up_cdci_create_caps (MXFMetadataTimelineTrack * track,
299     MXFMetadataCDCIPictureEssenceDescriptor * d, GstTagList ** tags,
300     gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
301     gpointer * mapping_data)
302 {
303   GstCaps *caps = NULL;
304   guint i;
305   const gchar *format;
306   guint bpp;
307
308   for (i = 0; i < G_N_ELEMENTS (_cdci_mapping_table); i++) {
309     if (_cdci_mapping_table[i].horizontal_subsampling ==
310         d->horizontal_subsampling
311         && _cdci_mapping_table[i].vertical_subsampling ==
312         d->vertical_subsampling
313         && _cdci_mapping_table[i].reversed_byte_order ==
314         d->reversed_byte_order) {
315       caps = gst_caps_from_string (_cdci_mapping_table[i].caps_string);
316       format = _cdci_mapping_table[i].format;
317       bpp = _cdci_mapping_table[i].bpp;
318       break;
319     }
320   }
321
322   if (caps) {
323     MXFUPMappingData *data = g_new0 (MXFUPMappingData, 1);
324
325     mxf_metadata_generic_picture_essence_descriptor_set_caps (&d->parent, caps);
326
327     data->width = d->parent.stored_width;
328     data->height = d->parent.stored_height;
329     data->format = format;
330     data->bpp = bpp;
331     data->image_start_offset =
332         ((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_start_offset;
333     data->image_end_offset =
334         ((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_end_offset;
335
336     *mapping_data = data;
337     *intra_only = TRUE;
338   } else {
339     GST_WARNING ("Unsupported CDCI format");
340   }
341
342   return caps;
343 }
344
345 static GstCaps *
346 mxf_up_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
347     gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
348     gpointer * mapping_data)
349 {
350   MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
351   MXFMetadataCDCIPictureEssenceDescriptor *c = NULL;
352   MXFMetadataRGBAPictureEssenceDescriptor *r = NULL;
353   guint i;
354   GstCaps *caps = NULL;
355
356   g_return_val_if_fail (track != NULL, NULL);
357
358   if (track->parent.descriptor == NULL) {
359     GST_ERROR ("No descriptor found for this track");
360     return NULL;
361   }
362
363   for (i = 0; i < track->parent.n_descriptor; i++) {
364     if (!track->parent.descriptor[i])
365       continue;
366
367     if (MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (track->parent.
368             descriptor[i])) {
369       p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent.
370           descriptor[i];
371       r = (MXFMetadataRGBAPictureEssenceDescriptor *) track->parent.
372           descriptor[i];
373       break;
374     } else if (MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (track->
375             parent.descriptor[i])) {
376       p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent.
377           descriptor[i];
378       c = (MXFMetadataCDCIPictureEssenceDescriptor *) track->parent.
379           descriptor[i];
380     }
381   }
382
383   if (!p) {
384     GST_ERROR ("No picture essence descriptor found for this track");
385     return NULL;
386   }
387
388   *handler = mxf_up_handle_essence_element;
389
390   if (r) {
391     caps =
392         mxf_up_rgba_create_caps (track, r, tags, intra_only, handler,
393         mapping_data);
394   } else if (c) {
395     caps =
396         mxf_up_cdci_create_caps (track, c, tags, intra_only, handler,
397         mapping_data);
398   } else {
399     return NULL;
400   }
401
402   if (caps) {
403     MXFUPMappingData *data = *mapping_data;
404     gsize expected_in_stride = 0, out_stride = 0;
405     gsize expected_in_size = 0, out_size = 0;
406
407     // Do some checking of the parameters to see if they're valid and
408     // we can actually work with them.
409     if (data->image_start_offset > data->image_end_offset) {
410       GST_WARNING ("Invalid image start/end offset");
411       g_free (data);
412       *mapping_data = NULL;
413       gst_clear_caps (&caps);
414
415       return NULL;
416     }
417
418     if (!g_size_checked_mul (&expected_in_stride, data->bpp, data->width) ||
419         (out_stride = GST_ROUND_UP_4 (expected_in_stride)) < expected_in_stride
420         || !g_size_checked_mul (&expected_in_size, expected_in_stride,
421             data->height)
422         || !g_size_checked_mul (&out_size, out_stride, data->height)) {
423       GST_ERROR ("Invalid resolution or bit depth");
424       g_free (data);
425       *mapping_data = NULL;
426       gst_clear_caps (&caps);
427
428       return NULL;
429     }
430   }
431
432   return caps;
433 }
434
435 static const MXFEssenceElementHandler mxf_up_essence_element_handler = {
436   mxf_is_up_essence_track,
437   mxf_up_get_track_wrapping,
438   mxf_up_create_caps
439 };
440
441 static GstFlowReturn
442 mxf_up_write_func (GstBuffer * buffer, gpointer mapping_data,
443     GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush)
444 {
445   MXFUPMappingData *data = mapping_data;
446
447   if (!buffer)
448     return GST_FLOW_OK;
449
450   if (gst_buffer_get_size (buffer) !=
451       GST_ROUND_UP_4 (data->bpp * data->width) * data->height) {
452     GST_ERROR ("Invalid buffer size");
453     return GST_FLOW_ERROR;
454   }
455
456   if (data->bpp != 4
457       || GST_ROUND_UP_4 (data->width * data->bpp) != data->width * data->bpp) {
458     guint y;
459     GstBuffer *ret;
460     GstMapInfo inmap, outmap;
461     guint8 *indata, *outdata;
462
463     ret = gst_buffer_new_and_alloc (data->width * data->bpp * data->height);
464     gst_buffer_map (buffer, &inmap, GST_MAP_READ);
465     gst_buffer_map (ret, &outmap, GST_MAP_WRITE);
466     indata = inmap.data;
467     outdata = outmap.data;
468
469     for (y = 0; y < data->height; y++) {
470       memcpy (outdata, indata, data->width * data->bpp);
471       indata += GST_ROUND_UP_4 (data->width * data->bpp);
472       outdata += data->width * data->bpp;
473     }
474
475     gst_buffer_unmap (buffer, &inmap);
476     gst_buffer_unmap (ret, &outmap);
477     gst_buffer_unref (buffer);
478
479     *outbuf = ret;
480   } else {
481     *outbuf = buffer;
482   }
483
484   return GST_FLOW_OK;
485 }
486
487 static const guint8 up_essence_container_ul[] = {
488   0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01,
489   0x0D, 0x01, 0x03, 0x01, 0x02, 0x05, 0x7F, 0x01
490 };
491
492 static MXFMetadataFileDescriptor *
493 mxf_up_get_rgba_descriptor (GstPadTemplate * tmpl, GstCaps * caps,
494     MXFEssenceElementWriteFunc * handler, gpointer * mapping_data)
495 {
496   MXFMetadataRGBAPictureEssenceDescriptor *ret;
497   guint i;
498   GstCaps *tmp, *intersection;
499   MXFUPMappingData *md = g_new0 (MXFUPMappingData, 1);
500
501   *mapping_data = md;
502
503   ret = (MXFMetadataRGBAPictureEssenceDescriptor *)
504       g_object_new (MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR, NULL);
505
506   for (i = 0; i < G_N_ELEMENTS (_rgba_mapping_table); i++) {
507     tmp = gst_caps_from_string (_rgba_mapping_table[i].caps_string);
508     intersection = gst_caps_intersect (caps, tmp);
509     gst_caps_unref (tmp);
510
511     if (!gst_caps_is_empty (intersection)) {
512       gst_caps_unref (intersection);
513       ret->n_pixel_layout = _rgba_mapping_table[i].n_pixel_layout;
514       ret->pixel_layout = g_new0 (guint8, ret->n_pixel_layout * 2);
515       md->format = _rgba_mapping_table[i].format;
516       md->bpp = _rgba_mapping_table[i].n_pixel_layout;
517       memcpy (ret->pixel_layout, _rgba_mapping_table[i].pixel_layout,
518           ret->n_pixel_layout * 2);
519       break;
520     }
521     gst_caps_unref (intersection);
522   }
523
524   if (md->format == NULL) {
525     GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps);
526     g_object_unref (ret);
527     return NULL;
528   }
529
530
531   memcpy (&ret->parent.parent.essence_container, &up_essence_container_ul, 16);
532
533   if (!mxf_metadata_generic_picture_essence_descriptor_from_caps (&ret->parent,
534           caps)) {
535     g_object_unref (ret);
536     return NULL;
537   }
538
539   md->width = ret->parent.stored_width;
540   md->height = ret->parent.stored_height;
541
542   *handler = mxf_up_write_func;
543
544   return (MXFMetadataFileDescriptor *) ret;
545 }
546
547 static MXFMetadataFileDescriptor *
548 mxf_up_get_cdci_descriptor (GstPadTemplate * tmpl, GstCaps * caps,
549     MXFEssenceElementWriteFunc * handler, gpointer * mapping_data)
550 {
551   MXFMetadataCDCIPictureEssenceDescriptor *ret;
552   guint i;
553   GstCaps *tmp, *intersection;
554   MXFUPMappingData *md = g_new0 (MXFUPMappingData, 1);
555
556   *mapping_data = md;
557
558   ret = (MXFMetadataCDCIPictureEssenceDescriptor *)
559       g_object_new (MXF_TYPE_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR, NULL);
560
561   for (i = 0; i < G_N_ELEMENTS (_cdci_mapping_table); i++) {
562     tmp = gst_caps_from_string (_cdci_mapping_table[i].caps_string);
563     intersection = gst_caps_intersect (caps, tmp);
564     gst_caps_unref (tmp);
565
566     if (!gst_caps_is_empty (intersection)) {
567       gst_caps_unref (intersection);
568       ret->horizontal_subsampling =
569           _cdci_mapping_table[i].horizontal_subsampling;
570       ret->vertical_subsampling = _cdci_mapping_table[i].vertical_subsampling;
571       ret->reversed_byte_order = _cdci_mapping_table[i].reversed_byte_order;
572       md->format = _cdci_mapping_table[i].format;
573       md->bpp = _cdci_mapping_table[i].bpp;
574       break;
575     }
576     gst_caps_unref (intersection);
577   }
578
579   if (md->format == NULL) {
580     GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps);
581     g_object_unref (ret);
582     return NULL;
583   }
584
585   memcpy (&ret->parent.parent.essence_container, &up_essence_container_ul, 16);
586
587   if (!mxf_metadata_generic_picture_essence_descriptor_from_caps (&ret->parent,
588           caps)) {
589     g_object_unref (ret);
590     return NULL;
591   }
592
593   md->width = ret->parent.stored_width;
594   md->height = ret->parent.stored_height;
595
596   *handler = mxf_up_write_func;
597
598   return (MXFMetadataFileDescriptor *) ret;
599 }
600
601 static MXFMetadataFileDescriptor *
602 mxf_up_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps,
603     MXFEssenceElementWriteFunc * handler, gpointer * mapping_data)
604 {
605   GstStructure *s;
606
607   s = gst_caps_get_structure (caps, 0);
608   if (strcmp (gst_structure_get_name (s), "video/x-raw") == 0) {
609     const gchar *format;
610
611     format = gst_structure_get_string (s, "format");
612     if (format == NULL)
613       return NULL;
614
615     if (g_str_equal (format, "YUY2") || g_str_equal (format, "UYVY"))
616       return mxf_up_get_cdci_descriptor (tmpl, caps, handler, mapping_data);
617     else
618       return mxf_up_get_rgba_descriptor (tmpl, caps, handler, mapping_data);
619   }
620
621   g_assert_not_reached ();
622   return NULL;
623 }
624
625 static void
626 mxf_up_update_descriptor (MXFMetadataFileDescriptor * d, GstCaps * caps,
627     gpointer mapping_data, GstBuffer * buf)
628 {
629   return;
630 }
631
632 static void
633 mxf_up_get_edit_rate (MXFMetadataFileDescriptor * a, GstCaps * caps,
634     gpointer mapping_data, GstBuffer * buf, MXFMetadataSourcePackage * package,
635     MXFMetadataTimelineTrack * track, MXFFraction * edit_rate)
636 {
637   edit_rate->n = a->sample_rate.n;
638   edit_rate->d = a->sample_rate.d;
639 }
640
641 static guint32
642 mxf_up_get_track_number_template (MXFMetadataFileDescriptor * a,
643     GstCaps * caps, gpointer mapping_data)
644 {
645   return (0x15 << 24) | (0x02 << 8);
646 }
647
648 static MXFEssenceElementWriter mxf_up_essence_element_writer = {
649   mxf_up_get_descriptor,
650   mxf_up_update_descriptor,
651   mxf_up_get_edit_rate,
652   mxf_up_get_track_number_template,
653   NULL,
654   {{0,}}
655 };
656
657 void
658 mxf_up_init (void)
659 {
660   GstCaps *tmp = NULL;
661   mxf_essence_element_handler_register (&mxf_up_essence_element_handler);
662   mxf_up_essence_element_writer.pad_template =
663       gst_pad_template_new ("up_video_sink_%u", GST_PAD_SINK, GST_PAD_REQUEST,
664       tmp = gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("RGB") "; "
665           GST_VIDEO_CAPS_MAKE ("BGR") "; "
666           GST_VIDEO_CAPS_MAKE ("RGBx") "; "
667           GST_VIDEO_CAPS_MAKE ("xRGB") "; "
668           GST_VIDEO_CAPS_MAKE ("BGRx") "; "
669           GST_VIDEO_CAPS_MAKE ("xBGR") "; "
670           GST_VIDEO_CAPS_MAKE ("ARGB") "; "
671           GST_VIDEO_CAPS_MAKE ("RGBA") "; "
672           GST_VIDEO_CAPS_MAKE ("ABGR") "; "
673           GST_VIDEO_CAPS_MAKE ("BGRA") "; "
674           GST_VIDEO_CAPS_MAKE ("AYUV") "; "
675           GST_VIDEO_CAPS_MAKE ("v308") "; "
676           GST_VIDEO_CAPS_MAKE ("UYVY") "; " GST_VIDEO_CAPS_MAKE ("YUY2")));
677   gst_caps_unref (tmp);
678
679   memcpy (&mxf_up_essence_element_writer.data_definition,
680       mxf_metadata_track_identifier_get (MXF_METADATA_TRACK_PICTURE_ESSENCE),
681       16);
682   mxf_essence_element_writer_register (&mxf_up_essence_element_writer);
683 }