Add the mpeg2 codecparser backend glue which will
call the GStreamer parsing functions.

Signed-off-by: Hugues Fruchet <hugues.fruc...@st.com>
---
 configure.ac                                    |  21 ++
 lib/libv4l-codecparsers/Makefile.am             |  14 +-
 lib/libv4l-codecparsers/libv4l-cparsers-mpeg2.c | 375 ++++++++++++++++++++++++
 lib/libv4l-codecparsers/libv4l-cparsers.c       |   4 +
 4 files changed, 413 insertions(+), 1 deletion(-)
 create mode 100644 lib/libv4l-codecparsers/libv4l-cparsers-mpeg2.c

diff --git a/configure.ac b/configure.ac
index 9ce7392..ce43f18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -273,6 +273,25 @@ fi
 
 AC_SUBST([JPEG_LIBS])
 
+# Check for GStreamer codecparsers
+
+gst_codecparsers_pkgconfig=false
+PKG_CHECK_MODULES([GST], [gstreamer-1.0 >= 1.8.0], [gst_pkgconfig=true], 
[gst_pkgconfig=false])
+if test "x$gst_pkgconfig" = "xfalse"; then
+   AC_MSG_WARN(GStreamer library is not available)
+else
+   PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-1.0 >= 1.8.0], 
[gst_base_pkgconfig=true], [gst_base_pkgconfig=false])
+   if test "x$gst_base_pkgconfig" = "xfalse"; then
+      AC_MSG_WARN(GStreamer base library is not available)
+   else
+      PKG_CHECK_MODULES(GST_CODEC_PARSERS, [gstreamer-codecparsers-1.0 >= 
1.8.0], [gst_codecparsers_pkgconfig=true], [gst_codecparsers_pkgconfig=false])
+      if test "x$gst_codecparsers_pkgconfig" = "xfalse"; then
+         AC_MSG_WARN(GStreamer codecparser library is not available)
+      fi
+   fi
+fi
+AM_CONDITIONAL([HAVE_GST_CODEC_PARSERS], [test x$gst_codecparsers_pkgconfig = 
xtrue])
+
 # Check for pthread
 
 AS_IF([test x$enable_shared != xno],
@@ -477,6 +496,7 @@ AM_COND_IF([WITH_V4L2_CTL_LIBV4L], [USE_V4L2_CTL="yes"], 
[USE_V4L2_CTL="no"])
 AM_COND_IF([WITH_V4L2_CTL_STREAM_TO], [USE_V4L2_CTL="yes"], 
[USE_V4L2_CTL="no"])
 AM_COND_IF([WITH_V4L2_COMPLIANCE_LIBV4L], [USE_V4L2_COMPLIANCE="yes"], 
[USE_V4L2_COMPLIANCE="no"])
 AS_IF([test "x$alsa_pkgconfig" = "xtrue"], [USE_ALSA="yes"], [USE_ALSA="no"])
+AS_IF([test "x$gst_codecparsers_pkgconfig" = "xtrue"], 
[USE_GST_CODECPARSERS="yes"], [USE_GST_CODECPARSERS="no"])
 
 AC_OUTPUT
 
@@ -497,6 +517,7 @@ compile time options summary
     pthread             : $have_pthread
     QT version          : $QT_VERSION
     ALSA support        : $USE_ALSA
+    GST codecparsers    : $USE_GST_CODECPARSERS
 
     build dynamic libs  : $enable_shared
     build static libs   : $enable_static
diff --git a/lib/libv4l-codecparsers/Makefile.am 
b/lib/libv4l-codecparsers/Makefile.am
index a9d6c8b..61f4730 100644
--- a/lib/libv4l-codecparsers/Makefile.am
+++ b/lib/libv4l-codecparsers/Makefile.am
@@ -1,9 +1,21 @@
 if WITH_V4L_PLUGINS
+if HAVE_GST_CODEC_PARSERS
+
 libv4l2plugin_LTLIBRARIES = libv4l-codecparsers.la
-endif
 
 libv4l_codecparsers_la_SOURCES = libv4l-cparsers.c libv4l-cparsers.h
 
 libv4l_codecparsers_la_CPPFLAGS = $(CFLAG_VISIBILITY) 
-I$(top_srcdir)/lib/libv4l2/ -I$(top_srcdir)/lib/libv4lconvert/
 libv4l_codecparsers_la_LDFLAGS = -avoid-version -module -shared 
-export-dynamic -lpthread
 libv4l_codecparsers_la_LIBADD = ../libv4l2/libv4l2.la
+
+# GStreamer codecparsers library
+libv4l_codecparsers_la_CFLAGS = $(GST_CFLAGS) -DGST_USE_UNSTABLE_API
+libv4l_codecparsers_la_LDFLAGS += $(GST_LIB_LDFLAGS)
+libv4l_codecparsers_la_LIBADD += $(GLIB_LIBS) $(GST_LIBS) $(GST_BASE_LIBS) 
$(GST_CODEC_PARSERS_LIBS) $(NULL)
+
+# MPEG-2 parser back-end
+libv4l_codecparsers_la_SOURCES += libv4l-cparsers-mpeg2.c
+
+endif
+endif
diff --git a/lib/libv4l-codecparsers/libv4l-cparsers-mpeg2.c 
b/lib/libv4l-codecparsers/libv4l-cparsers-mpeg2.c
new file mode 100644
index 0000000..3456b73
--- /dev/null
+++ b/lib/libv4l-codecparsers/libv4l-cparsers-mpeg2.c
@@ -0,0 +1,375 @@
+/*
+ * libv4l-cparsers-mpeg2.c
+ *
+ * Copyright (C) STMicroelectronics SA 2017
+ * Authors: Hugues Fruchet <hugues.fruc...@st.com>
+ *          Tifaine Inguere <tifaine.ingu...@st.com>
+ *          for STMicroelectronics.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335  USA
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "libv4l2.h"
+#include "libv4l2-priv.h"
+#include "libv4l-cparsers.h"
+
+#include <gst/codecparsers/gstmpegvideoparser.h>
+#include <gst/base/gstbitreader.h>
+
+/*
+ * parsing metadata ids and their associated control ids.
+ * keep in sync both enum and array, this is used to index metas[<meta id>]
+ */
+enum mpeg2_meta_id {
+       SEQ_HDR,
+       SEQ_EXT,
+       SEQ_DISPLAY_EXT,
+       SEQ_MATRIX_EXT,
+       PIC_HDR,
+       PIC_HDR1,/* 2nd field decoding of interlaced stream */
+       PIC_EXT,
+       PIC_EXT1,/* 2nd field decoding of interlaced stream */
+};
+
+static const struct v4l2_ext_control mpeg2_metas_store[] = {
+       {
+       .id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQ_HDR,
+       .size = sizeof(struct v4l2_mpeg_video_mpeg2_seq_hdr),
+       },
+       {
+       .id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQ_EXT,
+       .size = sizeof(struct v4l2_mpeg_video_mpeg2_seq_ext),
+       },
+       {
+       .id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQ_DISPLAY_EXT,
+       .size = sizeof(struct v4l2_mpeg_video_mpeg2_seq_display_ext),
+       },
+       {
+       .id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQ_MATRIX_EXT,
+       .size = sizeof(struct v4l2_mpeg_video_mpeg2_seq_matrix_ext),
+       },
+       {
+       .id = V4L2_CID_MPEG_VIDEO_MPEG2_PIC_HDR,
+       .size = sizeof(struct v4l2_mpeg_video_mpeg2_pic_hdr),
+       },
+       {/* 2nd field decoding of interlaced stream */
+       .id = V4L2_CID_MPEG_VIDEO_MPEG2_PIC_HDR,
+       .size = sizeof(struct v4l2_mpeg_video_mpeg2_pic_hdr),
+       },
+       {
+       .id = V4L2_CID_MPEG_VIDEO_MPEG2_PIC_EXT,
+       .size = sizeof(struct v4l2_mpeg_video_mpeg2_pic_ext),
+       },
+       {/* 2nd field decoding of interlaced stream */
+       .id = V4L2_CID_MPEG_VIDEO_MPEG2_PIC_EXT,
+       .size = sizeof(struct v4l2_mpeg_video_mpeg2_pic_ext),
+       },
+};
+
+guint8 get_extension_code(const GstMpegVideoPacket *packet)
+{
+       GstBitReader br;
+       unsigned char extension_code;
+
+       gst_bit_reader_init(&br, &packet->data[packet->offset], packet->size);
+       if (!gst_bit_reader_get_bits_uint8(&br, &extension_code, 4)) {
+               V4L2_LOG_ERR("failed to read extension code");
+               return GST_MPEG_VIDEO_PACKET_NONE;
+       }
+
+       return extension_code;
+}
+
+unsigned int mpeg2_parse_metas(struct cparsers_au *au,
+                              struct v4l2_ext_control *metas,
+                              unsigned int *nb_of_metas)
+{
+       unsigned char extension_code;
+       bool startcode_found = false;
+       bool meta_found = false;
+       GstMpegVideoPacket packet_data;
+       unsigned int slice_index = 0;
+       GstMpegVideoSequenceHdr gst_seq_hdr;
+       GstMpegVideoSequenceExt gst_seq_ext;
+       GstMpegVideoSequenceDisplayExt gst_seq_display_ext;
+       GstMpegVideoQuantMatrixExt gst_seq_matrix_ext;
+       GstMpegVideoPictureHdr gst_pic_hdr;
+       GstMpegVideoPictureExt gst_pic_ext;
+       struct v4l2_mpeg_video_mpeg2_seq_hdr *seq_hdr;
+       struct v4l2_mpeg_video_mpeg2_seq_ext *seq_ext;
+       struct v4l2_mpeg_video_mpeg2_seq_display_ext *seq_display_ext;
+       struct v4l2_mpeg_video_mpeg2_seq_matrix_ext *seq_matrix_ext;
+       struct v4l2_mpeg_video_mpeg2_pic_hdr *pic_hdrs[2];
+       struct v4l2_mpeg_video_mpeg2_pic_ext *pic_exts[2];
+
+       if ((!au->addr) || (!au->bytesused) || (!au->metas_store) || (!metas)) {
+               V4L2_LOG_ERR("%s: invalid input: au->addr=%p, au->bytesused=%d, 
au->metas_store=%p, metas=%p\n",
+                            __func__, au->addr, au->bytesused, 
au->metas_store, metas);
+               return 0;
+       }
+
+       seq_hdr = au->metas_store[SEQ_HDR].ptr;
+       seq_ext = au->metas_store[SEQ_EXT].ptr;
+       seq_display_ext = au->metas_store[SEQ_DISPLAY_EXT].ptr;
+       seq_matrix_ext = au->metas_store[SEQ_MATRIX_EXT].ptr;
+       pic_hdrs[0] = au->metas_store[PIC_HDR].ptr;
+       pic_hdrs[1] = au->metas_store[PIC_HDR + 1].ptr;
+       pic_exts[0] = au->metas_store[PIC_EXT].ptr;
+       pic_exts[1] = au->metas_store[PIC_EXT + 1].ptr;
+
+       memset(&packet_data, 0, sizeof(packet_data));
+
+       while (((packet_data.offset + 4) < au->bytesused)) {
+               V4L2_LOG("%s: parsing input from offset=%d\n", __func__,
+                        packet_data.offset);
+               startcode_found = gst_mpeg_video_parse(&packet_data, au->addr, 
au->bytesused, packet_data.offset);
+               if (!startcode_found) {
+                       V4L2_LOG("%s: parsing is over\n", __func__);
+                       break;
+               }
+               /*
+                * gst_mpeg_video_parse compute packet size by searching for 
next
+                * startcode, but if next startcode is not found (end of access 
unit),
+                * packet size is set to -1. We fix this here and set packet 
size
+                * to remaining size in this case.
+                */
+               if (packet_data.size < 0)
+                       packet_data.size = au->bytesused - packet_data.offset;
+
+               V4L2_LOG("%s: found startcode 0x%02x @offset=%u, size=%d\n",
+                        __func__, packet_data.type, packet_data.offset - 4, 
packet_data.size);
+
+               switch (packet_data.type) {
+               case GST_MPEG_VIDEO_PACKET_PICTURE:
+                       if (gst_mpeg_video_packet_parse_picture_header
+                           (&packet_data, &gst_pic_hdr)) {
+                               struct v4l2_mpeg_video_mpeg2_pic_hdr *pic_hdr = 
pic_hdrs[slice_index];
+
+                               metas[(*nb_of_metas)++] = 
au->metas_store[PIC_HDR + slice_index];
+
+                               memset(pic_hdr, 0, sizeof(*pic_hdr));
+                               pic_hdr->tsn = gst_pic_hdr.tsn;
+                               pic_hdr->pic_type = gst_pic_hdr.pic_type;
+                               pic_hdr->full_pel_forward_vector = 
gst_pic_hdr.full_pel_forward_vector;
+                               pic_hdr->full_pel_backward_vector = 
gst_pic_hdr.full_pel_backward_vector;
+                               memcpy(&pic_hdr->f_code, &gst_pic_hdr.f_code, 
sizeof(pic_hdr->f_code));
+
+                               V4L2_LOG("%s: PICTURE HEADER\n", __func__);
+                               meta_found = true;
+                       }
+                       break;
+
+               case GST_MPEG_VIDEO_PACKET_SLICE_MIN:
+                       /* New slice encountered */
+                       if (slice_index > 1) {
+                               V4L2_LOG_ERR("%s: more than 2 slices detected 
@offset=%d, ignoring this slice...\n",
+                                            __func__, packet_data.offset);
+                               break;
+                       }
+                       /* store its offset, including startcode */
+                       pic_hdrs[slice_index]->offset = packet_data.offset - 4;
+                       slice_index++;
+
+                       V4L2_LOG("%s: START OF SLICE @ offset=%d\n", __func__, 
packet_data.offset);
+                       meta_found = true;
+                       goto done;
+
+                       break;
+
+               case GST_MPEG_VIDEO_PACKET_USER_DATA:
+                       /* not implemented : do nothing */
+                       V4L2_LOG("%s: USER DATA, not implemented\n", __func__);
+                       break;
+
+               case GST_MPEG_VIDEO_PACKET_SEQUENCE:
+                       if (gst_mpeg_video_packet_parse_sequence_header
+                           (&packet_data, &gst_seq_hdr)) {
+                               metas[(*nb_of_metas)++] = 
au->metas_store[SEQ_HDR];
+
+                               memset(seq_hdr, 0, sizeof(*seq_hdr));
+                               seq_hdr->width = gst_seq_hdr.width;
+                               seq_hdr->height = gst_seq_hdr.height;
+                               seq_hdr->load_intra_quantiser_matrix = 1;
+                               memcpy(&seq_hdr->intra_quantiser_matrix,
+                                      &gst_seq_hdr.intra_quantizer_matrix,
+                                      sizeof(seq_hdr->intra_quantiser_matrix));
+                               seq_hdr->load_non_intra_quantiser_matrix = 1;
+                               memcpy(&seq_hdr->non_intra_quantiser_matrix,
+                                      &gst_seq_hdr.non_intra_quantizer_matrix,
+                                      
sizeof(seq_hdr->non_intra_quantiser_matrix));
+
+                               V4L2_LOG("%s: SEQUENCE HEADER\n", __func__);
+                               meta_found = true;
+                       }
+                       break;
+
+               case GST_MPEG_VIDEO_PACKET_EXTENSION:
+                       extension_code = get_extension_code(&packet_data);
+                       V4L2_LOG("%s: extension code=0x%02x  \n", __func__, 
extension_code);
+
+                       switch (extension_code) {
+                       case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE:
+                               if 
(gst_mpeg_video_packet_parse_sequence_extension
+                                   (&packet_data, &gst_seq_ext)) {
+                                       metas[(*nb_of_metas)++] = 
au->metas_store[SEQ_EXT];
+
+                                       memset(seq_ext, 0, sizeof(*seq_ext));
+                                       seq_ext->profile = gst_seq_ext.profile;
+                                       seq_ext->level = gst_seq_ext.level;
+                                       seq_ext->progressive = 
gst_seq_ext.progressive;
+                                       seq_ext->chroma_format = 
gst_seq_ext.chroma_format;
+                                       seq_ext->horiz_size_ext = 
gst_seq_ext.horiz_size_ext;
+                                       seq_ext->vert_size_ext = 
gst_seq_ext.vert_size_ext;
+
+                                       V4L2_LOG("%s: SEQUENCE EXTENSION\n", 
__func__);
+                                       meta_found = true;
+                               }
+                               break;
+
+                       case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY:
+                               if 
(gst_mpeg_video_packet_parse_sequence_display_extension
+                                   (&packet_data, &gst_seq_display_ext)) {
+                                       metas[(*nb_of_metas)++] = 
au->metas_store[SEQ_DISPLAY_EXT];
+
+                                       memset(seq_display_ext, 0, 
sizeof(*seq_display_ext));
+                                       seq_display_ext->video_format = 
gst_seq_display_ext.video_format;
+                                       
seq_display_ext->colour_description_flag = 
gst_seq_display_ext.colour_description_flag;
+                                       seq_display_ext->colour_primaries = 
gst_seq_display_ext.colour_primaries;
+                                       
seq_display_ext->transfer_characteristics = 
gst_seq_display_ext.transfer_characteristics;
+                                       seq_display_ext->matrix_coefficients = 
gst_seq_display_ext.matrix_coefficients;
+                                       
seq_display_ext->display_horizontal_size = 
gst_seq_display_ext.display_horizontal_size;
+                                       seq_display_ext->display_vertical_size 
= gst_seq_display_ext.display_vertical_size;
+
+                                       V4L2_LOG("%s: SEQUENCE DISPLAY 
EXTENSION\n", __func__);
+                                       meta_found = true;
+                               }
+                               break;
+
+                       case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX:
+                               if 
(gst_mpeg_video_packet_parse_quant_matrix_extension
+                                   (&packet_data, &gst_seq_matrix_ext)) {
+                                       metas[(*nb_of_metas)++] = 
au->metas_store[SEQ_DISPLAY_EXT];
+
+                                       memset(seq_matrix_ext, 0, 
sizeof(*seq_matrix_ext));
+                                       
seq_matrix_ext->load_intra_quantiser_matrix =
+                                               
gst_seq_matrix_ext.load_intra_quantiser_matrix;
+                                       
memcpy(&seq_matrix_ext->intra_quantiser_matrix,
+                                              
&gst_seq_matrix_ext.intra_quantiser_matrix,
+                                              
sizeof(seq_matrix_ext->intra_quantiser_matrix));
+                                       
seq_matrix_ext->load_non_intra_quantiser_matrix =
+                                               
gst_seq_matrix_ext.load_non_intra_quantiser_matrix;
+                                       
memcpy(&seq_matrix_ext->non_intra_quantiser_matrix,
+                                              
&gst_seq_matrix_ext.non_intra_quantiser_matrix,
+                                              
sizeof(seq_matrix_ext->non_intra_quantiser_matrix));
+                                       
seq_matrix_ext->load_chroma_intra_quantiser_matrix =
+                                               
gst_seq_matrix_ext.load_chroma_intra_quantiser_matrix;
+                                       
memcpy(&seq_matrix_ext->chroma_intra_quantiser_matrix,
+                                              
&gst_seq_matrix_ext.chroma_intra_quantiser_matrix,
+                                              
sizeof(seq_matrix_ext->chroma_intra_quantiser_matrix));
+                                       
seq_matrix_ext->load_chroma_non_intra_quantiser_matrix =
+                                               
gst_seq_matrix_ext.load_chroma_non_intra_quantiser_matrix;
+                                       
memcpy(&seq_matrix_ext->chroma_non_intra_quantiser_matrix,
+                                              
&gst_seq_matrix_ext.chroma_non_intra_quantiser_matrix,
+                                              
sizeof(seq_matrix_ext->chroma_non_intra_quantiser_matrix));
+
+                                       V4L2_LOG("%s: SEQUENCE MATRIX 
EXTENSION\n", __func__);
+                                       meta_found = true;
+                               }
+                               break;
+
+                       case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE:
+                               /* not implemented : do nothing */
+                               V4L2_LOG("%s: SEQUENCE SCALABLE EXTENSION, not 
implemented\n", __func__);
+                               break;
+
+                       case GST_MPEG_VIDEO_PACKET_EXT_PICTURE:
+                               if 
(gst_mpeg_video_packet_parse_picture_extension
+                                   (&packet_data, &gst_pic_ext)) {
+                                       struct v4l2_mpeg_video_mpeg2_pic_ext 
*pic_ext = pic_exts[slice_index];
+
+                                       metas[(*nb_of_metas)++] = 
au->metas_store[PIC_EXT + slice_index];
+
+                                       memset(pic_ext, 0, sizeof(*pic_ext));
+                                       memcpy(&pic_ext->f_code, 
&gst_pic_ext.f_code, sizeof(pic_ext->f_code));
+                                       pic_ext->intra_dc_precision = 
gst_pic_ext.intra_dc_precision;
+                                       pic_ext->picture_structure = 
gst_pic_ext.picture_structure;
+                                       pic_ext->top_field_first = 
gst_pic_ext.top_field_first;
+                                       pic_ext->frame_pred_frame_dct = 
gst_pic_ext.frame_pred_frame_dct;
+                                       pic_ext->concealment_motion_vectors = 
gst_pic_ext.concealment_motion_vectors;
+                                       pic_ext->q_scale_type = 
gst_pic_ext.q_scale_type;
+                                       pic_ext->intra_vlc_format = 
gst_pic_ext.intra_vlc_format;
+                                       pic_ext->alternate_scan = 
gst_pic_ext.alternate_scan;
+                                       pic_ext->repeat_first_field = 
gst_pic_ext.repeat_first_field;
+                                       pic_ext->chroma_420_type = 
gst_pic_ext.chroma_420_type;
+                                       pic_ext->progressive_frame = 
gst_pic_ext.progressive_frame;
+                                       pic_ext->composite_display = 
gst_pic_ext.composite_display;
+                                       pic_ext->v_axis = gst_pic_ext.v_axis;
+                                       pic_ext->field_sequence = 
gst_pic_ext.field_sequence;
+                                       pic_ext->sub_carrier = 
gst_pic_ext.sub_carrier;
+                                       pic_ext->burst_amplitude = 
gst_pic_ext.burst_amplitude;
+                                       pic_ext->sub_carrier_phase = 
gst_pic_ext.sub_carrier_phase;
+
+                                       V4L2_LOG("%s: PICTURE EXTENSION, 
top_field_first=%d\n",
+                                                __func__, 
pic_exts[slice_index]->top_field_first);
+                                       meta_found = true;
+                               }
+                               break;
+
+                       default:
+                               break;
+                       }
+                       break;
+
+               case GST_MPEG_VIDEO_PACKET_SEQUENCE_END:
+                       V4L2_LOG("%s: END OF PACKET SEQUENCE\n", __func__);
+                       break;
+
+               case GST_MPEG_VIDEO_PACKET_GOP:
+                       V4L2_LOG("%s: GOP\n", __func__);
+                       break;
+
+               default:
+                       V4L2_LOG("%s: unknown/unsupported header %02x\n",
+                                __func__, packet_data.type);
+                       break;
+               }
+       }
+
+done:
+       return meta_found;
+}
+
+const struct meta_parser mpeg2parse = {
+       .name = "mpeg2",
+       .streamformat = V4L2_PIX_FMT_MPEG2,
+       .parsedformat = V4L2_PIX_FMT_MPEG2_PARSED,
+       .nb_of_metas = sizeof(mpeg2_metas_store) / sizeof(mpeg2_metas_store[0]),
+       .metas_store = mpeg2_metas_store,
+       .parse_metas = mpeg2_parse_metas,
+};
+
+const struct meta_parser mpeg1parse = {
+       .name = "mpeg1",
+       .streamformat = V4L2_PIX_FMT_MPEG1,
+       .parsedformat = V4L2_PIX_FMT_MPEG1_PARSED,
+       .nb_of_metas = sizeof(mpeg2_metas_store) / sizeof(mpeg2_metas_store[0]),
+       .metas_store = mpeg2_metas_store,
+       .parse_metas = mpeg2_parse_metas,
+};
diff --git a/lib/libv4l-codecparsers/libv4l-cparsers.c 
b/lib/libv4l-codecparsers/libv4l-cparsers.c
index af59f50..4e8ae31 100644
--- a/lib/libv4l-codecparsers/libv4l-cparsers.c
+++ b/lib/libv4l-codecparsers/libv4l-cparsers.c
@@ -46,7 +46,11 @@
 #endif
 
 /* available parsers */
+extern const struct meta_parser mpeg1parse;
+extern const struct meta_parser mpeg2parse;
 const struct meta_parser *parsers[] = {
+       &mpeg1parse,
+       &mpeg2parse,
 };
 
 static void *plugin_init(int fd)
-- 
1.9.1

Reply via email to