mpeg4videoparse: port to baseparse
This commit is contained in:
parent
49eeb43fe2
commit
afb5b28d66
@ -1,13 +1,13 @@
|
|||||||
|
|
||||||
plugin_LTLIBRARIES = libgstmpeg4videoparse.la
|
plugin_LTLIBRARIES = libgstmpeg4videoparse.la
|
||||||
|
|
||||||
libgstmpeg4videoparse_la_SOURCES = mpeg4videoparse.c
|
libgstmpeg4videoparse_la_SOURCES = mpeg4videoparse.c mpeg4parse.c
|
||||||
libgstmpeg4videoparse_la_CFLAGS = $(GST_CFLAGS)
|
libgstmpeg4videoparse_la_CFLAGS = $(GST_BASE_CFLAGS) $(GST_CFLAGS)
|
||||||
libgstmpeg4videoparse_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
|
libgstmpeg4videoparse_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
|
||||||
libgstmpeg4videoparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgstmpeg4videoparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
libgstmpeg4videoparse_la_LIBTOOLFLAGS = --tag=disable-static
|
libgstmpeg4videoparse_la_LIBTOOLFLAGS = --tag=disable-static
|
||||||
|
|
||||||
noinst_HEADERS = mpeg4videoparse.h
|
noinst_HEADERS = mpeg4videoparse.h mpeg4parse.h
|
||||||
|
|
||||||
Android.mk: Makefile.am $(BUILT_SOURCES)
|
Android.mk: Makefile.am $(BUILT_SOURCES)
|
||||||
androgenizer \
|
androgenizer \
|
||||||
|
290
gst/mpeg4videoparse/mpeg4parse.c
Normal file
290
gst/mpeg4videoparse/mpeg4parse.c
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
/* GStreamer MPEG4-2 video Parser
|
||||||
|
* Copyright (C) <2008> Mindfruit B.V.
|
||||||
|
* @author Sjoerd Simons <sjoerd@luon.net>
|
||||||
|
* Copyright (C) <2007> Julien Moutte <julien@fluendo.com>
|
||||||
|
*
|
||||||
|
* 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 "mpeg4parse.h"
|
||||||
|
|
||||||
|
#include <gst/base/gstbitreader.h>
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_EXTERN (mpeg4v_parse_debug);
|
||||||
|
#define GST_CAT_DEFAULT mpeg4v_parse_debug
|
||||||
|
|
||||||
|
|
||||||
|
#define GET_BITS(b, num, bits) G_STMT_START { \
|
||||||
|
if (!gst_bit_reader_get_bits_uint32(b, bits, num)) \
|
||||||
|
goto failed; \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
|
#define MARKER_BIT(b) G_STMT_START { \
|
||||||
|
guint32 i; \
|
||||||
|
GET_BITS(b, 1, &i); \
|
||||||
|
if (i != 0x1) \
|
||||||
|
goto failed; \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
next_start_code (GstBitReader * b)
|
||||||
|
{
|
||||||
|
guint32 bits;
|
||||||
|
|
||||||
|
GET_BITS (b, 1, &bits);
|
||||||
|
if (bits != 0)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
while (b->bit != 0) {
|
||||||
|
GET_BITS (b, 1, &bits);
|
||||||
|
if (bits != 0x1)
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
skip_user_data (GstBitReader * bs, guint32 * bits)
|
||||||
|
{
|
||||||
|
while (*bits == MPEG4_USER_DATA_STARTCODE_MARKER) {
|
||||||
|
guint32 b;
|
||||||
|
|
||||||
|
do {
|
||||||
|
GET_BITS (bs, 8, &b);
|
||||||
|
*bits = (*bits << 8) | b;
|
||||||
|
} while ((*bits >> 8) != MPEG4_START_MARKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gint aspect_ratio_table[6][2] = {
|
||||||
|
{-1, -1}, {1, 1}, {12, 11}, {10, 11}, {16, 11}, {40, 33}
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_mpeg4_params_parse_vo (MPEG4Params * params, GstBitReader * br)
|
||||||
|
{
|
||||||
|
guint32 bits;
|
||||||
|
guint16 time_increment_resolution = 0;
|
||||||
|
guint16 fixed_time_increment = 0;
|
||||||
|
gint aspect_ratio_width = -1, aspect_ratio_height = -1;
|
||||||
|
gint height = -1, width = -1;
|
||||||
|
|
||||||
|
/* expecting a video object startcode */
|
||||||
|
GET_BITS (br, 32, &bits);
|
||||||
|
if (bits > 0x11F)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
/* expecting a video object layer startcode */
|
||||||
|
GET_BITS (br, 32, &bits);
|
||||||
|
if (bits < 0x120 || bits > 0x12F)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
/* ignore random accessible vol and video object type indication */
|
||||||
|
GET_BITS (br, 9, &bits);
|
||||||
|
|
||||||
|
GET_BITS (br, 1, &bits);
|
||||||
|
if (bits) {
|
||||||
|
/* skip video object layer verid and priority */
|
||||||
|
GET_BITS (br, 7, &bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* aspect ratio info */
|
||||||
|
GET_BITS (br, 4, &bits);
|
||||||
|
if (bits == 0)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
/* check if aspect ratio info is extended par */
|
||||||
|
if (bits == 0xf) {
|
||||||
|
GET_BITS (br, 8, &bits);
|
||||||
|
aspect_ratio_width = bits;
|
||||||
|
GET_BITS (br, 8, &bits);
|
||||||
|
aspect_ratio_height = bits;
|
||||||
|
} else if (bits < 0x6) {
|
||||||
|
aspect_ratio_width = aspect_ratio_table[bits][0];
|
||||||
|
aspect_ratio_height = aspect_ratio_table[bits][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
GET_BITS (br, 1, &bits);
|
||||||
|
if (bits) {
|
||||||
|
/* vol control parameters, skip chroma and low delay */
|
||||||
|
GET_BITS (br, 3, &bits);
|
||||||
|
GET_BITS (br, 1, &bits);
|
||||||
|
if (bits) {
|
||||||
|
/* skip vbv_parameters */
|
||||||
|
GET_BITS (br, 79, &bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* layer shape */
|
||||||
|
GET_BITS (br, 2, &bits);
|
||||||
|
/* only support rectangular */
|
||||||
|
if (bits != 0)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
MARKER_BIT (br);
|
||||||
|
GET_BITS (br, 16, &bits);
|
||||||
|
time_increment_resolution = bits;
|
||||||
|
MARKER_BIT (br);
|
||||||
|
|
||||||
|
GST_DEBUG ("time increment resolution %d", time_increment_resolution);
|
||||||
|
|
||||||
|
GET_BITS (br, 1, &bits);
|
||||||
|
if (bits) {
|
||||||
|
/* fixed time increment */
|
||||||
|
int n;
|
||||||
|
|
||||||
|
/* Length of the time increment is the minimal number of bits needed to
|
||||||
|
* represent time_increment_resolution */
|
||||||
|
for (n = 0; (time_increment_resolution >> n) != 0; n++);
|
||||||
|
GET_BITS (br, n, &bits);
|
||||||
|
|
||||||
|
fixed_time_increment = bits;
|
||||||
|
} else {
|
||||||
|
/* When fixed_vop_rate is not set we can't guess any framerate */
|
||||||
|
fixed_time_increment = 0;
|
||||||
|
}
|
||||||
|
GST_DEBUG ("fixed time increment %d", fixed_time_increment);
|
||||||
|
|
||||||
|
/* assuming rectangular shape */
|
||||||
|
MARKER_BIT (br);
|
||||||
|
GET_BITS (br, 13, &bits);
|
||||||
|
width = bits;
|
||||||
|
MARKER_BIT (br);
|
||||||
|
GET_BITS (br, 13, &bits);
|
||||||
|
height = bits;
|
||||||
|
MARKER_BIT (br);
|
||||||
|
|
||||||
|
/* so we got it all, report back */
|
||||||
|
params->width = width;
|
||||||
|
params->height = height;
|
||||||
|
params->time_increment_resolution = time_increment_resolution;
|
||||||
|
params->fixed_time_increment = fixed_time_increment;
|
||||||
|
params->aspect_ratio_width = aspect_ratio_width;
|
||||||
|
params->aspect_ratio_height = aspect_ratio_height;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
failed:
|
||||||
|
{
|
||||||
|
GST_WARNING ("Failed to parse config data");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_mpeg4_params_parse_vos (MPEG4Params * params, GstBitReader * br)
|
||||||
|
{
|
||||||
|
guint32 bits;
|
||||||
|
|
||||||
|
GET_BITS (br, 32, &bits);
|
||||||
|
if (bits != MPEG4_VOS_STARTCODE_MARKER)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
GET_BITS (br, 8, &bits);
|
||||||
|
params->profile = bits;
|
||||||
|
|
||||||
|
/* invalid profile, warn but carry on */
|
||||||
|
if (params->profile == 0) {
|
||||||
|
GST_WARNING ("Invalid profile in VOS");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expect Visual Object startcode */
|
||||||
|
GET_BITS (br, 32, &bits);
|
||||||
|
|
||||||
|
/* but skip optional user data */
|
||||||
|
if (!skip_user_data (br, &bits))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
if (bits != MPEG4_VISUAL_OBJECT_STARTCODE_MARKER)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
GET_BITS (br, 1, &bits);
|
||||||
|
if (bits == 0x1) {
|
||||||
|
/* Skip visual_object_verid and priority */
|
||||||
|
GET_BITS (br, 7, &bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
GET_BITS (br, 4, &bits);
|
||||||
|
/* Only support video ID */
|
||||||
|
if (bits != 0x1)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
/* video signal type */
|
||||||
|
GET_BITS (br, 1, &bits);
|
||||||
|
|
||||||
|
if (bits == 0x1) {
|
||||||
|
/* video signal type, ignore format and range */
|
||||||
|
GET_BITS (br, 4, &bits);
|
||||||
|
|
||||||
|
GET_BITS (br, 1, &bits);
|
||||||
|
if (bits == 0x1) {
|
||||||
|
/* ignore color description */
|
||||||
|
GET_BITS (br, 24, &bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!next_start_code (br))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
/* skip optional user data */
|
||||||
|
GET_BITS (br, 32, &bits);
|
||||||
|
if (!skip_user_data (br, &bits))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
/* rewind to start code */
|
||||||
|
gst_bit_reader_set_pos (br, gst_bit_reader_get_pos (br) - 32);
|
||||||
|
|
||||||
|
return gst_mpeg4_params_parse_vo (params, br);
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
failed:
|
||||||
|
{
|
||||||
|
GST_WARNING ("Failed to parse config data");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_mpeg4_params_parse_config (MPEG4Params * params, const guint8 * data,
|
||||||
|
guint size)
|
||||||
|
{
|
||||||
|
GstBitReader br;
|
||||||
|
|
||||||
|
if (size < 4)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
gst_bit_reader_init (&br, data, size);
|
||||||
|
|
||||||
|
if (data[3] == MPEG4_VOS_STARTCODE)
|
||||||
|
return gst_mpeg4_params_parse_vos (params, &br);
|
||||||
|
else
|
||||||
|
return gst_mpeg4_params_parse_vo (params, &br);
|
||||||
|
}
|
63
gst/mpeg4videoparse/mpeg4parse.h
Normal file
63
gst/mpeg4videoparse/mpeg4parse.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* GStreamer MPEG4-2 video Parser
|
||||||
|
* Copyright (C) <2008> Mindfruit B.V.
|
||||||
|
* @author Sjoerd Simons <sjoerd@luon.net>
|
||||||
|
* Copyright (C) <2007> Julien Moutte <julien@fluendo.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GST_MPEG4_PARAMS_H__
|
||||||
|
#define __GST_MPEG4_PARAMS_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define MPEG4_VIDEO_OBJECT_STARTCODE_MIN 0x00
|
||||||
|
#define MPEG4_VIDEO_OBJECT_STARTCODE_MAX 0x1F
|
||||||
|
#define MPEG4_VOS_STARTCODE 0xB0
|
||||||
|
#define MPEG4_VOS_ENDCODE 0xB1
|
||||||
|
#define MPEG4_USER_DATA_STARTCODE 0xB2
|
||||||
|
#define MPEG4_GOP_STARTCODE 0xB3
|
||||||
|
#define MPEG4_VISUAL_OBJECT_STARTCODE 0xB5
|
||||||
|
#define MPEG4_VOP_STARTCODE 0xB6
|
||||||
|
|
||||||
|
#define MPEG4_START_MARKER 0x000001
|
||||||
|
#define MPEG4_VISUAL_OBJECT_STARTCODE_MARKER \
|
||||||
|
((MPEG4_START_MARKER << 8) + MPEG4_VISUAL_OBJECT_STARTCODE)
|
||||||
|
#define MPEG4_VOS_STARTCODE_MARKER \
|
||||||
|
((MPEG4_START_MARKER << 8) + MPEG4_VOS_STARTCODE)
|
||||||
|
#define MPEG4_USER_DATA_STARTCODE_MARKER \
|
||||||
|
((MPEG4_START_MARKER << 8) + MPEG4_USER_DATA_STARTCODE)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _MPEG4Params MPEG4Params;
|
||||||
|
|
||||||
|
struct _MPEG4Params
|
||||||
|
{
|
||||||
|
gint profile;
|
||||||
|
|
||||||
|
gint width, height;
|
||||||
|
gint aspect_ratio_width, aspect_ratio_height;
|
||||||
|
gint time_increment_resolution;
|
||||||
|
gint fixed_time_increment;
|
||||||
|
};
|
||||||
|
|
||||||
|
GstFlowReturn gst_mpeg4_params_parse_config (MPEG4Params * params,
|
||||||
|
const guint8 * data, guint size);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,9 @@
|
|||||||
#define __MPEG4VIDEOPARSE_H__
|
#define __MPEG4VIDEOPARSE_H__
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstadapter.h>
|
#include <gst/base/gstbaseparse.h>
|
||||||
|
|
||||||
|
#include "mpeg4parse.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -40,47 +42,30 @@ G_BEGIN_DECLS
|
|||||||
typedef struct _GstMpeg4VParse GstMpeg4VParse;
|
typedef struct _GstMpeg4VParse GstMpeg4VParse;
|
||||||
typedef struct _GstMpeg4VParseClass GstMpeg4VParseClass;
|
typedef struct _GstMpeg4VParseClass GstMpeg4VParseClass;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
PARSE_NEED_START,
|
|
||||||
PARSE_START_FOUND,
|
|
||||||
PARSE_VO_FOUND,
|
|
||||||
PARSE_VOS_FOUND,
|
|
||||||
PARSE_VOP_FOUND
|
|
||||||
} GstMpeg4VParseState;
|
|
||||||
|
|
||||||
struct _GstMpeg4VParse {
|
struct _GstMpeg4VParse {
|
||||||
GstElement element;
|
GstBaseParse element;
|
||||||
|
|
||||||
GstPad * sinkpad;
|
|
||||||
GstPad * srcpad;
|
|
||||||
|
|
||||||
GstCaps *sink_caps;
|
|
||||||
|
|
||||||
guint interval;
|
|
||||||
GstClockTime last_report;
|
GstClockTime last_report;
|
||||||
|
|
||||||
GstAdapter * adapter;
|
/* parse state */
|
||||||
guint offset;
|
gint last_sc;
|
||||||
guint vos_offset;
|
gint vop_offset;
|
||||||
|
gint vos_offset;
|
||||||
|
gint vo_offset;
|
||||||
gboolean intra_frame;
|
gboolean intra_frame;
|
||||||
|
gboolean update_caps;
|
||||||
GstMpeg4VParseState state;
|
|
||||||
GstClockTime timestamp;
|
|
||||||
|
|
||||||
GstBuffer *config;
|
GstBuffer *config;
|
||||||
gboolean have_config;
|
|
||||||
guint8 profile;
|
guint8 profile;
|
||||||
GstClockTime frame_duration;
|
MPEG4Params params;
|
||||||
|
|
||||||
|
/* properties */
|
||||||
gboolean drop;
|
gboolean drop;
|
||||||
|
guint interval;
|
||||||
gboolean have_src_caps;
|
|
||||||
GstEvent *pending_segment;
|
|
||||||
GList *pending_events;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstMpeg4VParseClass {
|
struct _GstMpeg4VParseClass {
|
||||||
GstElementClass parent_class;
|
GstBaseParseClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_mpeg4vparse_get_type (void);
|
GType gst_mpeg4vparse_get_type (void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user