diff options
Diffstat (limited to 'gst')
-rw-r--r-- | gst/mxf/Makefile.am | 25 | ||||
-rw-r--r-- | gst/mxf/mxf.c | 16 | ||||
-rw-r--r-- | gst/mxf/mxfaes-bwf.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfaes-bwf.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfalaw.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfalaw.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfd10.c | 1 | ||||
-rw-r--r-- | gst/mxf/mxfd10.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfdemux.c | 3 | ||||
-rw-r--r-- | gst/mxf/mxfdemux.h | 4 | ||||
-rw-r--r-- | gst/mxf/mxfdms1.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfdv-dif.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfdv-dif.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfessence.c | 108 | ||||
-rw-r--r-- | gst/mxf/mxfessence.h (renamed from gst/mxf/mxfwrite.h) | 57 | ||||
-rw-r--r-- | gst/mxf/mxfjpeg2000.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfjpeg2000.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfmetadata.c | 3 | ||||
-rw-r--r-- | gst/mxf/mxfmpeg.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfmpeg.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfmux.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfparse.h | 105 | ||||
-rw-r--r-- | gst/mxf/mxftypes.c (renamed from gst/mxf/mxfparse.c) | 488 | ||||
-rw-r--r-- | gst/mxf/mxftypes.h | 103 | ||||
-rw-r--r-- | gst/mxf/mxful.c | 3 | ||||
-rw-r--r-- | gst/mxf/mxful.h | 6 | ||||
-rw-r--r-- | gst/mxf/mxfup.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfup.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfvc3.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfvc3.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfwrite.c | 551 |
31 files changed, 721 insertions, 786 deletions
diff --git a/gst/mxf/Makefile.am b/gst/mxf/Makefile.am index 96534c4b..55678679 100644 --- a/gst/mxf/Makefile.am +++ b/gst/mxf/Makefile.am @@ -2,9 +2,13 @@ plugin_LTLIBRARIES = libgstmxf.la libgstmxf_la_SOURCES = \ mxf.c \ + mxful.c \ + mxftypes.c \ + mxfmetadata.c \ + mxfessence.c \ mxfquark.c \ + mxfmux.c \ mxfdemux.c \ - mxfparse.c \ mxfaes-bwf.c \ mxfmpeg.c \ mxfdv-dif.c \ @@ -13,11 +17,7 @@ libgstmxf_la_SOURCES = \ mxfd10.c \ mxfup.c \ mxfvc3.c \ - mxfmetadata.c \ - mxfdms1.c \ - mxfwrite.c \ - mxfmux.c \ - mxful.c + mxfdms1.c libgstmxf_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) libgstmxf_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) \ @@ -26,9 +26,13 @@ libgstmxf_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstmxf_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ + mxful.h \ + mxftypes.h \ + mxfmetadata.h \ mxfquark.h \ + mxfessence.h \ mxfdemux.h \ - mxfparse.h \ + mxfmux.h \ mxfaes-bwf.h \ mxfmpeg.h \ mxfdv-dif.h \ @@ -37,10 +41,5 @@ noinst_HEADERS = \ mxfd10.h \ mxfup.h \ mxfvc3.h \ - mxftypes.h \ - mxfmetadata.h \ - mxfdms1.h \ - mxfwrite.h \ - mxfmux.h \ - mxful.h + mxfdms1.h diff --git a/gst/mxf/mxf.c b/gst/mxf/mxf.c index a906f1d8..c1a0a716 100644 --- a/gst/mxf/mxf.c +++ b/gst/mxf/mxf.c @@ -25,15 +25,15 @@ #include "mxfquark.h" #include "mxfdemux.h" #include "mxfmux.h" +#include "mxfdms1.h" #include "mxfaes-bwf.h" -#include "mxfmpeg.h" -#include "mxfdv-dif.h" #include "mxfalaw.h" -#include "mxfjpeg2000.h" #include "mxfd10.h" +#include "mxfdv-dif.h" +#include "mxfjpeg2000.h" +#include "mxfmpeg.h" #include "mxfup.h" #include "mxfvc3.h" -#include "mxfdms1.h" GST_DEBUG_CATEGORY (mxf_debug); #define GST_CAT_DEFAULT mxf_debug @@ -59,15 +59,15 @@ plugin_init (GstPlugin * plugin) mxf_init (); mxf_quark_initialize (); mxf_metadata_init_types (); + mxf_dms1_initialize (); mxf_aes_bwf_init (); - mxf_mpeg_init (); - mxf_dv_dif_init (); mxf_alaw_init (); - mxf_jpeg2000_init (); mxf_d10_init (); + mxf_dv_dif_init (); + mxf_jpeg2000_init (); + mxf_mpeg_init (); mxf_up_init (); mxf_vc3_init (); - mxf_dms1_initialize (); if (!gst_element_register (plugin, "mxfdemux", GST_RANK_PRIMARY, GST_TYPE_MXF_DEMUX) || diff --git a/gst/mxf/mxfaes-bwf.c b/gst/mxf/mxfaes-bwf.c index df9c0047..78c2f8a0 100644 --- a/gst/mxf/mxfaes-bwf.c +++ b/gst/mxf/mxfaes-bwf.c @@ -35,8 +35,8 @@ #include <gst/gst.h> #include <string.h> -#include "mxfwrite.h" #include "mxfaes-bwf.h" +#include "mxfessence.h" #include "mxfquark.h" GST_DEBUG_CATEGORY_EXTERN (mxf_debug); diff --git a/gst/mxf/mxfaes-bwf.h b/gst/mxf/mxfaes-bwf.h index ecefcbd5..f2f821a4 100644 --- a/gst/mxf/mxfaes-bwf.h +++ b/gst/mxf/mxfaes-bwf.h @@ -26,8 +26,6 @@ #include <gst/gst.h> -#include "mxfparse.h" - void mxf_aes_bwf_init (void); #endif /* __MXF_AES_BWF_H__ */ diff --git a/gst/mxf/mxfalaw.c b/gst/mxf/mxfalaw.c index 40517af0..a7116284 100644 --- a/gst/mxf/mxfalaw.c +++ b/gst/mxf/mxfalaw.c @@ -29,7 +29,7 @@ #include <string.h> #include "mxfalaw.h" -#include "mxfwrite.h" +#include "mxfessence.h" GST_DEBUG_CATEGORY_EXTERN (mxf_debug); #define GST_CAT_DEFAULT mxf_debug diff --git a/gst/mxf/mxfalaw.h b/gst/mxf/mxfalaw.h index 4b9845f6..12cbe135 100644 --- a/gst/mxf/mxfalaw.h +++ b/gst/mxf/mxfalaw.h @@ -26,8 +26,6 @@ #include <gst/gst.h> -#include "mxfparse.h" - void mxf_alaw_init (void); #endif /* __MXF_ALAW_H__ */ diff --git a/gst/mxf/mxfd10.c b/gst/mxf/mxfd10.c index 1195d3b4..71e818a4 100644 --- a/gst/mxf/mxfd10.c +++ b/gst/mxf/mxfd10.c @@ -31,6 +31,7 @@ #include "mxfd10.h" #include "mxfmpeg.h" +#include "mxfessence.h" GST_DEBUG_CATEGORY_EXTERN (mxf_debug); #define GST_CAT_DEFAULT mxf_debug diff --git a/gst/mxf/mxfd10.h b/gst/mxf/mxfd10.h index 61ad5227..deb4ceed 100644 --- a/gst/mxf/mxfd10.h +++ b/gst/mxf/mxfd10.h @@ -26,8 +26,6 @@ #include <gst/gst.h> -#include "mxfparse.h" - void mxf_d10_init (void); #endif /* __MXF_D10_H__ */ diff --git a/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c index 733e920d..76458e88 100644 --- a/gst/mxf/mxfdemux.c +++ b/gst/mxf/mxfdemux.c @@ -60,8 +60,7 @@ #endif #include "mxfdemux.h" -#include "mxfparse.h" -#include "mxfmetadata.h" +#include "mxfessence.h" #include <string.h> diff --git a/gst/mxf/mxfdemux.h b/gst/mxf/mxfdemux.h index daa1bff5..c8439cf6 100644 --- a/gst/mxf/mxfdemux.h +++ b/gst/mxf/mxfdemux.h @@ -23,9 +23,7 @@ #include <gst/gst.h> #include <gst/base/gstadapter.h> -#include "mxftypes.h" -#include "mxfparse.h" -#include "mxfmetadata.h" +#include "mxfessence.h" G_BEGIN_DECLS diff --git a/gst/mxf/mxfdms1.c b/gst/mxf/mxfdms1.c index 704d846f..0493270a 100644 --- a/gst/mxf/mxfdms1.c +++ b/gst/mxf/mxfdms1.c @@ -32,7 +32,7 @@ #include <string.h> #include "mxfdms1.h" -#include "mxfparse.h" +#include "mxftypes.h" GST_DEBUG_CATEGORY_EXTERN (mxf_debug); #define GST_CAT_DEFAULT mxf_debug diff --git a/gst/mxf/mxfdv-dif.c b/gst/mxf/mxfdv-dif.c index 220100a3..9e722532 100644 --- a/gst/mxf/mxfdv-dif.c +++ b/gst/mxf/mxfdv-dif.c @@ -37,7 +37,7 @@ #include <string.h> #include "mxfdv-dif.h" -#include "mxfwrite.h" +#include "mxfessence.h" GST_DEBUG_CATEGORY_EXTERN (mxf_debug); #define GST_CAT_DEFAULT mxf_debug diff --git a/gst/mxf/mxfdv-dif.h b/gst/mxf/mxfdv-dif.h index 5b9fc0e8..ce7efa58 100644 --- a/gst/mxf/mxfdv-dif.h +++ b/gst/mxf/mxfdv-dif.h @@ -26,8 +26,6 @@ #include <gst/gst.h> -#include "mxfparse.h" - void mxf_dv_dif_init (void); #endif /* __MXF_DV_DIF_H__ */ diff --git a/gst/mxf/mxfessence.c b/gst/mxf/mxfessence.c new file mode 100644 index 00000000..39350ad5 --- /dev/null +++ b/gst/mxf/mxfessence.c @@ -0,0 +1,108 @@ +/* GStreamer + * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <string.h> + +#include "mxfessence.h" + +GST_DEBUG_CATEGORY_EXTERN (mxf_debug); +#define GST_CAT_DEFAULT mxf_debug + +static GSList *_mxf_essence_element_handler_registry = NULL; + +void +mxf_essence_element_handler_register (const MXFEssenceElementHandler * handler) +{ + _mxf_essence_element_handler_registry = + g_slist_prepend (_mxf_essence_element_handler_registry, + (gpointer) handler); +} + +const MXFEssenceElementHandler * +mxf_essence_element_handler_find (const MXFMetadataTimelineTrack * track) +{ + GSList *l; + const MXFEssenceElementHandler *ret = NULL; + + for (l = _mxf_essence_element_handler_registry; l; l = l->next) { + MXFEssenceElementHandler *current = l->data; + + if (current->handles_track (track)) { + ret = current; + } + } + + return ret; +} + +static GList *_essence_element_writer_registry = NULL; +static GPtrArray *_essence_element_writer_pad_templates = NULL; + +void +mxf_essence_element_writer_register (const MXFEssenceElementWriter * writer) +{ + _essence_element_writer_registry = + g_list_prepend (_essence_element_writer_registry, (gpointer) writer); + + if (!_essence_element_writer_pad_templates) + _essence_element_writer_pad_templates = g_ptr_array_new (); + + if (_essence_element_writer_pad_templates->len > 0 && + g_ptr_array_index (_essence_element_writer_pad_templates, + _essence_element_writer_pad_templates->len - 1) == NULL) + g_ptr_array_remove_index (_essence_element_writer_pad_templates, + _essence_element_writer_pad_templates->len - 1); + + g_ptr_array_add (_essence_element_writer_pad_templates, + (gpointer) writer->pad_template); +} + +const GstPadTemplate ** +mxf_essence_element_writer_get_pad_templates (void) +{ + if (!_essence_element_writer_pad_templates + || _essence_element_writer_pad_templates->len == 0) + return NULL; + + if (g_ptr_array_index (_essence_element_writer_pad_templates, + _essence_element_writer_pad_templates->len - 1)) + g_ptr_array_add (_essence_element_writer_pad_templates, NULL); + + return (const GstPadTemplate **) _essence_element_writer_pad_templates->pdata; +} + +const MXFEssenceElementWriter * +mxf_essence_element_writer_find (const GstPadTemplate * templ) +{ + GList *l = _essence_element_writer_registry; + + for (; l; l = l->next) { + MXFEssenceElementWriter *writer = l->data; + + if (writer->pad_template == templ) + return writer; + } + + return NULL; +} diff --git a/gst/mxf/mxfwrite.h b/gst/mxf/mxfessence.h index 4ebca925..e5ee90c2 100644 --- a/gst/mxf/mxfwrite.h +++ b/gst/mxf/mxfessence.h @@ -17,18 +17,21 @@ * Boston, MA 02111-1307, USA. */ -/* Handling of the basic MXF types */ +#ifndef __MXF_ESSENCE_H__ +#define __MXF_ESSENCE_H__ -#ifndef __MXF_WRITE_H__ -#define __MXF_WRITE_H__ - -#include <string.h> #include <gst/gst.h> #include <gst/base/gstadapter.h> -#include "mxfmetadata.h" #include "mxftypes.h" -#include "mxfparse.h" +#include "mxfmetadata.h" + +typedef GstFlowReturn (*MXFEssenceElementHandleFunc) (const MXFUL *key, GstBuffer *buffer, GstCaps *caps, MXFMetadataTimelineTrack *track, gpointer mapping_data, GstBuffer **outbuf); + +typedef struct { + gboolean (*handles_track) (const MXFMetadataTimelineTrack *track); + GstCaps * (*create_caps) (MXFMetadataTimelineTrack *track, GstTagList **tags, MXFEssenceElementHandleFunc *handler, gpointer *mapping_data); +} MXFEssenceElementHandler; typedef GstFlowReturn (*MXFEssenceElementWriteFunc) (GstBuffer *buffer, GstCaps *caps, gpointer mapping_data, GstAdapter *adapter, GstBuffer **outbuf, gboolean flush); @@ -41,45 +44,11 @@ typedef struct { MXFUL data_definition; } MXFEssenceElementWriter; -typedef enum { - MXF_OP_UNKNOWN = 0, - MXF_OP_ATOM, - MXF_OP_1a, - MXF_OP_1b, - MXF_OP_1c, - MXF_OP_2a, - MXF_OP_2b, - MXF_OP_2c, - MXF_OP_3a, - MXF_OP_3b, - MXF_OP_3c, -} MXFOperationalPattern; +void mxf_essence_element_handler_register (const MXFEssenceElementHandler *handler); +const MXFEssenceElementHandler * mxf_essence_element_handler_find (const MXFMetadataTimelineTrack *track); void mxf_essence_element_writer_register (const MXFEssenceElementWriter *writer); const GstPadTemplate ** mxf_essence_element_writer_get_pad_templates (void); const MXFEssenceElementWriter *mxf_essence_element_writer_find (const GstPadTemplate *templ); -void mxf_ul_set (MXFUL *ul, GHashTable *hashtable); -void mxf_umid_set (MXFUMID *umid); - -void mxf_timestamp_set_now (MXFTimestamp *timestamp); -void mxf_timestamp_write (const MXFTimestamp *timestamp, guint8 *data); - -void mxf_op_set_atom (MXFUL *ul, gboolean single_sourceclip, gboolean single_essence_track); -void mxf_op_set_generalized (MXFUL *ul, MXFOperationalPattern pattern, gboolean internal_essence, gboolean streamable, gboolean single_track); - -guint16 mxf_primer_pack_add_mapping (MXFPrimerPack *primer, guint16 local_tag, const MXFUL *ul); - -guint mxf_ber_encode_size (guint size, guint8 ber[9]); - -guint8 * mxf_utf8_to_utf16 (const gchar *str, guint16 *size); - -void mxf_product_version_write (const MXFProductVersion *version, guint8 *data); - -GstBuffer * mxf_partition_pack_to_buffer (const MXFPartitionPack *pack); -GstBuffer * mxf_primer_pack_to_buffer (const MXFPrimerPack *pack); -GstBuffer * mxf_fill_new (guint size); - -GstBuffer * mxf_random_index_pack_to_buffer (const GArray *array); - -#endif /* __MXF_WRITE_H__ */ +#endif /* __MXF_ESSENCE_H__ */ diff --git a/gst/mxf/mxfjpeg2000.c b/gst/mxf/mxfjpeg2000.c index 9d949d4e..e9e947b3 100644 --- a/gst/mxf/mxfjpeg2000.c +++ b/gst/mxf/mxfjpeg2000.c @@ -35,7 +35,7 @@ #include <string.h> #include "mxfjpeg2000.h" -#include "mxfwrite.h" +#include "mxfessence.h" GST_DEBUG_CATEGORY_EXTERN (mxf_debug); #define GST_CAT_DEFAULT mxf_debug diff --git a/gst/mxf/mxfjpeg2000.h b/gst/mxf/mxfjpeg2000.h index b46f33af..6540a503 100644 --- a/gst/mxf/mxfjpeg2000.h +++ b/gst/mxf/mxfjpeg2000.h @@ -26,8 +26,6 @@ #include <gst/gst.h> -#include "mxfparse.h" - void mxf_jpeg2000_init (void); #endif /* __MXF_JPEG2000_H__ */ diff --git a/gst/mxf/mxfmetadata.c b/gst/mxf/mxfmetadata.c index 0aff0317..8985ea90 100644 --- a/gst/mxf/mxfmetadata.c +++ b/gst/mxf/mxfmetadata.c @@ -24,10 +24,9 @@ #include <gst/gst.h> #include <string.h> -#include "mxfparse.h" +#include "mxftypes.h" #include "mxfmetadata.h" #include "mxfquark.h" -#include "mxfwrite.h" GST_DEBUG_CATEGORY_EXTERN (mxf_debug); #define GST_CAT_DEFAULT mxf_debug diff --git a/gst/mxf/mxfmpeg.c b/gst/mxf/mxfmpeg.c index 868aeb80..e9269810 100644 --- a/gst/mxf/mxfmpeg.c +++ b/gst/mxf/mxfmpeg.c @@ -38,7 +38,7 @@ #include "mxfmpeg.h" #include "mxfquark.h" -#include "mxfwrite.h" +#include "mxfessence.h" #include <gst/base/gstbytereader.h> diff --git a/gst/mxf/mxfmpeg.h b/gst/mxf/mxfmpeg.h index 15f96cee..2beddec3 100644 --- a/gst/mxf/mxfmpeg.h +++ b/gst/mxf/mxfmpeg.h @@ -26,8 +26,6 @@ #include <gst/gst.h> -#include "mxfparse.h" - void mxf_mpeg_init (void); gboolean mxf_mpeg_is_mpeg2_keyframe (GstBuffer *buffer); diff --git a/gst/mxf/mxfmux.h b/gst/mxf/mxfmux.h index 81f232ad..d539aaa1 100644 --- a/gst/mxf/mxfmux.h +++ b/gst/mxf/mxfmux.h @@ -24,7 +24,7 @@ #include <gst/base/gstadapter.h> #include <gst/base/gstcollectpads.h> -#include "mxfwrite.h" +#include "mxfessence.h" G_BEGIN_DECLS diff --git a/gst/mxf/mxfparse.h b/gst/mxf/mxfparse.h deleted file mode 100644 index 58d88d6b..00000000 --- a/gst/mxf/mxfparse.h +++ /dev/null @@ -1,105 +0,0 @@ -/* GStreamer - * Copyright (C) 2008-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Handling of the basic MXF types */ - -#ifndef __MXF_PARSE_H__ -#define __MXF_PARSE_H__ - -#include <string.h> - -#include "mxftypes.h" -#include "mxful.h" -#include "mxfmetadata.h" - -typedef GstFlowReturn (*MXFEssenceElementHandleFunc) (const MXFUL *key, GstBuffer *buffer, GstCaps *caps, MXFMetadataTimelineTrack *track, gpointer mapping_data, GstBuffer **outbuf); - -typedef struct { - gboolean (*handles_track) (const MXFMetadataTimelineTrack *track); - GstCaps * (*create_caps) (MXFMetadataTimelineTrack *track, GstTagList **tags, MXFEssenceElementHandleFunc *handler, gpointer *mapping_data); -} MXFEssenceElementHandler; - -gchar *mxf_umid_to_string (const MXFUMID * umid, gchar str[96]); -MXFUMID *mxf_umid_from_string (const gchar *str, MXFUMID * umid); -gboolean mxf_umid_is_equal (const MXFUMID *a, const MXFUMID *b); -gboolean mxf_umid_is_zero (const MXFUMID *umid); - -gboolean mxf_is_mxf_packet (const MXFUL *key); - -gboolean mxf_is_partition_pack (const MXFUL *key); -gboolean mxf_is_header_partition_pack (const MXFUL *key); -gboolean mxf_is_body_partition_pack (const MXFUL *key); -gboolean mxf_is_footer_partition_pack (const MXFUL *key); - -gboolean mxf_is_primer_pack (const MXFUL *key); - -gboolean mxf_is_metadata (const MXFUL *key); -gboolean mxf_is_descriptive_metadata (const MXFUL *key); - -gboolean mxf_is_random_index_pack (const MXFUL *key); -gboolean mxf_is_index_table_segment (const MXFUL *key); - -gboolean mxf_is_generic_container_system_item (const MXFUL *key); -gboolean mxf_is_generic_container_essence_element (const MXFUL *key); -gboolean mxf_is_avid_essence_container_essence_element (const MXFUL * key); - -gboolean mxf_is_generic_container_essence_container_label (const MXFUL *key); -gboolean mxf_is_avid_essence_container_label (const MXFUL *key); - -gboolean mxf_is_fill (const MXFUL *key); - -gchar * mxf_utf16_to_utf8 (const guint8 * data, guint size); - -gboolean mxf_product_version_parse (MXFProductVersion * product_version, - const guint8 * data, guint size); -gboolean mxf_product_version_is_valid (const MXFProductVersion *version); - -gboolean mxf_fraction_parse (MXFFraction *fraction, const guint8 *data, guint size); -gdouble mxf_fraction_to_double (const MXFFraction *fraction); - -gboolean mxf_timestamp_parse (MXFTimestamp * timestamp, const guint8 * data, guint size); -gboolean mxf_timestamp_is_unknown (const MXFTimestamp *a); -gint mxf_timestamp_compare (const MXFTimestamp *a, const MXFTimestamp *b); -gchar *mxf_timestamp_to_string (const MXFTimestamp *t, gchar str[32]); - -gboolean mxf_partition_pack_parse (const MXFUL *key, MXFPartitionPack *pack, const guint8 *data, guint size); -void mxf_partition_pack_reset (MXFPartitionPack *pack); - -gboolean mxf_primer_pack_parse (const MXFUL *key, MXFPrimerPack *pack, const guint8 *data, guint size); -void mxf_primer_pack_reset (MXFPrimerPack *pack); - -gboolean mxf_random_index_pack_parse (const MXFUL *key, const guint8 *data, guint size, GArray **array); - -gboolean mxf_index_table_segment_parse (const MXFUL *key, MXFIndexTableSegment *segment, const MXFPrimerPack *primer, const guint8 *data, guint size); -void mxf_index_table_segment_reset (MXFIndexTableSegment *segment); - -gboolean mxf_local_tag_parse (const guint8 * data, guint size, guint16 * tag, - guint16 * tag_size, const guint8 ** tag_data); -void mxf_local_tag_free (MXFLocalTag *tag); - -gboolean mxf_local_tag_add_to_hash_table (const MXFPrimerPack *primer, - guint16 tag, const guint8 *tag_data, guint16 tag_size, - GHashTable **hash_table); -gboolean mxf_local_tag_insert (MXFLocalTag *tag, GHashTable **hash_table); - -void mxf_essence_element_handler_register (const MXFEssenceElementHandler *handler); -const MXFEssenceElementHandler * mxf_essence_element_handler_find (const MXFMetadataTimelineTrack *track); - -#endif /* __MXF_PARSE_H__ */ - diff --git a/gst/mxf/mxfparse.c b/gst/mxf/mxftypes.c index f0c0d0e5..5660ec7f 100644 --- a/gst/mxf/mxfparse.c +++ b/gst/mxf/mxftypes.c @@ -24,7 +24,7 @@ #include <gst/gst.h> #include <string.h> -#include "mxfparse.h" +#include "mxftypes.h" GST_DEBUG_CATEGORY_EXTERN (mxf_debug); #define GST_CAT_DEFAULT mxf_debug @@ -157,6 +157,66 @@ mxf_is_avid_essence_container_essence_element (const MXFUL * ul) ul)); } +guint +mxf_ber_encode_size (guint size, guint8 ber[9]) +{ + guint8 slen, i; + guint8 tmp[8]; + + memset (ber, 0, 9); + + if (size <= 127) { + ber[0] = size; + return 1; + } else if (size > G_MAXUINT) { + return 0; + } + + slen = 0; + while (size > 0) { + tmp[slen] = size & 0xff; + size >>= 8; + slen++; + } + + ber[0] = 0x80 | slen; + for (i = 0; i < slen; i++) { + ber[i + 1] = tmp[slen - i - 1]; + } + + return slen + 1; +} + +GstBuffer * +mxf_fill_new (guint size) +{ + GstBuffer *ret; + guint slen; + guint8 ber[9]; + + slen = mxf_ber_encode_size (size, ber); + + ret = gst_buffer_new_and_alloc (16 + slen + size); + memcpy (GST_BUFFER_DATA (ret), MXF_UL (FILL), 16); + memcpy (GST_BUFFER_DATA (ret) + 16, &ber, slen); + memset (GST_BUFFER_DATA (ret) + slen, 0, size); + + return ret; +} + +void +mxf_ul_set (MXFUL * ul, GHashTable * hashtable) +{ + guint i; + + do { + for (i = 0; i < 4; i++) + GST_WRITE_UINT32_BE (&ul->u[i * 4], g_random_int ()); + + } while (hashtable + && g_hash_table_lookup_extended (hashtable, ul, NULL, NULL)); +} + gboolean mxf_umid_is_equal (const MXFUMID * a, const MXFUMID * b) { @@ -231,6 +291,52 @@ mxf_umid_from_string (const gchar * str, MXFUMID * umid) return umid; } +void +mxf_umid_set (MXFUMID * umid) +{ + guint i; + guint32 tmp; + + /* SMPTE S330M 5.1.1: + * UMID Identifier + */ + umid->u[0] = 0x06; + umid->u[1] = 0x0a; + umid->u[2] = 0x2b; + umid->u[3] = 0x34; + umid->u[4] = 0x01; + umid->u[5] = 0x01; + umid->u[6] = 0x01; + umid->u[7] = 0x05; /* version, see RP210 */ + umid->u[8] = 0x01; + umid->u[9] = 0x01; + umid->u[10] = 0x0d; /* mixed group of components in a single container */ + + /* - UUID/UL method for material number + * - 24 bit PRG for instance number + */ + umid->u[11] = 0x20 | 0x02; + + /* Length of remaining data */ + umid->u[12] = 0x13; + + /* Instance number */ + tmp = g_random_int (); + umid->u[13] = (tmp >> 24) & 0xff; + umid->u[14] = (tmp >> 16) & 0xff; + umid->u[15] = (tmp >> 8) & 0xff; + + /* Material number: ISO UUID Version 4 */ + for (i = 16; i < 32; i += 4) + GST_WRITE_UINT32_BE (&umid->u[i], g_random_int ()); + + umid->u[16 + 6] &= 0x0f; + umid->u[16 + 6] |= 0x40; + + umid->u[16 + 8] &= 0x3f; + umid->u[16 + 8] |= 0x80; +} + gboolean mxf_timestamp_parse (MXFTimestamp * timestamp, const guint8 * data, guint size) { @@ -294,6 +400,47 @@ mxf_timestamp_to_string (const MXFTimestamp * t, gchar str[32]) return str; } +void +mxf_timestamp_set_now (MXFTimestamp * timestamp) +{ + GTimeVal tv; + time_t t; + struct tm *tm; + +#ifdef HAVE_GMTIME_R + struct tm tm_; +#endif + + g_get_current_time (&tv); + t = (time_t) tv.tv_sec; + +#ifdef HAVE_GMTIME_R + tm = gmtime_r (&t, &tm_); +#else + tm = gmtime (&t); +#endif + + timestamp->year = tm->tm_year + 1900; + timestamp->month = tm->tm_mon; + timestamp->day = tm->tm_mday; + timestamp->hour = tm->tm_hour; + timestamp->minute = tm->tm_min; + timestamp->second = tm->tm_sec; + timestamp->msecond = tv.tv_usec / 1000; +} + +void +mxf_timestamp_write (const MXFTimestamp * timestamp, guint8 * data) +{ + GST_WRITE_UINT16_BE (data, timestamp->year); + GST_WRITE_UINT8 (data + 2, timestamp->month); + GST_WRITE_UINT8 (data + 3, timestamp->day); + GST_WRITE_UINT8 (data + 4, timestamp->hour); + GST_WRITE_UINT8 (data + 5, timestamp->minute); + GST_WRITE_UINT8 (data + 6, timestamp->second); + GST_WRITE_UINT8 (data + 7, (timestamp->msecond * 256) / 1000); +} + gboolean mxf_fraction_parse (MXFFraction * fraction, const guint8 * data, guint size) { @@ -336,6 +483,35 @@ mxf_utf16_to_utf8 (const guint8 * data, guint size) return ret; } +guint8 * +mxf_utf8_to_utf16 (const gchar * str, guint16 * size) +{ + guint8 *ret; + GError *error = NULL; + gsize s; + + g_return_val_if_fail (size != NULL, NULL); + + if (str == NULL) { + *size = 0; + return NULL; + } + + ret = (guint8 *) + g_convert_with_fallback (str, -1, "UTF-16BE", "UTF-8", "*", NULL, &s, + &error); + + if (ret == NULL) { + GST_WARNING ("UTF-16-BE to UTF-8 conversion failed: %s", error->message); + g_error_free (error); + *size = 0; + return NULL; + } + + *size = s; + return (guint8 *) ret; +} + gboolean mxf_product_version_parse (MXFProductVersion * product_version, const guint8 * data, guint size) @@ -370,6 +546,67 @@ mxf_product_version_is_valid (const MXFProductVersion * version) return (memcmp (version, &null, sizeof (MXFProductVersion)) == 0); } +void +mxf_product_version_write (const MXFProductVersion * version, guint8 * data) +{ + GST_WRITE_UINT16_BE (data, version->major); + GST_WRITE_UINT16_BE (data + 2, version->minor); + GST_WRITE_UINT16_BE (data + 4, version->patch); + GST_WRITE_UINT16_BE (data + 6, version->build); + GST_WRITE_UINT16_BE (data + 8, version->release); +} + +void +mxf_op_set_atom (MXFUL * ul, gboolean single_sourceclip, + gboolean single_essence_track) +{ + memcpy (&ul->u, MXF_UL (OPERATIONAL_PATTERN_IDENTIFICATION), 12); + ul->u[12] = 0x10; + ul->u[13] = 0; + + if (!single_sourceclip) + ul->u[13] |= 0x80; + + if (!single_essence_track) + ul->u[13] |= 0x40; + + ul->u[14] = 0; + ul->u[15] = 0; +} + +void +mxf_op_set_generalized (MXFUL * ul, MXFOperationalPattern pattern, + gboolean internal_essence, gboolean streamable, gboolean single_track) +{ + g_return_if_fail (pattern >= MXF_OP_1a); + + memcpy (&ul->u, MXF_UL (OPERATIONAL_PATTERN_IDENTIFICATION), 12); + + if (pattern == MXF_OP_1a || pattern == MXF_OP_1b || pattern == MXF_OP_1c) + ul->u[12] = 0x01; + else if (pattern == MXF_OP_2a || pattern == MXF_OP_2b || pattern == MXF_OP_2c) + ul->u[12] = 0x02; + else if (pattern == MXF_OP_3a || pattern == MXF_OP_3b || pattern == MXF_OP_3c) + ul->u[12] = 0x03; + + if (pattern == MXF_OP_1a || pattern == MXF_OP_2a || pattern == MXF_OP_3a) + ul->u[13] = 0x01; + else if (pattern == MXF_OP_1b || pattern == MXF_OP_2b || pattern == MXF_OP_3b) + ul->u[13] = 0x02; + else if (pattern == MXF_OP_1c || pattern == MXF_OP_2c || pattern == MXF_OP_3c) + ul->u[13] = 0x02; + + ul->u[14] = 0x80; + if (!internal_essence) + ul->u[14] |= 0x40; + if (!streamable) + ul->u[14] |= 0x20; + if (!single_track) + ul->u[14] |= 0x10; + + ul->u[15] = 0; +} + /* SMPTE 377M 6.1, Table 2 */ gboolean mxf_partition_pack_parse (const MXFUL * key, MXFPartitionPack * pack, @@ -512,6 +749,83 @@ mxf_partition_pack_reset (MXFPartitionPack * pack) memset (pack, 0, sizeof (MXFPartitionPack)); } +GstBuffer * +mxf_partition_pack_to_buffer (const MXFPartitionPack * pack) +{ + guint slen; + guint8 ber[9]; + GstBuffer *ret; + guint8 *data; + guint i; + guint size = + 8 + 16 * pack->n_essence_containers + 16 + 4 + 8 + 4 + 8 + 8 + 8 + 8 + 8 + + 4 + 2 + 2; + + slen = mxf_ber_encode_size (size, ber); + + ret = gst_buffer_new_and_alloc (16 + slen + size); + memcpy (GST_BUFFER_DATA (ret), MXF_UL (PARTITION_PACK), 13); + if (pack->type == MXF_PARTITION_PACK_HEADER) + GST_BUFFER_DATA (ret)[13] = 0x02; + else if (pack->type == MXF_PARTITION_PACK_BODY) + GST_BUFFER_DATA (ret)[13] = 0x03; + else if (pack->type == MXF_PARTITION_PACK_FOOTER) + GST_BUFFER_DATA (ret)[13] = 0x04; + GST_BUFFER_DATA (ret)[14] = 0; + if (pack->complete) + GST_BUFFER_DATA (ret)[14] |= 0x02; + if (pack->closed) + GST_BUFFER_DATA (ret)[14] |= 0x01; + GST_BUFFER_DATA (ret)[14] += 1; + GST_BUFFER_DATA (ret)[15] = 0; + memcpy (GST_BUFFER_DATA (ret) + 16, &ber, slen); + + data = GST_BUFFER_DATA (ret) + 16 + slen; + + GST_WRITE_UINT16_BE (data, pack->major_version); + GST_WRITE_UINT16_BE (data + 2, pack->minor_version); + data += 4; + + GST_WRITE_UINT32_BE (data, pack->kag_size); + data += 4; + + GST_WRITE_UINT64_BE (data, pack->this_partition); + data += 8; + + GST_WRITE_UINT64_BE (data, pack->prev_partition); + data += 8; + + GST_WRITE_UINT64_BE (data, pack->footer_partition); + data += 8; + + GST_WRITE_UINT64_BE (data, pack->header_byte_count); + data += 8; + + GST_WRITE_UINT64_BE (data, pack->index_byte_count); + data += 8; + + GST_WRITE_UINT32_BE (data, pack->index_sid); + data += 4; + + GST_WRITE_UINT64_BE (data, pack->body_offset); + data += 8; + + GST_WRITE_UINT32_BE (data, pack->body_sid); + data += 4; + + memcpy (data, &pack->operational_pattern, 16); + data += 16; + + GST_WRITE_UINT32_BE (data, pack->n_essence_containers); + GST_WRITE_UINT32_BE (data + 4, 16); + data += 8; + + for (i = 0; i < pack->n_essence_containers; i++) + memcpy (data + 16 * i, &pack->essence_containers[i], 16); + + return ret; +} + /* SMPTE 377M 11.1 */ gboolean mxf_random_index_pack_parse (const MXFUL * key, const guint8 * data, guint size, @@ -552,6 +866,38 @@ mxf_random_index_pack_parse (const MXFUL * key, const guint8 * data, guint size, return TRUE; } +GstBuffer * +mxf_random_index_pack_to_buffer (const GArray * array) +{ + MXFRandomIndexPackEntry *entry; + guint i; + GstBuffer *ret; + guint8 slen, ber[9]; + guint size; + guint8 *data; + + if (array->len == 0) + return NULL; + + size = array->len * 12 + 4; + slen = mxf_ber_encode_size (size, ber); + ret = gst_buffer_new_and_alloc (16 + slen + size); + memcpy (GST_BUFFER_DATA (ret), MXF_UL (RANDOM_INDEX_PACK), 16); + memcpy (GST_BUFFER_DATA (ret) + 16, ber, slen); + + data = GST_BUFFER_DATA (ret) + 16 + slen; + + for (i = 0; i < array->len; i++) { + entry = &g_array_index (array, MXFRandomIndexPackEntry, i); + GST_WRITE_UINT32_BE (data, entry->body_sid); + GST_WRITE_UINT64_BE (data + 4, entry->offset); + data += 12; + } + GST_WRITE_UINT32_BE (data, GST_BUFFER_SIZE (ret)); + + return ret; +} + /* SMPTE 377M 10.2.3 */ gboolean mxf_index_table_segment_parse (const MXFUL * key, @@ -882,6 +1228,119 @@ mxf_primer_pack_reset (MXFPrimerPack * pack) pack->next_free_tag = 0x8000; } +guint16 +mxf_primer_pack_add_mapping (MXFPrimerPack * primer, guint16 local_tag, + const MXFUL * ul) +{ + MXFUL *uid; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + + if (primer->mappings == NULL) { + primer->mappings = g_hash_table_new_full (g_direct_hash, g_direct_equal, + (GDestroyNotify) NULL, (GDestroyNotify) _mxf_mapping_ul_free); + } + + if (primer->reverse_mappings == NULL) { + primer->reverse_mappings = g_hash_table_new_full ((GHashFunc) mxf_ul_hash, + (GEqualFunc) mxf_ul_is_equal, (GDestroyNotify) _mxf_mapping_ul_free, + (GDestroyNotify) NULL); + } + + if (primer->next_free_tag == 0xffff && local_tag == 0) { + GST_ERROR ("Used too many dynamic tags"); + return 0; + } + + if (local_tag == 0) { + guint16 tmp; + + tmp = GPOINTER_TO_UINT (g_hash_table_lookup (primer->reverse_mappings, ul)); + if (tmp == 0) { + local_tag = primer->next_free_tag; + primer->next_free_tag++; + } + } else { + if (g_hash_table_lookup (primer->mappings, GUINT_TO_POINTER (local_tag))) + return local_tag; + } + + g_assert (local_tag != 0); + + uid = g_slice_new (MXFUL); + memcpy (uid, ul, 16); + + GST_DEBUG ("Adding mapping = 0x%04x -> %s", local_tag, + mxf_ul_to_string (uid, str)); + g_hash_table_insert (primer->mappings, GUINT_TO_POINTER (local_tag), uid); + uid = g_slice_dup (MXFUL, uid); + g_hash_table_insert (primer->reverse_mappings, uid, + GUINT_TO_POINTER (local_tag)); + + return local_tag; +} + +GstBuffer * +mxf_primer_pack_to_buffer (const MXFPrimerPack * pack) +{ + guint slen; + guint8 ber[9]; + GstBuffer *ret; + guint n; + guint8 *data; + + if (pack->mappings) + n = g_hash_table_size (pack->mappings); + else + n = 0; + + slen = mxf_ber_encode_size (8 + 18 * n, ber); + + ret = gst_buffer_new_and_alloc (16 + slen + 8 + 18 * n); + memcpy (GST_BUFFER_DATA (ret), MXF_UL (PRIMER_PACK), 16); + memcpy (GST_BUFFER_DATA (ret) + 16, &ber, slen); + + data = GST_BUFFER_DATA (ret) + 16 + slen; + + GST_WRITE_UINT32_BE (data, n); + GST_WRITE_UINT32_BE (data + 4, 18); + data += 8; + + if (pack->mappings) { + guint16 local_tag; + MXFUL *ul; +#if GLIB_CHECK_VERSION (2, 16, 0) + GHashTableIter iter; + + g_hash_table_iter_init (&iter, pack->mappings); +#else + GList *l, *values; + + keys = g_hash_table_get_keys (pack->mappings); +#endif + +#if GLIB_CHECK_VERSION (2, 16, 0) + while (g_hash_table_iter_next (&iter, (gpointer) & local_tag, + (gpointer) & ul)) { +#else + for (l = keys l; l = l->next) { + local_tag = GPOINTER_TO_GUINT (l->data); + ul = g_hash_table_lookup (pack->mappings, GUINT_TO_POINTER (local_tag)); +#endif + GST_WRITE_UINT16_BE (data, local_tag); + memcpy (data + 2, ul, 16); + data += 18; + } + +#if !GLIB_CHECK_VERSION (2, 16, 0) + g_list_free (keys); +#endif + } + + return ret; +} + /* structural metadata parsing */ gboolean @@ -984,30 +1443,3 @@ mxf_local_tag_insert (MXFLocalTag * tag, GHashTable ** hash_table) return TRUE; } - -static GSList *_mxf_essence_element_handler_registry = NULL; - -void -mxf_essence_element_handler_register (const MXFEssenceElementHandler * handler) -{ - _mxf_essence_element_handler_registry = - g_slist_prepend (_mxf_essence_element_handler_registry, - (gpointer) handler); -} - -const MXFEssenceElementHandler * -mxf_essence_element_handler_find (const MXFMetadataTimelineTrack * track) -{ - GSList *l; - const MXFEssenceElementHandler *ret = NULL; - - for (l = _mxf_essence_element_handler_registry; l; l = l->next) { - MXFEssenceElementHandler *current = l->data; - - if (current->handles_track (track)) { - ret = current; - } - } - - return ret; -} diff --git a/gst/mxf/mxftypes.h b/gst/mxf/mxftypes.h index ffb40d9c..8a6e9ccc 100644 --- a/gst/mxf/mxftypes.h +++ b/gst/mxf/mxftypes.h @@ -24,10 +24,7 @@ #include <gst/gst.h> -/* SMPTE 377M 3.2 */ -typedef struct { - guint8 u[16]; -} MXFUL; +#include "mxful.h" typedef struct { guint8 u[16]; @@ -80,6 +77,20 @@ typedef struct { } MXFRandomIndexPackEntry; typedef enum { + MXF_OP_UNKNOWN = 0, + MXF_OP_ATOM, + MXF_OP_1a, + MXF_OP_1b, + MXF_OP_1c, + MXF_OP_2a, + MXF_OP_2b, + MXF_OP_2c, + MXF_OP_3a, + MXF_OP_3b, + MXF_OP_3c, +} MXFOperationalPattern; + +typedef enum { MXF_PARTITION_PACK_HEADER, MXF_PARTITION_PACK_BODY, MXF_PARTITION_PACK_FOOTER @@ -166,4 +177,88 @@ typedef struct { #define GST_TAG_MXF_STRUCTURE "mxf-structure" #define GST_TAG_MXF_DESCRIPTIVE_METADATA_FRAMEWORK "mxf-descriptive-metadata-framework" +/* FIXME: UUID */ +void mxf_ul_set (MXFUL *ul, GHashTable *hashtable); + +gchar *mxf_umid_to_string (const MXFUMID * umid, gchar str[96]); +MXFUMID *mxf_umid_from_string (const gchar *str, MXFUMID * umid); +gboolean mxf_umid_is_equal (const MXFUMID *a, const MXFUMID *b); +gboolean mxf_umid_is_zero (const MXFUMID *umid); +/* FIXME: _set => init */ +void mxf_umid_set (MXFUMID *umid); + +gboolean mxf_is_mxf_packet (const MXFUL *key); + +gboolean mxf_is_partition_pack (const MXFUL *key); +gboolean mxf_is_header_partition_pack (const MXFUL *key); +gboolean mxf_is_body_partition_pack (const MXFUL *key); +gboolean mxf_is_footer_partition_pack (const MXFUL *key); + +gboolean mxf_is_primer_pack (const MXFUL *key); + +gboolean mxf_is_metadata (const MXFUL *key); +gboolean mxf_is_descriptive_metadata (const MXFUL *key); + +gboolean mxf_is_random_index_pack (const MXFUL *key); +gboolean mxf_is_index_table_segment (const MXFUL *key); + +gboolean mxf_is_generic_container_system_item (const MXFUL *key); +gboolean mxf_is_generic_container_essence_element (const MXFUL *key); +gboolean mxf_is_avid_essence_container_essence_element (const MXFUL * key); + +gboolean mxf_is_generic_container_essence_container_label (const MXFUL *key); +gboolean mxf_is_avid_essence_container_label (const MXFUL *key); + +gboolean mxf_is_fill (const MXFUL *key); + +guint mxf_ber_encode_size (guint size, guint8 ber[9]); + +gchar * mxf_utf16_to_utf8 (const guint8 * data, guint size); +guint8 * mxf_utf8_to_utf16 (const gchar *str, guint16 *size); + +gboolean mxf_product_version_parse (MXFProductVersion * product_version, + const guint8 * data, guint size); +gboolean mxf_product_version_is_valid (const MXFProductVersion *version); +void mxf_product_version_write (const MXFProductVersion *version, guint8 *data); + + +gboolean mxf_fraction_parse (MXFFraction *fraction, const guint8 *data, guint size); +gdouble mxf_fraction_to_double (const MXFFraction *fraction); + +gboolean mxf_timestamp_parse (MXFTimestamp * timestamp, const guint8 * data, guint size); +gboolean mxf_timestamp_is_unknown (const MXFTimestamp *a); +gint mxf_timestamp_compare (const MXFTimestamp *a, const MXFTimestamp *b); +gchar *mxf_timestamp_to_string (const MXFTimestamp *t, gchar str[32]); +void mxf_timestamp_set_now (MXFTimestamp *timestamp); +void mxf_timestamp_write (const MXFTimestamp *timestamp, guint8 *data); + +void mxf_op_set_atom (MXFUL *ul, gboolean single_sourceclip, gboolean single_essence_track); +void mxf_op_set_generalized (MXFUL *ul, MXFOperationalPattern pattern, gboolean internal_essence, gboolean streamable, gboolean single_track); + +GstBuffer * mxf_fill_new (guint size); + +gboolean mxf_partition_pack_parse (const MXFUL *key, MXFPartitionPack *pack, const guint8 *data, guint size); +void mxf_partition_pack_reset (MXFPartitionPack *pack); +GstBuffer * mxf_partition_pack_to_buffer (const MXFPartitionPack *pack); + +gboolean mxf_primer_pack_parse (const MXFUL *key, MXFPrimerPack *pack, const guint8 *data, guint size); +void mxf_primer_pack_reset (MXFPrimerPack *pack); +guint16 mxf_primer_pack_add_mapping (MXFPrimerPack *primer, guint16 local_tag, const MXFUL *ul); +GstBuffer * mxf_primer_pack_to_buffer (const MXFPrimerPack *pack); + +gboolean mxf_random_index_pack_parse (const MXFUL *key, const guint8 *data, guint size, GArray **array); +GstBuffer * mxf_random_index_pack_to_buffer (const GArray *array); + +gboolean mxf_index_table_segment_parse (const MXFUL *key, MXFIndexTableSegment *segment, const MXFPrimerPack *primer, const guint8 *data, guint size); +void mxf_index_table_segment_reset (MXFIndexTableSegment *segment); + +gboolean mxf_local_tag_parse (const guint8 * data, guint size, guint16 * tag, + guint16 * tag_size, const guint8 ** tag_data); +void mxf_local_tag_free (MXFLocalTag *tag); + +gboolean mxf_local_tag_add_to_hash_table (const MXFPrimerPack *primer, + guint16 tag, const guint8 *tag_data, guint16 tag_size, + GHashTable **hash_table); +gboolean mxf_local_tag_insert (MXFLocalTag *tag, GHashTable **hash_table); + #endif /* __MXF_TYPES_H__ */ diff --git a/gst/mxf/mxful.c b/gst/mxf/mxful.c index 37624c53..6ddc8ebd 100644 --- a/gst/mxf/mxful.c +++ b/gst/mxf/mxful.c @@ -64,6 +64,9 @@ const MXFUL _mxf_ul_table[] = { /* AVID_ESSENCE_CONTAINER_ESSENCE_LABEL, undocumented */ {{0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0xff, 0x4b, 0x46, 0x41, 0x41, 0x00, 0x0d, 0x4d, 0x4f}}, + /* OPERATIONAL_PATTERN_IDENTIFICATION */ + {{0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, + 0x0d, 0x01, 0x02, 0x01, 0x00,}} }; gboolean diff --git a/gst/mxf/mxful.h b/gst/mxf/mxful.h index b187229d..9a82f12a 100644 --- a/gst/mxf/mxful.h +++ b/gst/mxf/mxful.h @@ -22,7 +22,10 @@ #include <gst/gst.h> -#include "mxftypes.h" +/* SMPTE 377M 3.2 */ +typedef struct { + guint8 u[16]; +} MXFUL; typedef enum { MXF_UL_SMPTE = 0, @@ -38,6 +41,7 @@ typedef enum { MXF_UL_GENERIC_CONTAINER_ESSENCE_CONTAINER_LABEL, MXF_UL_AVID_ESSENCE_CONTAINER_ESSENCE_ELEMENT, MXF_UL_AVID_ESSENCE_CONTAINER_ESSENCE_LABEL, + MXF_UL_OPERATIONAL_PATTERN_IDENTIFICATION, MXF_UL_MAX } MXFULId; diff --git a/gst/mxf/mxfup.c b/gst/mxf/mxfup.c index a86a2c19..fa669d42 100644 --- a/gst/mxf/mxfup.c +++ b/gst/mxf/mxfup.c @@ -39,7 +39,7 @@ #include <gst/video/video.h> #include "mxfup.h" -#include "mxfwrite.h" +#include "mxfessence.h" GST_DEBUG_CATEGORY_EXTERN (mxf_debug); #define GST_CAT_DEFAULT mxf_debug diff --git a/gst/mxf/mxfup.h b/gst/mxf/mxfup.h index 02d60084..a1c8e15e 100644 --- a/gst/mxf/mxfup.h +++ b/gst/mxf/mxfup.h @@ -26,8 +26,6 @@ #include <gst/gst.h> -#include "mxfparse.h" - void mxf_up_init (void); #endif /* __MXF_UP_H__ */ diff --git a/gst/mxf/mxfvc3.c b/gst/mxf/mxfvc3.c index 3e94f378..4c0c6692 100644 --- a/gst/mxf/mxfvc3.c +++ b/gst/mxf/mxfvc3.c @@ -30,7 +30,7 @@ #include <string.h> #include "mxfvc3.h" -#include "mxfwrite.h" +#include "mxfessence.h" GST_DEBUG_CATEGORY_EXTERN (mxf_debug); #define GST_CAT_DEFAULT mxf_debug diff --git a/gst/mxf/mxfvc3.h b/gst/mxf/mxfvc3.h index d467e7dd..97053b97 100644 --- a/gst/mxf/mxfvc3.h +++ b/gst/mxf/mxfvc3.h @@ -26,8 +26,6 @@ #include <gst/gst.h> -#include "mxfparse.h" - void mxf_vc3_init (void); #endif /* __MXF_VC3_H__ */ diff --git a/gst/mxf/mxfwrite.c b/gst/mxf/mxfwrite.c deleted file mode 100644 index 3a92a8ad..00000000 --- a/gst/mxf/mxfwrite.c +++ /dev/null @@ -1,551 +0,0 @@ -/* GStreamer - * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gst/gst.h> -#include <string.h> - -#include "mxfwrite.h" -#include "mxful.h" - -GST_DEBUG_CATEGORY_EXTERN (mxf_debug); -#define GST_CAT_DEFAULT mxf_debug - -static GList *_essence_element_writer_registry = NULL; -static GPtrArray *_essence_element_writer_pad_templates = NULL; - -void -mxf_essence_element_writer_register (const MXFEssenceElementWriter * writer) -{ - _essence_element_writer_registry = - g_list_prepend (_essence_element_writer_registry, (gpointer) writer); - - if (!_essence_element_writer_pad_templates) - _essence_element_writer_pad_templates = g_ptr_array_new (); - - if (_essence_element_writer_pad_templates->len > 0 && - g_ptr_array_index (_essence_element_writer_pad_templates, - _essence_element_writer_pad_templates->len - 1) == NULL) - g_ptr_array_remove_index (_essence_element_writer_pad_templates, - _essence_element_writer_pad_templates->len - 1); - - g_ptr_array_add (_essence_element_writer_pad_templates, - (gpointer) writer->pad_template); -} - -const GstPadTemplate ** -mxf_essence_element_writer_get_pad_templates (void) -{ - if (!_essence_element_writer_pad_templates - || _essence_element_writer_pad_templates->len == 0) - return NULL; - - if (g_ptr_array_index (_essence_element_writer_pad_templates, - _essence_element_writer_pad_templates->len - 1)) - g_ptr_array_add (_essence_element_writer_pad_templates, NULL); - - return (const GstPadTemplate **) _essence_element_writer_pad_templates->pdata; -} - -const MXFEssenceElementWriter * -mxf_essence_element_writer_find (const GstPadTemplate * templ) -{ - GList *l = _essence_element_writer_registry; - - for (; l; l = l->next) { - MXFEssenceElementWriter *writer = l->data; - - if (writer->pad_template == templ) - return writer; - } - - return NULL; -} - -void -mxf_ul_set (MXFUL * ul, GHashTable * hashtable) -{ - guint i; - -next_try: - for (i = 0; i < 4; i++) - GST_WRITE_UINT32_BE (&ul->u[i * 4], g_random_int ()); - - if (hashtable && g_hash_table_lookup_extended (hashtable, ul, NULL, NULL)) - goto next_try; -} - -void -mxf_umid_set (MXFUMID * umid) -{ - guint i; - guint32 tmp; - - /* SMPTE S330M 5.1.1: - * UMID Identifier - */ - umid->u[0] = 0x06; - umid->u[1] = 0x0a; - umid->u[2] = 0x2b; - umid->u[3] = 0x34; - umid->u[4] = 0x01; - umid->u[5] = 0x01; - umid->u[6] = 0x01; - umid->u[7] = 0x05; /* version, see RP210 */ - umid->u[8] = 0x01; - umid->u[9] = 0x01; - umid->u[10] = 0x0d; /* mixed group of components in a single container */ - - /* - UUID/UL method for material number - * - 24 bit PRG for instance number - */ - umid->u[11] = 0x20 | 0x02; - - /* Length of remaining data */ - umid->u[12] = 0x13; - - /* Instance number */ - tmp = g_random_int (); - umid->u[13] = (tmp >> 24) & 0xff; - umid->u[14] = (tmp >> 16) & 0xff; - umid->u[15] = (tmp >> 8) & 0xff; - - /* Material number: ISO UUID Version 4 */ - for (i = 16; i < 32; i += 4) - GST_WRITE_UINT32_BE (&umid->u[i], g_random_int ()); - - umid->u[16 + 6] &= 0x0f; - umid->u[16 + 6] |= 0x40; - - umid->u[16 + 8] &= 0x3f; - umid->u[16 + 8] |= 0x80; -} - -void -mxf_timestamp_set_now (MXFTimestamp * timestamp) -{ - GTimeVal tv; - time_t t; - struct tm *tm; - -#ifdef HAVE_GMTIME_R - struct tm tm_; -#endif - - g_get_current_time (&tv); - t = (time_t) tv.tv_sec; - -#ifdef HAVE_GMTIME_R - tm = gmtime_r (&t, &tm_); -#else - tm = gmtime (&t); -#endif - - timestamp->year = tm->tm_year + 1900; - timestamp->month = tm->tm_mon; - timestamp->day = tm->tm_mday; - timestamp->hour = tm->tm_hour; - timestamp->minute = tm->tm_min; - timestamp->second = tm->tm_sec; - timestamp->msecond = tv.tv_usec / 1000; -} - -static guint8 mxf_op_identification_ul[] = { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x0d, 0x01, 0x02, 0x01 -}; - -void -mxf_op_set_atom (MXFUL * ul, gboolean single_sourceclip, - gboolean single_essence_track) -{ - memcpy (&ul->u, &mxf_op_identification_ul, 12); - ul->u[12] = 0x10; - ul->u[13] = 0; - - if (!single_sourceclip) - ul->u[13] |= 0x80; - - if (!single_essence_track) - ul->u[13] |= 0x40; - - ul->u[14] = 0; - ul->u[15] = 0; -} - -void -mxf_op_set_generalized (MXFUL * ul, MXFOperationalPattern pattern, - gboolean internal_essence, gboolean streamable, gboolean single_track) -{ - g_return_if_fail (pattern >= MXF_OP_1a); - - memcpy (&ul->u, &mxf_op_identification_ul, 12); - - if (pattern == MXF_OP_1a || pattern == MXF_OP_1b || pattern == MXF_OP_1c) - ul->u[12] = 0x01; - else if (pattern == MXF_OP_2a || pattern == MXF_OP_2b || pattern == MXF_OP_2c) - ul->u[12] = 0x02; - else if (pattern == MXF_OP_3a || pattern == MXF_OP_3b || pattern == MXF_OP_3c) - ul->u[12] = 0x03; - - if (pattern == MXF_OP_1a || pattern == MXF_OP_2a || pattern == MXF_OP_3a) - ul->u[13] = 0x01; - else if (pattern == MXF_OP_1b || pattern == MXF_OP_2b || pattern == MXF_OP_3b) - ul->u[13] = 0x02; - else if (pattern == MXF_OP_1c || pattern == MXF_OP_2c || pattern == MXF_OP_3c) - ul->u[13] = 0x02; - - ul->u[14] = 0x80; - if (!internal_essence) - ul->u[14] |= 0x40; - if (!streamable) - ul->u[14] |= 0x20; - if (!single_track) - ul->u[14] |= 0x10; - - ul->u[15] = 0; -} - -static void -_mxf_mapping_ul_free (MXFUL * ul) -{ - g_slice_free (MXFUL, ul); -} - -guint16 -mxf_primer_pack_add_mapping (MXFPrimerPack * primer, guint16 local_tag, - const MXFUL * ul) -{ - MXFUL *uid; -#ifndef GST_DISABLE_GST_DEBUG - gchar str[48]; -#endif - - if (primer->mappings == NULL) { - primer->mappings = g_hash_table_new_full (g_direct_hash, g_direct_equal, - (GDestroyNotify) NULL, (GDestroyNotify) _mxf_mapping_ul_free); - } - - if (primer->reverse_mappings == NULL) { - primer->reverse_mappings = g_hash_table_new_full ((GHashFunc) mxf_ul_hash, - (GEqualFunc) mxf_ul_is_equal, (GDestroyNotify) _mxf_mapping_ul_free, - (GDestroyNotify) NULL); - } - - if (primer->next_free_tag == 0xffff && local_tag == 0) { - GST_ERROR ("Used too many dynamic tags"); - return 0; - } - - if (local_tag == 0) { - guint16 tmp; - - tmp = GPOINTER_TO_UINT (g_hash_table_lookup (primer->reverse_mappings, ul)); - if (tmp == 0) { - local_tag = primer->next_free_tag; - primer->next_free_tag++; - } - } else { - if (g_hash_table_lookup (primer->mappings, GUINT_TO_POINTER (local_tag))) - return local_tag; - } - - g_assert (local_tag != 0); - - uid = g_slice_new (MXFUL); - memcpy (uid, ul, 16); - - GST_DEBUG ("Adding mapping = 0x%04x -> %s", local_tag, - mxf_ul_to_string (uid, str)); - g_hash_table_insert (primer->mappings, GUINT_TO_POINTER (local_tag), uid); - uid = g_slice_dup (MXFUL, uid); - g_hash_table_insert (primer->reverse_mappings, uid, - GUINT_TO_POINTER (local_tag)); - - return local_tag; -} - -guint -mxf_ber_encode_size (guint size, guint8 ber[9]) -{ - guint8 slen, i; - guint8 tmp[8]; - - memset (ber, 0, 9); - - if (size <= 127) { - ber[0] = size; - return 1; - } else if (size > G_MAXUINT) { - return 0; - } - - slen = 0; - while (size > 0) { - tmp[slen] = size & 0xff; - size >>= 8; - slen++; - } - - ber[0] = 0x80 | slen; - for (i = 0; i < slen; i++) { - ber[i + 1] = tmp[slen - i - 1]; - } - - return slen + 1; -} - -void -mxf_timestamp_write (const MXFTimestamp * timestamp, guint8 * data) -{ - GST_WRITE_UINT16_BE (data, timestamp->year); - GST_WRITE_UINT8 (data + 2, timestamp->month); - GST_WRITE_UINT8 (data + 3, timestamp->day); - GST_WRITE_UINT8 (data + 4, timestamp->hour); - GST_WRITE_UINT8 (data + 5, timestamp->minute); - GST_WRITE_UINT8 (data + 6, timestamp->second); - GST_WRITE_UINT8 (data + 7, (timestamp->msecond * 256) / 1000); -} - -guint8 * -mxf_utf8_to_utf16 (const gchar * str, guint16 * size) -{ - guint8 *ret; - GError *error = NULL; - gsize s; - - g_return_val_if_fail (size != NULL, NULL); - - if (str == NULL) { - *size = 0; - return NULL; - } - - ret = (guint8 *) - g_convert_with_fallback (str, -1, "UTF-16BE", "UTF-8", "*", NULL, &s, - &error); - - if (ret == NULL) { - GST_WARNING ("UTF-16-BE to UTF-8 conversion failed: %s", error->message); - g_error_free (error); - *size = 0; - return NULL; - } - - *size = s; - return (guint8 *) ret; -} - -void -mxf_product_version_write (const MXFProductVersion * version, guint8 * data) -{ - GST_WRITE_UINT16_BE (data, version->major); - GST_WRITE_UINT16_BE (data + 2, version->minor); - GST_WRITE_UINT16_BE (data + 4, version->patch); - GST_WRITE_UINT16_BE (data + 6, version->build); - GST_WRITE_UINT16_BE (data + 8, version->release); -} - -GstBuffer * -mxf_partition_pack_to_buffer (const MXFPartitionPack * pack) -{ - guint slen; - guint8 ber[9]; - GstBuffer *ret; - guint8 *data; - guint i; - guint size = - 8 + 16 * pack->n_essence_containers + 16 + 4 + 8 + 4 + 8 + 8 + 8 + 8 + 8 + - 4 + 2 + 2; - - slen = mxf_ber_encode_size (size, ber); - - ret = gst_buffer_new_and_alloc (16 + slen + size); - memcpy (GST_BUFFER_DATA (ret), MXF_UL (PARTITION_PACK), 13); - if (pack->type == MXF_PARTITION_PACK_HEADER) - GST_BUFFER_DATA (ret)[13] = 0x02; - else if (pack->type == MXF_PARTITION_PACK_BODY) - GST_BUFFER_DATA (ret)[13] = 0x03; - else if (pack->type == MXF_PARTITION_PACK_FOOTER) - GST_BUFFER_DATA (ret)[13] = 0x04; - GST_BUFFER_DATA (ret)[14] = 0; - if (pack->complete) - GST_BUFFER_DATA (ret)[14] |= 0x02; - if (pack->closed) - GST_BUFFER_DATA (ret)[14] |= 0x01; - GST_BUFFER_DATA (ret)[14] += 1; - GST_BUFFER_DATA (ret)[15] = 0; - memcpy (GST_BUFFER_DATA (ret) + 16, &ber, slen); - - data = GST_BUFFER_DATA (ret) + 16 + slen; - - GST_WRITE_UINT16_BE (data, pack->major_version); - GST_WRITE_UINT16_BE (data + 2, pack->minor_version); - data += 4; - - GST_WRITE_UINT32_BE (data, pack->kag_size); - data += 4; - - GST_WRITE_UINT64_BE (data, pack->this_partition); - data += 8; - - GST_WRITE_UINT64_BE (data, pack->prev_partition); - data += 8; - - GST_WRITE_UINT64_BE (data, pack->footer_partition); - data += 8; - - GST_WRITE_UINT64_BE (data, pack->header_byte_count); - data += 8; - - GST_WRITE_UINT64_BE (data, pack->index_byte_count); - data += 8; - - GST_WRITE_UINT32_BE (data, pack->index_sid); - data += 4; - - GST_WRITE_UINT64_BE (data, pack->body_offset); - data += 8; - - GST_WRITE_UINT32_BE (data, pack->body_sid); - data += 4; - - memcpy (data, &pack->operational_pattern, 16); - data += 16; - - GST_WRITE_UINT32_BE (data, pack->n_essence_containers); - GST_WRITE_UINT32_BE (data + 4, 16); - data += 8; - - for (i = 0; i < pack->n_essence_containers; i++) - memcpy (data + 16 * i, &pack->essence_containers[i], 16); - - return ret; -} - -GstBuffer * -mxf_primer_pack_to_buffer (const MXFPrimerPack * pack) -{ - guint slen; - guint8 ber[9]; - GstBuffer *ret; - guint n; - guint8 *data; - - if (pack->mappings) - n = g_hash_table_size (pack->mappings); - else - n = 0; - - slen = mxf_ber_encode_size (8 + 18 * n, ber); - - ret = gst_buffer_new_and_alloc (16 + slen + 8 + 18 * n); - memcpy (GST_BUFFER_DATA (ret), MXF_UL (PRIMER_PACK), 16); - memcpy (GST_BUFFER_DATA (ret) + 16, &ber, slen); - - data = GST_BUFFER_DATA (ret) + 16 + slen; - - GST_WRITE_UINT32_BE (data, n); - GST_WRITE_UINT32_BE (data + 4, 18); - data += 8; - - if (pack->mappings) { - guint16 local_tag; - MXFUL *ul; -#if GLIB_CHECK_VERSION (2, 16, 0) - GHashTableIter iter; - - g_hash_table_iter_init (&iter, pack->mappings); -#else - GList *l, *values; - - keys = g_hash_table_get_keys (pack->mappings); -#endif - -#if GLIB_CHECK_VERSION (2, 16, 0) - while (g_hash_table_iter_next (&iter, (gpointer) & local_tag, - (gpointer) & ul)) { -#else - for (l = keys l; l = l->next) { - local_tag = GPOINTER_TO_GUINT (l->data); - ul = g_hash_table_lookup (pack->mappings, GUINT_TO_POINTER (local_tag)); -#endif - GST_WRITE_UINT16_BE (data, local_tag); - memcpy (data + 2, ul, 16); - data += 18; - } - -#if !GLIB_CHECK_VERSION (2, 16, 0) - g_list_free (keys); -#endif - } - - return ret; -} - -GstBuffer * -mxf_fill_new (guint size) -{ - GstBuffer *ret; - guint slen; - guint8 ber[9]; - - slen = mxf_ber_encode_size (size, ber); - - ret = gst_buffer_new_and_alloc (16 + slen + size); - memcpy (GST_BUFFER_DATA (ret), MXF_UL (FILL), 16); - memcpy (GST_BUFFER_DATA (ret) + 16, &ber, slen); - memset (GST_BUFFER_DATA (ret) + slen, 0, size); - - return ret; -} - -GstBuffer * -mxf_random_index_pack_to_buffer (const GArray * array) -{ - MXFRandomIndexPackEntry *entry; - guint i; - GstBuffer *ret; - guint8 slen, ber[9]; - guint size; - guint8 *data; - - if (array->len == 0) - return NULL; - - size = array->len * 12 + 4; - slen = mxf_ber_encode_size (size, ber); - ret = gst_buffer_new_and_alloc (16 + slen + size); - memcpy (GST_BUFFER_DATA (ret), MXF_UL (RANDOM_INDEX_PACK), 16); - memcpy (GST_BUFFER_DATA (ret) + 16, ber, slen); - - data = GST_BUFFER_DATA (ret) + 16 + slen; - - for (i = 0; i < array->len; i++) { - entry = &g_array_index (array, MXFRandomIndexPackEntry, i); - GST_WRITE_UINT32_BE (data, entry->body_sid); - GST_WRITE_UINT64_BE (data + 4, entry->offset); - data += 12; - } - GST_WRITE_UINT32_BE (data, GST_BUFFER_SIZE (ret)); - - return ret; -} |