mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
mpeg4videoparse: port to baseparse
This commit is contained in:
parent
49eeb43fe2
commit
afb5b28d66
5 changed files with 817 additions and 967 deletions
|
@ -1,13 +1,13 @@
|
|||
|
||||
plugin_LTLIBRARIES = libgstmpeg4videoparse.la
|
||||
|
||||
libgstmpeg4videoparse_la_SOURCES = mpeg4videoparse.c
|
||||
libgstmpeg4videoparse_la_CFLAGS = $(GST_CFLAGS)
|
||||
libgstmpeg4videoparse_la_SOURCES = mpeg4videoparse.c mpeg4parse.c
|
||||
libgstmpeg4videoparse_la_CFLAGS = $(GST_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
libgstmpeg4videoparse_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
|
||||
libgstmpeg4videoparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
libgstmpeg4videoparse_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
noinst_HEADERS = mpeg4videoparse.h
|
||||
noinst_HEADERS = mpeg4videoparse.h mpeg4parse.h
|
||||
|
||||
Android.mk: Makefile.am $(BUILT_SOURCES)
|
||||
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__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
#include <gst/base/gstbaseparse.h>
|
||||
|
||||
#include "mpeg4parse.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -40,47 +42,30 @@ G_BEGIN_DECLS
|
|||
typedef struct _GstMpeg4VParse GstMpeg4VParse;
|
||||
typedef struct _GstMpeg4VParseClass GstMpeg4VParseClass;
|
||||
|
||||
typedef enum {
|
||||
PARSE_NEED_START,
|
||||
PARSE_START_FOUND,
|
||||
PARSE_VO_FOUND,
|
||||
PARSE_VOS_FOUND,
|
||||
PARSE_VOP_FOUND
|
||||
} GstMpeg4VParseState;
|
||||
|
||||
struct _GstMpeg4VParse {
|
||||
GstElement element;
|
||||
GstBaseParse element;
|
||||
|
||||
GstPad * sinkpad;
|
||||
GstPad * srcpad;
|
||||
|
||||
GstCaps *sink_caps;
|
||||
|
||||
guint interval;
|
||||
GstClockTime last_report;
|
||||
|
||||
GstAdapter * adapter;
|
||||
guint offset;
|
||||
guint vos_offset;
|
||||
/* parse state */
|
||||
gint last_sc;
|
||||
gint vop_offset;
|
||||
gint vos_offset;
|
||||
gint vo_offset;
|
||||
gboolean intra_frame;
|
||||
|
||||
GstMpeg4VParseState state;
|
||||
GstClockTime timestamp;
|
||||
gboolean update_caps;
|
||||
|
||||
GstBuffer *config;
|
||||
gboolean have_config;
|
||||
guint8 profile;
|
||||
GstClockTime frame_duration;
|
||||
MPEG4Params params;
|
||||
|
||||
/* properties */
|
||||
gboolean drop;
|
||||
|
||||
gboolean have_src_caps;
|
||||
GstEvent *pending_segment;
|
||||
GList *pending_events;
|
||||
guint interval;
|
||||
};
|
||||
|
||||
struct _GstMpeg4VParseClass {
|
||||
GstElementClass parent_class;
|
||||
GstBaseParseClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_mpeg4vparse_get_type (void);
|
||||
|
|
Loading…
Reference in a new issue