Thanks Nicolas, I will update configure.ac accordingly. BR, Hugues. On 05/01/2017 07:37 PM, Nicolas Dufresne wrote: > Le vendredi 28 avril 2017 à 17:02 +0200, Hugues Fruchet a écrit : >> Add the mpeg2 codecparser backend glue which will >> call the GStreamer parsing functions. >> >> Signed-off-by: Hugues Fruchet <hugues.fruchet@xxxxxx> >> --- >> 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], > > You should only check for the codecparser library. The rest are > dependencies which will be pulled automatically by pkg-config. If for > some reason you needed multiple libs, that don't depend on each others, > notice the S in PKG_CHECK_MODULES. You can do a single invocation. > >> [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.fruchet@xxxxxx> >> + * Tifaine Inguere <tifaine.inguere@xxxxxx> >> + * 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_quanti >> zer_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.l >> oad_intra_quantiser_matrix; >> + memcpy(&seq_matrix_ext- >>> intra_quantiser_matrix, >> + &gst_seq_matrix_ext.i >> ntra_quantiser_matrix, >> + sizeof(seq_matrix_ext >> ->intra_quantiser_matrix)); >> + seq_matrix_ext- >>> load_non_intra_quantiser_matrix = >> + gst_seq_matrix_ext.l >> oad_non_intra_quantiser_matrix; >> + memcpy(&seq_matrix_ext- >>> non_intra_quantiser_matrix, >> + &gst_seq_matrix_ext.n >> on_intra_quantiser_matrix, >> + sizeof(seq_matrix_ext >> ->non_intra_quantiser_matrix)); >> + seq_matrix_ext- >>> load_chroma_intra_quantiser_matrix = >> + gst_seq_matrix_ext.l >> oad_chroma_intra_quantiser_matrix; >> + memcpy(&seq_matrix_ext- >>> chroma_intra_quantiser_matrix, >> + &gst_seq_matrix_ext.c >> hroma_intra_quantiser_matrix, >> + sizeof(seq_matrix_ext >> ->chroma_intra_quantiser_matrix)); >> + seq_matrix_ext- >>> load_chroma_non_intra_quantiser_matrix = >> + gst_seq_matrix_ext.l >> oad_chroma_non_intra_quantiser_matrix; >> + memcpy(&seq_matrix_ext- >>> chroma_non_intra_quantiser_matrix, >> + &gst_seq_matrix_ext.c >> hroma_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)