videoparsers: port to 0.11

Unit tests missing for now.
This commit is contained in:
René Stadler 2011-11-24 12:01:48 +01:00
parent 4a8373b267
commit e6df0b672f
6 changed files with 268 additions and 216 deletions

View file

@ -302,7 +302,7 @@ GST_PLUGINS_NONPORTED=" adpcmdec adpcmenc aiff asfmux \
mpegpsmux mpegvideoparse mve mxf mythtv nsf nuvdemux \
patchdetect pcapparse pnm rawparse real removesilence rtpmux rtpvp8 scaletempo \
sdi segmentclip siren speed subenc stereo tta videofilters \
videomaxrate videomeasure videoparsers videosignal vmnc \
videomaxrate videomeasure videosignal vmnc \
decklink fbdev linsys shm vcd \
voaacenc apexsink bz2 camerabin2 cdaudio celt cog curl dc1394 dirac directfb dts resindvd \
gsettings gsm jp2k ladspa modplug mpeg2enc mplex mimic \

View file

@ -95,13 +95,20 @@ GST_STATIC_PAD_TEMPLATE ("src",
/* class initialization */
GST_BOILERPLATE (GstDiracParse, gst_dirac_parse, GstBaseParse,
GST_TYPE_BASE_PARSE);
#define parent_class gst_dirac_parse_parent_class
G_DEFINE_TYPE (GstDiracParse, gst_dirac_parse, GST_TYPE_BASE_PARSE);
static void
gst_dirac_parse_base_init (gpointer g_class)
gst_dirac_parse_class_init (GstDiracParseClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstBaseParseClass *base_parse_class = GST_BASE_PARSE_CLASS (klass);
gobject_class->set_property = gst_dirac_parse_set_property;
gobject_class->get_property = gst_dirac_parse_get_property;
gobject_class->dispose = gst_dirac_parse_dispose;
gobject_class->finalize = gst_dirac_parse_finalize;
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_dirac_parse_src_template));
@ -111,18 +118,7 @@ gst_dirac_parse_base_init (gpointer g_class)
gst_element_class_set_details_simple (element_class, "Dirac parser",
"Codec/Parser/Video", "Parses Dirac streams",
"David Schleef <ds@schleef.org>");
}
static void
gst_dirac_parse_class_init (GstDiracParseClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstBaseParseClass *base_parse_class = GST_BASE_PARSE_CLASS (klass);
gobject_class->set_property = gst_dirac_parse_set_property;
gobject_class->get_property = gst_dirac_parse_get_property;
gobject_class->dispose = gst_dirac_parse_dispose;
gobject_class->finalize = gst_dirac_parse_finalize;
base_parse_class->start = GST_DEBUG_FUNCPTR (gst_dirac_parse_start);
base_parse_class->stop = GST_DEBUG_FUNCPTR (gst_dirac_parse_stop);
base_parse_class->set_sink_caps =
@ -140,11 +136,9 @@ gst_dirac_parse_class_init (GstDiracParseClass * klass)
}
static void
gst_dirac_parse_init (GstDiracParse * diracparse,
GstDiracParseClass * diracparse_class)
gst_dirac_parse_init (GstDiracParse * diracparse)
{
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (diracparse), 13);
}
void
@ -219,37 +213,38 @@ static gboolean
gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
{
GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (frame->buffer);
int off;
guint32 next_header;
guint8 *data;
int size;
gsize size;
gboolean have_picture = FALSE;
int offset;
data = GST_BUFFER_DATA (frame->buffer);
size = GST_BUFFER_SIZE (frame->buffer);
data = gst_buffer_map (frame->buffer, &size, NULL, GST_MAP_READ);
if (G_UNLIKELY (size < 13))
return FALSE;
goto out;
GST_DEBUG ("%d: %02x %02x %02x %02x", size, data[0], data[1], data[2],
data[3]);
if (GST_READ_UINT32_BE (data) != 0x42424344) {
GstByteReader reader;
gst_byte_reader_init (&reader, data, size);
off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
0x42424344, 0, GST_BUFFER_SIZE (frame->buffer));
0x42424344, 0, size);
if (off < 0) {
*skipsize = GST_BUFFER_SIZE (frame->buffer) - 3;
return FALSE;
*skipsize = size - 3;
goto out;
}
GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off);
GST_DEBUG ("skipping %d", off);
*skipsize = off;
return FALSE;
goto out;
}
/* have sync, parse chunks */
@ -260,7 +255,7 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
if (offset + 13 >= size) {
*framesize = offset + 13;
return FALSE;
goto out;
}
GST_DEBUG ("chunk type %02x", data[offset + 4]);
@ -268,7 +263,7 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
if (GST_READ_UINT32_BE (data + offset) != 0x42424344) {
GST_DEBUG ("bad header");
*skipsize = 3;
return FALSE;
goto out;
}
next_header = GST_READ_UINT32_BE (data + offset + 5);
@ -283,14 +278,20 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
offset += next_header;
if (offset >= size) {
*framesize = offset;
return FALSE;
goto out;
}
}
gst_buffer_unmap (frame->buffer, data, size);
*framesize = offset;
GST_DEBUG ("framesize %d", *framesize);
return TRUE;
out:
gst_buffer_unmap (frame->buffer, data, size);
return FALSE;
}
static GstFlowReturn
@ -298,14 +299,13 @@ gst_dirac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
guint8 *data;
int size;
gsize size;
/* Called when processing incoming buffers. Function should parse
a checked frame. */
/* MUST implement */
data = GST_BUFFER_DATA (frame->buffer);
size = GST_BUFFER_SIZE (frame->buffer);
data = gst_buffer_map (frame->buffer, &size, NULL, GST_MAP_READ);
//GST_ERROR("got here %d", size);
@ -339,8 +339,7 @@ gst_dirac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
}
}
gst_buffer_set_caps (frame->buffer,
GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (parse)));
gst_buffer_unmap (frame->buffer, data, size);
gst_base_parse_set_min_frame_size (parse, 13);

View file

@ -48,7 +48,7 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK,
GST_STATIC_CAPS ("video/x-h263, variant = (string) itu")
);
GST_BOILERPLATE (GstH263Parse, gst_h263_parse, GstElement, GST_TYPE_BASE_PARSE);
G_DEFINE_TYPE (GstH263Parse, gst_h263_parse, GST_TYPE_BASE_PARSE);
static gboolean gst_h263_parse_start (GstBaseParse * parse);
static gboolean gst_h263_parse_stop (GstBaseParse * parse);
@ -60,9 +60,12 @@ static GstFlowReturn gst_h263_parse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
static void
gst_h263_parse_base_init (gpointer g_class)
gst_h263_parse_class_init (GstH263ParseClass * klass)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
GST_DEBUG_CATEGORY_INIT (h263_parse_debug, "h263parse", 0, "h263 parser");
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&srctemplate));
@ -74,14 +77,6 @@ gst_h263_parse_base_init (gpointer g_class)
"Arun Raghavan <arun.raghavan@collabora.co.uk>,"
"Edward Hervey <edward.hervey@collabora.co.uk>");
GST_DEBUG_CATEGORY_INIT (h263_parse_debug, "h263parse", 0, "h263 parser");
}
static void
gst_h263_parse_class_init (GstH263ParseClass * klass)
{
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
/* Override BaseParse vfuncs */
parse_class->start = GST_DEBUG_FUNCPTR (gst_h263_parse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_h263_parse_stop);
@ -92,7 +87,7 @@ gst_h263_parse_class_init (GstH263ParseClass * klass)
}
static void
gst_h263_parse_init (GstH263Parse * h263parse, GstH263ParseClass * g_class)
gst_h263_parse_init (GstH263Parse * h263parse)
{
}
@ -153,10 +148,13 @@ gst_h263_parse_sink_event (GstBaseParse * parse, GstEvent * event)
static guint
find_psc (GstBuffer * buffer, guint skip)
{
guint8 *buf_data;
gsize buf_size;
GstByteReader br;
guint psc_pos = -1, psc;
gst_byte_reader_init_from_buffer (&br, buffer);
buf_data = gst_buffer_map (buffer, &buf_size, NULL, GST_MAP_READ);
gst_byte_reader_init (&br, buf_data, buf_size);
if (!gst_byte_reader_set_pos (&br, skip))
goto out;
@ -174,6 +172,7 @@ find_psc (GstBuffer * buffer, guint skip)
}
out:
gst_buffer_unmap (buffer, buf_data, buf_size);
return psc_pos;
}
@ -187,16 +186,16 @@ gst_h263_parse_set_src_caps (GstH263Parse * h263parse,
g_assert (h263parse->state == PASSTHROUGH || h263parse->state == GOT_HEADER);
caps = GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (h263parse));
caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (h263parse));
if (caps) {
caps = gst_caps_copy (caps);
caps = gst_caps_make_writable (caps);
} else {
caps = gst_caps_new_simple ("video/x-h263",
"variant", G_TYPE_STRING, "itu", NULL);
}
gst_caps_set_simple (caps, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
sink_caps = GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (h263parse));
sink_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (h263parse));
if (sink_caps && (st = gst_caps_get_structure (sink_caps, 0)) &&
gst_structure_get_fraction (st, "framerate", &fr_num, &fr_denom)) {
/* Got it in caps - nothing more to do */
@ -253,19 +252,21 @@ gst_h263_parse_check_valid_frame (GstBaseParse * parse,
GstH263Parse *h263parse;
GstBuffer *buffer;
guint psc_pos, next_psc_pos;
gsize size;
h263parse = GST_H263_PARSE (parse);
buffer = frame->buffer;
size = gst_buffer_get_size (buffer);
if (GST_BUFFER_SIZE (buffer) < 3)
if (size < 3)
return FALSE;
psc_pos = find_psc (buffer, 0);
if (psc_pos == -1) {
/* PSC not found, need more data */
if (GST_BUFFER_SIZE (buffer) > 3)
psc_pos = GST_BUFFER_SIZE (buffer) - 3;
if (size > 3)
psc_pos = size - 3;
else
psc_pos = 0;
goto more;
@ -278,7 +279,7 @@ gst_h263_parse_check_valid_frame (GstBaseParse * parse,
if (next_psc_pos == -1) {
if (GST_BASE_PARSE_DRAINING (parse))
/* FLUSH/EOS, it's okay if we can't find the next frame */
next_psc_pos = GST_BUFFER_SIZE (buffer);
next_psc_pos = size;
else
goto more;
}
@ -347,9 +348,6 @@ gst_h263_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
/* h263parse->state is now GOT_HEADER */
gst_buffer_set_caps (buffer,
GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (GST_BASE_PARSE (h263parse))));
if (gst_h263_parse_is_delta_unit (&params))
GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
else

View file

@ -71,8 +71,8 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
"stream-format=(string) { avc, byte-stream }, "
"alignment=(string) { au, nal }"));
GST_BOILERPLATE (GstH264Parse, gst_h264_parse, GstBaseParse,
GST_TYPE_BASE_PARSE);
#define parent_class gst_h264_parse_parent_class
G_DEFINE_TYPE (GstH264Parse, gst_h264_parse, GST_TYPE_BASE_PARSE);
static void gst_h264_parse_finalize (GObject * object);
@ -91,32 +91,19 @@ static void gst_h264_parse_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps);
static GstCaps *gst_h264_parse_get_caps (GstBaseParse * parse);
static GstFlowReturn gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer);
static void
gst_h264_parse_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&srctemplate));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&sinktemplate));
gst_element_class_set_details_simple (gstelement_class, "H.264 parser",
"Codec/Parser/Converter/Video",
"Parses H.264 streams",
"Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>");
GST_DEBUG_CATEGORY_INIT (h264_parse_debug, "h264parse", 0, "h264 parser");
}
static GstCaps *gst_h264_parse_get_caps (GstBaseParse * parse,
GstCaps * filter);
static GstFlowReturn gst_h264_parse_chain (GstPad * pad, GstObject * parent,
GstBuffer * buffer);
static void
gst_h264_parse_class_init (GstH264ParseClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
GST_DEBUG_CATEGORY_INIT (h264_parse_debug, "h264parse", 0, "h264 parser");
gobject_class->finalize = gst_h264_parse_finalize;
gobject_class->set_property = gst_h264_parse_set_property;
@ -140,10 +127,20 @@ gst_h264_parse_class_init (GstH264ParseClass * klass)
GST_DEBUG_FUNCPTR (gst_h264_parse_pre_push_frame);
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_h264_parse_set_caps);
parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_h264_parse_get_caps);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&srctemplate));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&sinktemplate));
gst_element_class_set_details_simple (gstelement_class, "H.264 parser",
"Codec/Parser/Converter/Video",
"Parses H.264 streams",
"Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>");
}
static void
gst_h264_parse_init (GstH264Parse * h264parse, GstH264ParseClass * g_class)
gst_h264_parse_init (GstH264Parse * h264parse)
{
h264parse->frame_out = gst_adapter_new ();
@ -340,22 +337,23 @@ gst_h264_parse_wrap_nal (GstH264Parse * h264parse, guint format, guint8 * data,
{
GstBuffer *buf;
guint nl = h264parse->nal_length_size;
guint32 tmp;
GST_DEBUG_OBJECT (h264parse, "nal length %d", size);
buf = gst_buffer_new_and_alloc (size + nl + 4);
buf = gst_buffer_new_allocate (NULL, nl + size, 0);
if (format == GST_H264_PARSE_FORMAT_AVC) {
GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), size << (32 - 8 * nl));
tmp = GUINT32_TO_BE (size << (32 - 8 * nl));
} else {
/* HACK: nl should always be 4 here, otherwise this won't work.
* There are legit cases where nl in avc stream is 2, but byte-stream
* SC is still always 4 bytes. */
nl = 4;
GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), 1);
tmp = GUINT32_TO_BE (1);
}
GST_BUFFER_SIZE (buf) = size + nl;
memcpy (GST_BUFFER_DATA (buf) + nl, data, size);
gst_buffer_fill (buf, 0, &tmp, sizeof (guint32));
gst_buffer_fill (buf, nl, data, size);
return buf;
}
@ -383,8 +381,8 @@ gst_h264_parser_store_nal (GstH264Parse * h264parse, guint id,
return;
}
buf = gst_buffer_new_and_alloc (size);
memcpy (GST_BUFFER_DATA (buf), nalu->data + nalu->offset, size);
buf = gst_buffer_new_allocate (NULL, size, 0);
gst_buffer_fill (buf, 0, nalu->data + nalu->offset, size);
if (store[id])
gst_buffer_unref (store[id]);
@ -592,14 +590,19 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
GstH264Parse *h264parse = GST_H264_PARSE (parse);
GstBuffer *buffer = frame->buffer;
guint8 *data;
guint size, current_off = 0;
gsize size;
guint current_off = 0;
gboolean drain;
GstH264NalParser *nalparser = h264parse->nalparser;
GstH264NalUnit nalu = h264parse->nalu;
data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
/* expect at least 3 bytes startcode == sc, and 2 bytes NALU payload */
if (G_UNLIKELY (GST_BUFFER_SIZE (buffer) < 5))
if (G_UNLIKELY (size < 5)) {
gst_buffer_unmap (buffer, data, size);
return FALSE;
}
/* need to configure aggregation */
if (G_UNLIKELY (h264parse->format == GST_H264_PARSE_FORMAT_NONE))
@ -614,9 +617,6 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
GST_LOG_OBJECT (h264parse, "resuming frame parsing");
}
data = GST_BUFFER_DATA (buffer);
size = GST_BUFFER_SIZE (buffer);
drain = FALSE;
current_off = h264parse->current_off;
@ -645,7 +645,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
}
break;
case GST_H264_PARSER_BROKEN_LINK:
return FALSE;
goto out;
case GST_H264_PARSER_ERROR:
current_off = size - 3;
goto parsing_error;
@ -711,6 +711,7 @@ end:
*framesize = nalu.offset + nalu.size - h264parse->nalu.sc_offset;
h264parse->current_off = current_off;
gst_buffer_unmap (buffer, data, size);
return TRUE;
parsing_error:
@ -733,11 +734,14 @@ more:
/* Restart parsing from here next time */
h264parse->current_off = current_off;
/* Fall-through. */
out:
gst_buffer_unmap (buffer, data, size);
return FALSE;
invalid:
gst_h264_parse_reset_frame (h264parse);
return FALSE;
goto out;
}
/* byte together avc codec data based on collected pps and sps so far */
@ -748,20 +752,23 @@ gst_h264_parse_make_codec_data (GstH264Parse * h264parse)
gint i, sps_size = 0, pps_size = 0, num_sps = 0, num_pps = 0;
guint8 profile_idc = 0, profile_comp = 0, level_idc = 0;
gboolean found = FALSE;
guint8 *data;
guint8 *buf_data, *data;
/* only nal payload in stored nals */
for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
if ((nal = h264parse->sps_nals[i])) {
gsize size = gst_buffer_get_size (nal);
num_sps++;
/* size bytes also count */
sps_size += GST_BUFFER_SIZE (nal) + 2;
if (GST_BUFFER_SIZE (nal) >= 4) {
sps_size += size + 2;
if (size >= 4) {
guint8 tmp[3];
found = TRUE;
profile_idc = (GST_BUFFER_DATA (nal))[1];
profile_comp = (GST_BUFFER_DATA (nal))[2];
level_idc = (GST_BUFFER_DATA (nal))[3];
gst_buffer_extract (nal, 1, tmp, 3);
profile_idc = tmp[0];
profile_comp = tmp[1];
level_idc = tmp[2];
}
}
}
@ -769,7 +776,7 @@ gst_h264_parse_make_codec_data (GstH264Parse * h264parse)
if ((nal = h264parse->pps_nals[i])) {
num_pps++;
/* size bytes also count */
pps_size += GST_BUFFER_SIZE (nal) + 2;
pps_size += gst_buffer_get_size (nal) + 2;
}
}
@ -779,8 +786,9 @@ gst_h264_parse_make_codec_data (GstH264Parse * h264parse)
if (!found || !num_pps)
return NULL;
buf = gst_buffer_new_and_alloc (5 + 1 + sps_size + 1 + pps_size);
data = GST_BUFFER_DATA (buf);
buf = gst_buffer_new_allocate (NULL, 5 + 1 + sps_size + 1 + pps_size, 0);
buf_data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
data = buf_data;
data[0] = 1; /* AVC Decoder Configuration Record ver. 1 */
data[1] = profile_idc; /* profile_idc */
@ -792,9 +800,10 @@ gst_h264_parse_make_codec_data (GstH264Parse * h264parse)
data += 6;
for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
if ((nal = h264parse->sps_nals[i])) {
GST_WRITE_UINT16_BE (data, GST_BUFFER_SIZE (nal));
memcpy (data + 2, GST_BUFFER_DATA (nal), GST_BUFFER_SIZE (nal));
data += 2 + GST_BUFFER_SIZE (nal);
gsize nal_size = gst_buffer_get_size (nal);
GST_WRITE_UINT16_BE (data, nal_size);
gst_buffer_extract (nal, 0, data + 2, nal_size);
data += 2 + nal_size;
}
}
@ -802,12 +811,15 @@ gst_h264_parse_make_codec_data (GstH264Parse * h264parse)
data++;
for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
if ((nal = h264parse->pps_nals[i])) {
GST_WRITE_UINT16_BE (data, GST_BUFFER_SIZE (nal));
memcpy (data + 2, GST_BUFFER_DATA (nal), GST_BUFFER_SIZE (nal));
data += 2 + GST_BUFFER_SIZE (nal);
gsize nal_size = gst_buffer_get_size (nal);
GST_WRITE_UINT16_BE (data, nal_size);
gst_buffer_extract (nal, 0, data + 2, nal_size);
data += 2 + nal_size;
}
}
gst_buffer_unmap (buf, buf_data, -1);
return buf;
}
@ -819,7 +831,8 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps)
gboolean modified = FALSE;
GstBuffer *buf = NULL;
if (G_UNLIKELY (!GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (h264parse))))
if (G_UNLIKELY (!gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD
(h264parse))))
modified = TRUE;
else if (G_UNLIKELY (!h264parse->update_caps))
return;
@ -829,13 +842,11 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps)
if (caps)
sink_caps = caps;
else
sink_caps = GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (h264parse));
sink_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (h264parse));
/* carry over input caps as much as possible; override with our own stuff */
if (sink_caps)
gst_caps_ref (sink_caps);
else
sink_caps = gst_caps_new_simple ("video/x-h264", NULL);
if (!sink_caps)
sink_caps = gst_caps_new_empty_simple ("video/x-h264");
sps = h264parse->nalparser->last_sps;
GST_DEBUG_OBJECT (h264parse, "sps: %p", sps);
@ -845,10 +856,15 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps)
h264parse->align == GST_H264_PARSE_ALIGN_AU) {
buf = gst_h264_parse_make_codec_data (h264parse);
if (buf && h264parse->codec_data) {
if (GST_BUFFER_SIZE (buf) != GST_BUFFER_SIZE (h264parse->codec_data) ||
memcmp (GST_BUFFER_DATA (buf),
GST_BUFFER_DATA (h264parse->codec_data), GST_BUFFER_SIZE (buf)))
gsize size;
gpointer data;
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
if (size != gst_buffer_get_size (h264parse->codec_data) ||
gst_buffer_memcmp (h264parse->codec_data, 0, data, size))
modified = TRUE;
gst_buffer_unmap (buf, data, size);
} else {
if (h264parse->codec_data)
buf = gst_buffer_ref (h264parse->codec_data);
@ -1061,7 +1077,7 @@ gst_h264_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
GstBuffer *buf;
buf = gst_adapter_take_buffer (h264parse->frame_out, av);
gst_buffer_copy_metadata (buf, buffer, GST_BUFFER_COPY_ALL);
gst_buffer_copy_into (buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
gst_buffer_replace (&frame->buffer, buf);
gst_buffer_unref (buf);
}
@ -1075,14 +1091,16 @@ static GstFlowReturn
gst_h264_parse_push_codec_buffer (GstH264Parse * h264parse, GstBuffer * nal,
GstClockTime ts)
{
nal = gst_h264_parse_wrap_nal (h264parse, h264parse->format,
GST_BUFFER_DATA (nal), GST_BUFFER_SIZE (nal));
gpointer data;
gsize size;
data = gst_buffer_map (nal, &size, NULL, GST_MAP_READ);
nal = gst_h264_parse_wrap_nal (h264parse, h264parse->format, data, size);
gst_buffer_unmap (nal, data, size);
GST_BUFFER_TIMESTAMP (nal) = ts;
GST_BUFFER_DURATION (nal) = 0;
gst_buffer_set_caps (nal, GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (h264parse)));
return gst_pad_push (GST_BASE_PARSE_SRC_PAD (h264parse), nal);
}
@ -1156,36 +1174,33 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
GstBuffer *new_buf;
const gboolean bs = h264parse->format == GST_H264_PARSE_FORMAT_BYTE;
gst_byte_writer_init_with_size (&bw, GST_BUFFER_SIZE (buffer), FALSE);
gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (buffer),
h264parse->idr_pos);
gst_byte_writer_init_with_size (&bw, gst_buffer_get_size (buffer),
FALSE);
gst_byte_writer_put_buffer (&bw, buffer, 0, h264parse->idr_pos);
GST_DEBUG_OBJECT (h264parse, "- inserting SPS/PPS");
for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
if ((codec_nal = h264parse->sps_nals[i])) {
gsize nal_size = gst_buffer_get_size (codec_nal);
GST_DEBUG_OBJECT (h264parse, "inserting SPS nal");
gst_byte_writer_put_uint32_be (&bw,
bs ? 1 : GST_BUFFER_SIZE (codec_nal));
gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (codec_nal),
GST_BUFFER_SIZE (codec_nal));
gst_byte_writer_put_uint32_be (&bw, bs ? 1 : nal_size);
gst_byte_writer_put_buffer (&bw, codec_nal, 0, nal_size);
h264parse->last_report = new_ts;
}
}
for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
if ((codec_nal = h264parse->pps_nals[i])) {
gsize nal_size = gst_buffer_get_size (codec_nal);
GST_DEBUG_OBJECT (h264parse, "inserting PPS nal");
gst_byte_writer_put_uint32_be (&bw,
bs ? 1 : GST_BUFFER_SIZE (codec_nal));
gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (codec_nal),
GST_BUFFER_SIZE (codec_nal));
gst_byte_writer_put_uint32_be (&bw, bs ? 1 : nal_size);
gst_byte_writer_put_buffer (&bw, codec_nal, 0, nal_size);
h264parse->last_report = new_ts;
}
}
gst_byte_writer_put_data (&bw,
GST_BUFFER_DATA (buffer) + h264parse->idr_pos,
GST_BUFFER_SIZE (buffer) - h264parse->idr_pos);
gst_byte_writer_put_buffer (&bw, buffer, h264parse->idr_pos, -1);
/* collect result and push */
new_buf = gst_byte_writer_reset_and_get_buffer (&bw);
gst_buffer_copy_metadata (new_buf, buffer, GST_BUFFER_COPY_ALL);
gst_buffer_copy_into (new_buf, buffer, GST_BUFFER_COPY_METADATA, 0,
-1);
gst_buffer_replace (&frame->buffer, new_buf);
gst_buffer_unref (new_buf);
}
@ -1207,7 +1222,8 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
GstStructure *str;
const GValue *value;
GstBuffer *codec_data = NULL;
guint size, format, align, off;
gsize size;
guint format, align, off;
GstH264NalUnit nalu;
GstH264ParserResult parseres;
@ -1241,15 +1257,18 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
codec_data = gst_value_get_buffer (value);
if (!codec_data)
goto wrong_type;
data = GST_BUFFER_DATA (codec_data);
size = GST_BUFFER_SIZE (codec_data);
data = gst_buffer_map (codec_data, &size, NULL, GST_MAP_READ);
/* parse the avcC data */
if (size < 8)
if (size < 8) {
gst_buffer_unmap (codec_data, data, size);
goto avcc_too_small;
}
/* parse the version, this must be 1 */
if (data[0] != 1)
if (data[0] != 1) {
gst_buffer_unmap (codec_data, data, size);
goto wrong_version;
}
/* AVCProfileIndication */
/* profile_compat */
@ -1269,8 +1288,10 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
for (i = 0; i < num_sps; i++) {
parseres = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
data, off, size, 2, &nalu);
if (parseres != GST_H264_PARSER_OK)
if (parseres != GST_H264_PARSER_OK) {
gst_buffer_unmap (codec_data, data, size);
goto avcc_too_small;
}
gst_h264_parse_process_nal (h264parse, &nalu);
off = nalu.offset + nalu.size;
@ -1283,6 +1304,7 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
parseres = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
data, off, size, 2, &nalu);
if (parseres != GST_H264_PARSER_OK) {
gst_buffer_unmap (codec_data, data, size);
goto avcc_too_small;
}
@ -1290,6 +1312,8 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
off = nalu.offset + nalu.size;
}
gst_buffer_unmap (codec_data, data, size);
h264parse->codec_data = gst_buffer_ref (codec_data);
/* if upstream sets codec_data without setting stream-format and alignment, we
@ -1354,11 +1378,13 @@ refuse_caps:
}
static GstCaps *
gst_h264_parse_get_caps (GstBaseParse * parse)
gst_h264_parse_get_caps (GstBaseParse * parse, GstCaps * filter)
{
GstCaps *peercaps;
GstCaps *peercaps, *template_caps;
GstCaps *res;
template_caps =
gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
if (peercaps) {
guint i, n;
@ -1372,24 +1398,28 @@ gst_h264_parse_get_caps (GstBaseParse * parse)
gst_structure_remove_field (s, "parsed");
}
res =
gst_caps_intersect_full (peercaps,
gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)),
res = gst_caps_intersect_full (peercaps, template_caps,
GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (peercaps);
gst_caps_unref (template_caps);
} else {
res =
gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD
(parse)));
res = template_caps;
}
if (filter) {
GstCaps *tmp = gst_caps_intersect_full (res, filter,
GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (res);
res = tmp;
}
return res;
}
static GstFlowReturn
gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer)
gst_h264_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
GstH264Parse *h264parse = GST_H264_PARSE (GST_PAD_PARENT (pad));
GstH264Parse *h264parse = GST_H264_PARSE (parent);
if (h264parse->packetized && buffer) {
GstBuffer *sub;
@ -1397,6 +1427,8 @@ gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer)
GstH264ParserResult parse_res;
GstH264NalUnit nalu;
const guint nl = h264parse->nal_length_size;
gpointer data;
gsize size;
if (nl < 1 || nl > 4) {
GST_DEBUG_OBJECT (h264parse, "insufficient data to split input");
@ -1405,11 +1437,13 @@ gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer)
return GST_FLOW_NOT_NEGOTIATED;
}
GST_LOG_OBJECT (h264parse, "processing packet buffer of size %d",
GST_BUFFER_SIZE (buffer));
data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
GST_LOG_OBJECT (h264parse,
"processing packet buffer of size %" G_GSIZE_FORMAT, size);
parse_res = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
GST_BUFFER_DATA (buffer), 0, GST_BUFFER_SIZE (buffer), nl, &nalu);
data, 0, size, nl, &nalu);
while (parse_res == GST_H264_PARSER_OK) {
GST_DEBUG_OBJECT (h264parse, "AVC nal offset %d",
@ -1422,7 +1456,7 @@ gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer)
/* at least this should make sense */
GST_BUFFER_TIMESTAMP (sub) = GST_BUFFER_TIMESTAMP (buffer);
GST_LOG_OBJECT (h264parse, "pushing NAL of size %d", nalu.size);
ret = h264parse->parse_chain (pad, sub);
ret = h264parse->parse_chain (pad, parent, sub);
} else {
/* pass-through: no looking for frames (and nal processing),
* so need to parse to collect data here */
@ -1434,10 +1468,11 @@ gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer)
}
parse_res = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
GST_BUFFER_DATA (buffer), nalu.offset + nalu.size,
GST_BUFFER_SIZE (buffer), nl, &nalu);
data, nalu.offset + nalu.size, size, nl, &nalu);
}
gst_buffer_unmap (buffer, data, size);
if (h264parse->split_packetized) {
gst_buffer_unref (buffer);
return ret;
@ -1463,7 +1498,7 @@ gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer)
}
}
return h264parse->parse_chain (pad, buffer);
return h264parse->parse_chain (pad, parent, buffer);
}
static void

View file

@ -61,8 +61,8 @@ enum
PROP_LAST
};
GST_BOILERPLATE (GstMpegvParse, gst_mpegv_parse, GstBaseParse,
GST_TYPE_BASE_PARSE);
#define parent_class gst_mpegv_parse_parent_class
G_DEFINE_TYPE (GstMpegvParse, gst_mpegv_parse, GST_TYPE_BASE_PARSE);
static gboolean gst_mpegv_parse_start (GstBaseParse * parse);
static gboolean gst_mpegv_parse_stop (GstBaseParse * parse);
@ -79,28 +79,6 @@ static void gst_mpegv_parse_set_property (GObject * object, guint prop_id,
static void gst_mpegv_parse_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void
gst_mpegv_parse_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_template));
gst_element_class_set_details_simple (element_class,
"MPEG video elementary stream parser",
"Codec/Parser/Video",
"Parses and frames MPEG-1 and MPEG-2 elementary video streams",
"Wim Taymans <wim.taymans@ccollabora.co.uk>, "
"Jan Schmidt <thaytan@mad.scientist.com>, "
"Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>");
GST_DEBUG_CATEGORY_INIT (mpegv_parse_debug, "mpegvideoparse", 0,
"MPEG-1/2 video parser");
}
static void
gst_mpegv_parse_set_property (GObject * object, guint property_id,
const GValue * value, GParamSpec * pspec)
@ -141,8 +119,12 @@ static void
gst_mpegv_parse_class_init (GstMpegvParseClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
GST_DEBUG_CATEGORY_INIT (mpegv_parse_debug, "mpegvideoparse", 0,
"MPEG-1/2 video parser");
parent_class = g_type_class_peek_parent (klass);
gobject_class->set_property = gst_mpegv_parse_set_property;
@ -159,6 +141,19 @@ gst_mpegv_parse_class_init (GstMpegvParseClass * klass)
"Split frame when encountering GOP", DEFAULT_PROP_GOP_SPLIT,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_template));
gst_element_class_set_details_simple (element_class,
"MPEG video elementary stream parser",
"Codec/Parser/Video",
"Parses and frames MPEG-1 and MPEG-2 elementary video streams",
"Wim Taymans <wim.taymans@ccollabora.co.uk>, "
"Jan Schmidt <thaytan@mad.scientist.com>, "
"Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>");
/* Override BaseParse vfuncs */
parse_class->start = GST_DEBUG_FUNCPTR (gst_mpegv_parse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_mpegv_parse_stop);
@ -171,7 +166,7 @@ gst_mpegv_parse_class_init (GstMpegvParseClass * klass)
}
static void
gst_mpegv_parse_init (GstMpegvParse * parse, GstMpegvParseClass * g_class)
gst_mpegv_parse_init (GstMpegvParse * parse)
{
parse->mpeg_version = 0;
}
@ -231,16 +226,21 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
guint size)
{
GList *tmp;
guint8 *data = GST_BUFFER_DATA (buf);
data = data + mpvparse->seq_offset;
guint8 *buf_data, *data;
gsize buf_size;
buf_data = gst_buffer_map (buf, &buf_size, NULL, GST_MAP_READ);
data = buf_data + mpvparse->seq_offset;
/* only do stuff if something new */
if (mpvparse->config && size == GST_BUFFER_SIZE (mpvparse->config) &&
memcmp (GST_BUFFER_DATA (mpvparse->config), data, size) == 0)
if (mpvparse->config && size == gst_buffer_get_size (mpvparse->config) &&
gst_buffer_memcmp (mpvparse->config, 0, data, size) == 0) {
gst_buffer_unmap (buf, buf_data, buf_size);
return TRUE;
}
if (gst_mpeg_video_parse_sequence_header (&mpvparse->sequencehdr, data,
GST_BUFFER_SIZE (buf) - mpvparse->seq_offset, 0)) {
buf_size - mpvparse->seq_offset, 0)) {
if (mpvparse->fps_num == 0 || mpvparse->fps_den == 0) {
mpvparse->fps_num = mpvparse->sequencehdr.fps_n;
mpvparse->fps_den = mpvparse->sequencehdr.fps_d;
@ -249,6 +249,7 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
GST_DEBUG_OBJECT (mpvparse,
"failed to parse config data (size %d) at offset %d",
size, mpvparse->seq_offset);
gst_buffer_unmap (buf, buf_data, buf_size);
return FALSE;
}
@ -266,8 +267,7 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
mpvparse->mpeg_version = 2;
if (gst_mpeg_video_parse_sequence_extension (&mpvparse->sequenceext,
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf),
tpoffsz->offset)) {
buf_data, buf_size, tpoffsz->offset)) {
mpvparse->fps_num =
mpvparse->sequencehdr.fps_n * (mpvparse->sequenceext.fps_n_ext +
1) * 2;
@ -284,11 +284,13 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
gst_buffer_unref (mpvparse->config);
mpvparse->config = gst_buffer_new_and_alloc (size);
memcpy (GST_BUFFER_DATA (mpvparse->config), data, size);
gst_buffer_fill (mpvparse->config, 0, data, size);
/* trigger src caps update */
mpvparse->update_caps = TRUE;
gst_buffer_unmap (buf, buf_data, buf_size);
return TRUE;
}
@ -354,8 +356,12 @@ static void
parse_picture_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off)
{
GstMpegVideoPictureExt ext;
if (gst_mpeg_video_parse_picture_extension (&ext, GST_BUFFER_DATA (buf),
GST_BUFFER_SIZE (buf), off)) {
gpointer data;
gsize size;
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
if (gst_mpeg_video_parse_picture_extension (&ext, data, size, off)) {
mpvparse->frame_repeat_count = 1;
if (ext.repeat_first_field) {
@ -369,6 +375,8 @@ parse_picture_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off)
}
}
}
gst_buffer_unmap (buf, data, size);
}
/* caller guarantees at least start code in @buf at @off */
@ -380,7 +388,7 @@ gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse,
{
gboolean ret = FALSE, packet = TRUE;
g_return_val_if_fail (buf && GST_BUFFER_SIZE (buf) >= 4, FALSE);
g_return_val_if_fail (buf && gst_buffer_get_size (buf) >= 4, FALSE);
GST_LOG_OBJECT (mpvparse, "process startcode %x (%s)", code,
picture_start_code_name (code));
@ -427,14 +435,19 @@ gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse,
/* extract some picture info if there is any in the frame being terminated */
if (ret && mpvparse->pic_offset >= 0 && mpvparse->pic_offset < off) {
gsize size;
gpointer data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
if (gst_mpeg_video_parse_picture_header (&mpvparse->pichdr,
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), mpvparse->pic_offset))
data, size, mpvparse->pic_offset))
GST_LOG_OBJECT (mpvparse, "picture_coding_type %d (%s), ending"
"frame of size %d", mpvparse->pichdr.pic_type,
picture_type_name (mpvparse->pichdr.pic_type), off - 4);
else
GST_LOG_OBJECT (mpvparse, "Couldn't parse picture at offset %d",
mpvparse->pic_offset);
gst_buffer_unmap (buf, data, size);
}
return ret;
@ -487,14 +500,17 @@ gst_mpegv_parse_check_valid_frame (GstBaseParse * parse,
gboolean ret = FALSE;
GList *tmp;
gint off = 0, fsize = -1;
gpointer buf_data;
gsize buf_size;
update_frame_parsing_status (mpvparse, frame);
if (mpvparse->last_sc >= 0)
off = mpvparse->last_sc;
mpvparse->typeoffsize =
gst_mpeg_video_parse (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), off);
buf_data = gst_buffer_map (buf, &buf_size, NULL, GST_MAP_READ);
mpvparse->typeoffsize = gst_mpeg_video_parse (buf_data, buf_size, off);
gst_buffer_unmap (buf, buf_data, buf_size);
/* No sc found */
if (mpvparse->typeoffsize == NULL)
@ -531,15 +547,15 @@ end:
*framesize = fsize;
ret = TRUE;
} else if (GST_BASE_PARSE_DRAINING (parse)) {
*framesize = GST_BUFFER_SIZE (buf);
*framesize = buf_size;
ret = TRUE;
} else {
/* resume scan where we left it */
if (!mpvparse->last_sc)
*skipsize = mpvparse->last_sc = GST_BUFFER_SIZE (buf) - 3;
*skipsize = mpvparse->last_sc = buf_size - 3;
else if (mpvparse->typeoffsize)
mpvparse->last_sc = GST_BUFFER_SIZE (buf) - 3;
mpvparse->last_sc = buf_size - 3;
else
*skipsize = 0;
@ -561,16 +577,16 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse)
GstCaps *caps = NULL;
/* only update if no src caps yet or explicitly triggered */
if (G_LIKELY (GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (mpvparse)) &&
if (G_LIKELY (gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (mpvparse)) &&
!mpvparse->update_caps))
return;
/* carry over input caps as much as possible; override with our own stuff */
caps = GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (mpvparse));
caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (mpvparse));
if (caps) {
caps = gst_caps_copy (caps);
caps = gst_caps_make_writable (caps);
} else {
caps = gst_caps_new_simple ("video/mpeg", NULL);
caps = gst_caps_new_empty_simple ("video/mpeg");
}
/* typically we don't output buffers until we have properly parsed some
@ -722,13 +738,11 @@ gst_mpegv_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
/* codec tag */
codec = g_strdup_printf ("MPEG %d Video", mpvparse->mpeg_version);
taglist = gst_tag_list_new ();
gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE,
GST_TAG_VIDEO_CODEC, codec, NULL);
taglist = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
g_free (codec);
gst_element_found_tags_for_pad (GST_ELEMENT (mpvparse),
GST_BASE_PARSE_SRC_PAD (mpvparse), taglist);
gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (mpvparse),
gst_event_new_tag (taglist));
mpvparse->send_codec_tag = FALSE;
}
@ -756,7 +770,7 @@ gst_mpegv_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
/* best possible parse attempt,
* src caps are based on sink caps so it will end up in there
* whether sucessful or not */
gst_mpegv_parse_process_config (mpvparse, buf, GST_BUFFER_SIZE (buf));
gst_mpegv_parse_process_config (mpvparse, buf, gst_buffer_get_size (buf));
}
/* let's not interfere and accept regardless of config parsing success */

View file

@ -73,14 +73,18 @@ gst_h263_parse_get_params (H263Params * params, GstBuffer * buffer,
};
GstBitReader br;
guint8 *buf_data;
gsize buf_size;
guint8 tr;
guint32 psc = 0, temp32;
guint8 temp8, pquant;
gboolean hasplusptype;
buf_data = gst_buffer_map (buffer, &buf_size, NULL, GST_MAP_READ);
/* FIXME: we can optimise a little by checking the value of available
* instead of calling using the bit reader's get_bits_* functions. */
gst_bit_reader_init_from_buffer (&br, buffer);
gst_bit_reader_init (&br, buf_data, buf_size);
/* Default PCF is CIF PCF = 30000/1001 */
params->pcfnum = 30000;
@ -445,10 +449,12 @@ gst_h263_parse_get_params (H263Params * params, GstBuffer * buffer,
done:
*state = GOT_HEADER;
more:
gst_buffer_unmap (buffer, buf_data, buf_size);
return GST_FLOW_OK;
beach:
*state = PASSTHROUGH;
gst_buffer_unmap (buffer, buf_data, buf_size);
return GST_FLOW_OK;
}