From 89a57e67b0b062708968b8f9b5aaeecd366a222e Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 15 Feb 2018 13:59:56 +0100 Subject: WIP ancillary support MORE WIP WIP MORE fixups --- gst-libs/gst/video/Makefile.am | 3 + gst-libs/gst/video/video-anc.h | 76 ++++++++++++++++++ gst-libs/gst/video/video-vbi.c | 178 +++++++++++++++++++++++++++++++++++++++++ gst-libs/gst/video/video-vbi.h | 52 ++++++++++++ 4 files changed, 309 insertions(+) create mode 100644 gst-libs/gst/video/video-anc.h create mode 100644 gst-libs/gst/video/video-vbi.c create mode 100644 gst-libs/gst/video/video-vbi.h diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index 49d52b8e6..79b420c94 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -33,6 +33,7 @@ libgstvideo_@GST_API_VERSION@_la_SOURCES = \ video-frame.c \ video-scaler.c \ video-tile.c \ + video-vbi.c \ gstvideosink.c \ gstvideofilter.c \ convertframe.c \ @@ -60,6 +61,7 @@ libgstvideo_@GST_API_VERSION@include_HEADERS = \ colorbalancechannel.h \ navigation.h \ video.h \ + video-anc.h \ video-event.h \ video-format.h \ video-chroma.h \ @@ -70,6 +72,7 @@ libgstvideo_@GST_API_VERSION@include_HEADERS = \ video-frame.h \ video-scaler.h \ video-tile.h \ + video-vbi.h \ gstvideosink.h \ gstvideofilter.h \ gstvideometa.h \ diff --git a/gst-libs/gst/video/video-anc.h b/gst-libs/gst/video/video-anc.h new file mode 100644 index 000000000..274245b0c --- /dev/null +++ b/gst-libs/gst/video/video-anc.h @@ -0,0 +1,76 @@ +/* GStreamer + * Copyright (C) <2018> Edward Hervey + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GST_VIDEO_ANC_H__ +#define __GST_VIDEO_ANC_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GstVideoAncillary GstVideoAncillary; + +/** + * GstVideoAncillary: + * @DID: The Data Identifier + * @SDID_block_number: The Secondary Data Identifier (if type 2) or the Data + * Block Number (if type 2) + * @data_count: The amount of data (in bytes) in @data (max 255 bytes) + * @data: The content of the Ancillary packet in 16bit. Contains everything + * including the ADF, DID, SDI, DC, user words and CS. (the size + * is therefore @data_count + 4) + * + * Video Ancillary data, according to SMPTE-291M specification. + * */ +struct _GstVideoAncillary { + guint8 DID; + guint8 SDID_block_number; + guint8 data_count; + guint16 *data; + + /*< private >*/ + /* Padding for future extension */ + gpointer _gst_reserved[GST_PADDING]; +}; + +typedef enum { + GST_VIDEO_ANCILLARY_DID_UNDEFINED = 0x00, + GST_VIDEO_ANCILLARY_DID_DELETION = 0x80, + GST_VIDEO_ANCILLARY_DID_HANC_3G_AUDIO_DATA_FIRST = 0xa0, + GST_VIDEO_ANCILLARY_DID_HANC_3G_AUDIO_DATA_LAST = 0xa7, + GST_VIDEO_ANCILLARY_DID_HANC_HDTV_AUDIO_DATA_FIRST = 0xe0, + GST_VIDEO_ANCILLARY_DID_HANC_HDTV_AUDIO_DATA_LAST = 0xe7, + GST_VIDEO_ANCILLARY_DID_HANC_SDTV_AUDIO_DATA_1_FIRST = 0xec, + GST_VIDEO_ANCILLARY_DID_HANC_SDTV_AUDIO_DATA_1_LAST = 0xef, + GST_VIDEO_ANCILLARY_DID_CAMERA_POSITION = 0xf0, + GST_VIDEO_ANCILLARY_DID_HANC_ERROR_DETECTION = 0xf4, + GST_VIDEO_ANCILLARY_DID_HANC_SDTV_AUDIO_DATA_2_FIRST = 0xf8, + GST_VIDEO_ANCILLARY_DID_HANC_SDTV_AUDIO_DATA_2_LAST = 0xff, +} GstVideoAncillaryDID; + +#define GST_VIDEO_ANCILLARY_DID16(anc) ((guint16)(anc->DID) << 8 | (guint16)(anc->SDID_block_number) + +typedef enum { + GST_VIDEO_ANCILLARY_DID16_S334_EIA_708 = 0x6101, + GST_VIDEO_ANCILLARY_DID16_S334_EIA_608 = 0x6102, +} GstVideoAncillaryDID16; + +G_END_DECLS + +#endif /* __GST_VIDEO_ANC_H__ */ diff --git a/gst-libs/gst/video/video-vbi.c b/gst-libs/gst/video/video-vbi.c new file mode 100644 index 000000000..37cb9db95 --- /dev/null +++ b/gst-libs/gst/video/video-vbi.c @@ -0,0 +1,178 @@ +/* GStreamer + * Copyright (C) 2018 Edward Hervey + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "video-vbi.h" + +#ifndef GST_DISABLE_GST_DEBUG +#define GST_CAT_DEFAULT ensure_debug_category() +static GstDebugCategory * +ensure_debug_category (void) +{ + static gsize cat_gonce = 0; + + if (g_once_init_enter (&cat_gonce)) { + gsize cat_done; + + cat_done = (gsize) _gst_debug_category_new ("video-vbi", 0, + "video VBI parser"); + + g_once_init_leave (&cat_gonce, cat_done); + } + + return (GstDebugCategory *) cat_gonce; +} +#else +#define ensure_debug_category() /* NOOP */ +#endif /* GST_DISABLE_GST_DEBUG */ + +struct _GstVideoVBIParser +{ + GstVideoInfo info; /* format of the lines provided */ + guint16 *work_data; /* Converted line in 16bit format */ + guint32 work_data_size; /* Size (in guint16) of work_data */ + guint offset; /* Current offset (in guint16) in work_data */ +}; + +GstVideoVBIParserResult +gst_video_vbi_parser_get_ancillary (GstVideoVBIParser * parser, + GstVideoAncillary * anc) +{ + return GST_VIDEO_VBI_PARSER_RESULT_DONE; +} + +GstVideoVBIParser * +gst_video_vbi_parser_new (GstVideoFormat format, guint32 pixel_width) +{ + GstVideoVBIParser *parser; + + switch (format) { + case GST_VIDEO_FORMAT_v210: + parser = g_new0 (GstVideoVBIParser, 1); + break; + default: + GST_WARNING ("Format not supported by GstVideoVBIParser"); + return NULL; + } + + gst_video_info_init (&parser->info); + if (!gst_video_info_set_format (&parser->info, format, pixel_width, 1)) { + GST_ERROR ("Could not create GstVideoInfo"); + g_free (parser); + return NULL; + } + + /* Allocate the workspace which is going to be 2 * pixel_width * data big */ + parser->work_data_size = 2 * pixel_width; + parser->work_data = g_new0 (guint16, parser->work_data_size); + parser->offset = 0; + + return parser; +} + +void +gst_video_vbi_parser_free (GstVideoVBIParser * parser) +{ + g_free (parser->work_data); + g_free (parser); +} + +static void +gst_info_dump_mem16_line (gchar * linebuf, gsize linebuf_size, + const guint16 * mem, gsize mem_offset, gsize mem_size) +{ + gchar hexstr[50], digitstr[6]; + + if (mem_size > 8) + mem_size = 8; + + hexstr[0] = '\0'; + + if (mem != NULL) { + guint i = 0; + + mem += mem_offset; + while (i < mem_size) { + g_snprintf (digitstr, sizeof (digitstr), "%04x ", mem[i]); + g_strlcat (hexstr, digitstr, sizeof (hexstr)); + ++i; + } + } + + g_snprintf (linebuf, linebuf_size, "%08x: %-48.48s", + (guint) mem_offset, hexstr); +} + + +void +gst_video_vbi_parser_add_line (GstVideoVBIParser * parser, const guint8 * data) +{ + guint i; + guint16 *y = parser->work_data; + guint16 *uv = y + parser->info.width; + guint32 a, b, c, d; + + parser->offset = 0; + + /* Convert the line \o/ */ + for (i = 0; i < parser->info.width - 5; i += 6) { + a = GST_READ_UINT32_LE (data + (i / 6) * 16 + 0); + b = GST_READ_UINT32_LE (data + (i / 6) * 16 + 4); + c = GST_READ_UINT32_LE (data + (i / 6) * 16 + 8); + d = GST_READ_UINT32_LE (data + (i / 6) * 16 + 12); + + *uv++ = (a >> 0) & 0x3ff; + *y++ = (a >> 10) & 0x3ff; + *uv++ = (a >> 20) & 0x3ff; + *y++ = (b >> 0) & 0x3ff; + + *uv++ = (b >> 10) & 0x3ff; + *y++ = (b >> 20) & 0x3ff; + *uv++ = (c >> 0) & 0x3ff; + *y++ = (c >> 10) & 0x3ff; + + *uv++ = (c >> 20) & 0x3ff; + *y++ = (d >> 0) & 0x3ff; + *uv++ = (d >> 10) & 0x3ff; + *y++ = (d >> 20) & 0x3ff; + } + if (1) { + guint off = 0; + gsize length = parser->info.width * 2; + + GST_TRACE ("--------" + "-------------------------------------------------------------------"); + + while (off < length) { + gchar buf[128]; + + /* gst_info_dump_mem_line will process 16 bytes (8 16bit chunks) at most */ + gst_info_dump_mem16_line (buf, sizeof (buf), parser->work_data, off, + length - off); + GST_TRACE ("%s", buf); + off += 8; + } + GST_TRACE ("--------" + "-------------------------------------------------------------------"); + } +} diff --git a/gst-libs/gst/video/video-vbi.h b/gst-libs/gst/video/video-vbi.h new file mode 100644 index 000000000..5d50c9163 --- /dev/null +++ b/gst-libs/gst/video/video-vbi.h @@ -0,0 +1,52 @@ +/* GStreamer + * Copyright (C) <2018> Edward Hervey + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GST_VIDEO_VBI_H__ +#define __GST_VIDEO_VBI_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _GstVideoVBIParser GstVideoVBIParser; + +typedef enum { + GST_VIDEO_VBI_PARSER_RESULT_DONE = 0, /* No lines provided or no more ANC detected */ + GST_VIDEO_VBI_PARSER_RESULT_OK = 1, /* ANC parsed. there might be more */ + GST_VIDEO_VBI_PARSER_RESULT_ERROR = 2 /* An error occured */ +} GstVideoVBIParserResult; + +GST_EXPORT +GstVideoVBIParserResult gst_video_vbi_parser_get_ancillary(GstVideoVBIParser *parser, + GstVideoAncillary *anc); + +GST_EXPORT +GstVideoVBIParser *gst_video_vbi_parser_new (GstVideoFormat format, guint32 pixel_width); + +GST_EXPORT +void gst_video_vbi_parser_free (GstVideoVBIParser *parser); + +GST_EXPORT +void gst_video_vbi_parser_add_line (GstVideoVBIParser *parser, const guint8 *data); + +G_END_DECLS + +#endif /* __GST_VIDEO_VBI_H__ */ -- cgit v1.2.3