GstCaps * caps);
static GstCaps *gst_dirac_parse_get_sink_caps (GstBaseParse * parse,
GstCaps * filter);
-static gboolean gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
-static GstFlowReturn gst_dirac_parse_parse_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame);
+static GstFlowReturn gst_dirac_parse_handle_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame, gint * skipsize);
static gboolean gst_dirac_parse_convert (GstBaseParse * parse,
GstFormat src_format, gint64 src_value, GstFormat dest_format,
gint64 * dest_value);
GST_DEBUG_FUNCPTR (gst_dirac_parse_set_sink_caps);
base_parse_class->get_sink_caps =
GST_DEBUG_FUNCPTR (gst_dirac_parse_get_sink_caps);
- base_parse_class->check_valid_frame =
- GST_DEBUG_FUNCPTR (gst_dirac_parse_check_valid_frame);
- base_parse_class->parse_frame =
- GST_DEBUG_FUNCPTR (gst_dirac_parse_parse_frame);
+ base_parse_class->handle_frame =
+ GST_DEBUG_FUNCPTR (gst_dirac_parse_handle_frame);
base_parse_class->convert = GST_DEBUG_FUNCPTR (gst_dirac_parse_convert);
base_parse_class->event = GST_DEBUG_FUNCPTR (gst_dirac_parse_event);
base_parse_class->src_event = GST_DEBUG_FUNCPTR (gst_dirac_parse_src_event);
return TRUE;
}
-static gboolean
-gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_dirac_parse_handle_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame, gint * skipsize)
{
int off;
guint32 next_header;
gsize size;
gboolean have_picture = FALSE;
int offset;
+ guint framesize = 0;
gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
data = map.data;
size = map.size;
- if (G_UNLIKELY (size < 13))
+ if (G_UNLIKELY (size < 13)) {
+ *skipsize = 1;
goto out;
+ }
GST_DEBUG ("%" G_GSIZE_FORMAT ": %02x %02x %02x %02x", size, data[0], data[1],
data[2], data[3]);
GST_DEBUG ("offset %d:", offset);
if (offset + 13 >= size) {
- *framesize = offset + 13;
+ framesize = offset + 13;
goto out;
}
offset += next_header;
if (offset >= size) {
- *framesize = offset;
+ framesize = offset;
goto out;
}
}
gst_buffer_unmap (frame->buffer, &map);
- *framesize = offset;
- GST_DEBUG ("framesize %d", *framesize);
+ framesize = offset;
+ GST_DEBUG ("framesize %d", framesize);
- return TRUE;
-
-out:
- gst_buffer_unmap (frame->buffer, &map);
- return FALSE;
-}
-
-static GstFlowReturn
-gst_dirac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
-{
- GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
- GstMapInfo map;
- guint8 *data;
- gsize size;
-
- /* Called when processing incoming buffers. Function should parse
- a checked frame. */
- /* MUST implement */
-
- gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
- data = map.data;
- size = map.size;
-
- //GST_ERROR("got here %d", size);
+ g_assert (framesize <= size);
if (data[4] == SCHRO_PARSE_CODE_SEQUENCE_HEADER) {
GstCaps *caps;
+ GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
DiracSequenceHeader sequence_header;
int ret;
}
}
- gst_buffer_unmap (frame->buffer, &map);
-
gst_base_parse_set_min_frame_size (parse, 13);
+ return gst_base_parse_finish_frame (parse, frame, framesize);
+
+out:
+ gst_buffer_unmap (frame->buffer, &map);
+ if (framesize)
+ gst_base_parse_set_min_frame_size (parse, framesize);
return GST_FLOW_OK;
}
#include <gst/base/gstbytereader.h>
#include "gsth263parse.h"
+#include <string.h>
+
GST_DEBUG_CATEGORY (h263_parse_debug);
#define GST_CAT_DEFAULT h263_parse_debug
static gboolean gst_h263_parse_stop (GstBaseParse * parse);
static gboolean gst_h263_parse_sink_event (GstBaseParse * parse,
GstEvent * event);
-static gboolean gst_h263_parse_check_valid_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
-static GstFlowReturn gst_h263_parse_parse_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame);
+static GstFlowReturn gst_h263_parse_handle_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame, gint * skipsize);
static GstCaps *gst_h263_parse_get_sink_caps (GstBaseParse * parse,
GstCaps * filter);
parse_class->start = GST_DEBUG_FUNCPTR (gst_h263_parse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_h263_parse_stop);
parse_class->event = GST_DEBUG_FUNCPTR (gst_h263_parse_sink_event);
- parse_class->check_valid_frame =
- GST_DEBUG_FUNCPTR (gst_h263_parse_check_valid_frame);
- parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_h263_parse_parse_frame);
+ parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_h263_parse_handle_frame);
parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_h263_parse_get_sink_caps);
}
gst_caps_unref (caps);
}
-static gboolean
-gst_h263_parse_check_valid_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_h263_parse_handle_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame, gint * skipsize)
{
GstH263Parse *h263parse;
GstBuffer *buffer;
guint psc_pos, next_psc_pos;
gsize size;
+ H263Params params = { 0, };
+ GstFlowReturn res = GST_FLOW_OK;
h263parse = GST_H263_PARSE (parse);
buffer = frame->buffer;
size = gst_buffer_get_size (buffer);
- if (size < 3)
- return FALSE;
+ if (size < 3) {
+ *skipsize = 1;
+ return GST_FLOW_OK;
+ }
psc_pos = find_psc (buffer, 0);
goto more;
}
+ /* need to skip */
+ if (psc_pos > 0)
+ goto more;
+
/* Found the start of the frame, now try to find the end */
next_psc_pos = psc_pos + 3;
next_psc_pos = find_psc (buffer, next_psc_pos);
/* If this is the first frame, parse and set srcpad caps */
if (h263parse->state == PARSING) {
- H263Params params = { 0, };
- GstFlowReturn res;
-
res = gst_h263_parse_get_params (¶ms, buffer, FALSE, &h263parse->state);
if (res != GST_FLOW_OK || h263parse->state != GOT_HEADER) {
GST_WARNING ("Couldn't parse header - setting passthrough mode");
gst_h263_parse_set_src_caps (h263parse, ¶ms);
gst_base_parse_set_passthrough (parse, FALSE);
}
+ memset (¶ms, 0, sizeof (params));
}
- *skipsize = psc_pos;
- *framesize = next_psc_pos - psc_pos;
-
/* XXX: After getting a keyframe, should we adjust min_frame_size to
* something smaller so we don't end up collecting too many non-keyframes? */
- GST_DEBUG_OBJECT (h263parse, "found a frame of size %d at pos %d",
- *framesize, *skipsize);
-
- return TRUE;
-
-more:
- /* ask for best next available */
- *framesize = G_MAXUINT;
-
- *skipsize = psc_pos;
-
- return FALSE;
-}
-
-static GstFlowReturn
-gst_h263_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
-{
- GstH263Parse *h263parse;
- GstBuffer *buffer;
- GstFlowReturn res;
- H263Params params = { 0, };
-
- h263parse = GST_H263_PARSE (parse);
- buffer = frame->buffer;
+ GST_DEBUG_OBJECT (h263parse, "found a frame of size %u at pos %u",
+ next_psc_pos, psc_pos);
res = gst_h263_parse_get_params (¶ms, buffer, TRUE, &h263parse->state);
if (res != GST_FLOW_OK)
- goto out;
+ goto more;
if (h263parse->state == PASSTHROUGH || h263parse->state == PARSING) {
/* There's a feature we don't support, or we didn't have enough data to
* passthrough mode and let downstream handle it if it can. */
GST_WARNING ("Couldn't parse header - setting passthrough mode");
gst_base_parse_set_passthrough (parse, TRUE);
- goto out;
+ goto more;
}
- /* h263parse->state is now GOT_HEADER */
-
if (gst_h263_parse_is_delta_unit (¶ms))
GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
else
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
-out:
+ return gst_base_parse_finish_frame (parse, frame, next_psc_pos);
+
+more:
+ *skipsize = psc_pos;
return res;
}
static gboolean gst_h264_parse_start (GstBaseParse * parse);
static gboolean gst_h264_parse_stop (GstBaseParse * parse);
-static gboolean gst_h264_parse_check_valid_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
+static GstFlowReturn gst_h264_parse_handle_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame, gint * skipsize);
static GstFlowReturn gst_h264_parse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
static GstFlowReturn gst_h264_parse_pre_push_frame (GstBaseParse * parse,
/* Override BaseParse vfuncs */
parse_class->start = GST_DEBUG_FUNCPTR (gst_h264_parse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_h264_parse_stop);
- parse_class->check_valid_frame =
- GST_DEBUG_FUNCPTR (gst_h264_parse_check_valid_frame);
- parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_h264_parse_parse_frame);
+ parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_h264_parse_handle_frame);
parse_class->pre_push_frame =
GST_DEBUG_FUNCPTR (gst_h264_parse_pre_push_frame);
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_h264_parse_set_caps);
* see https://bugzilla.gnome.org/show_bug.cgi?id=650093 */
#define GST_BASE_PARSE_FRAME_FLAG_PARSING 0x10000
-static gboolean
-gst_h264_parse_check_valid_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_h264_parse_handle_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame, gint * skipsize)
{
GstH264Parse *h264parse = GST_H264_PARSE (parse);
GstBuffer *buffer = frame->buffer;
GstH264NalParser *nalparser = h264parse->nalparser;
GstH264NalUnit nalu;
GstH264ParserResult pres;
+ gint framesize;
gst_buffer_map (buffer, &map, GST_MAP_READ);
data = map.data;
/* expect at least 3 bytes startcode == sc, and 2 bytes NALU payload */
if (G_UNLIKELY (size < 5)) {
gst_buffer_unmap (buffer, &map);
- return FALSE;
+ *skipsize = 1;
+ return GST_FLOW_OK;
}
/* need to configure aggregation */
}
end:
- *framesize = nalu.offset + nalu.size;
+ framesize = nalu.offset + nalu.size;
gst_buffer_unmap (buffer, &map);
- return TRUE;
+
+ gst_h264_parse_parse_frame (parse, frame);
+
+ return gst_base_parse_finish_frame (parse, frame, framesize);
more:
- /* ask for best next available */
- *framesize = G_MAXUINT;
*skipsize = 0;
/* Restart parsing from here next time */
/* Fall-through. */
out:
gst_buffer_unmap (buffer, &map);
- return FALSE;
+ return GST_FLOW_OK;
skip:
GST_DEBUG_OBJECT (h264parse, "skipping %d", *skipsize);
buf = gst_adapter_take_buffer (h264parse->frame_out, av);
gst_buffer_copy_into (buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
- gst_buffer_replace (&frame->buffer, buf);
+ gst_buffer_replace (&frame->out_buffer, buf);
gst_buffer_unref (buf);
}
/* should already be keyframe/IDR, but it may not have been,
* so mark it as such to avoid being discarded by picky decoder */
GST_BUFFER_FLAG_UNSET (new_buf, GST_BUFFER_FLAG_DELTA_UNIT);
- gst_buffer_replace (&frame->buffer, new_buf);
+ gst_buffer_replace (&frame->out_buffer, new_buf);
gst_buffer_unref (new_buf);
}
}
static gboolean gst_mpeg4vparse_start (GstBaseParse * parse);
static gboolean gst_mpeg4vparse_stop (GstBaseParse * parse);
-static gboolean gst_mpeg4vparse_check_valid_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
+static GstFlowReturn gst_mpeg4vparse_handle_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame, gint * skipsize);
static GstFlowReturn gst_mpeg4vparse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
static GstFlowReturn gst_mpeg4vparse_pre_push_frame (GstBaseParse * parse,
/* Override BaseParse vfuncs */
parse_class->start = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_stop);
- parse_class->check_valid_frame =
- GST_DEBUG_FUNCPTR (gst_mpeg4vparse_check_valid_frame);
- parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_parse_frame);
+ parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_handle_frame);
parse_class->pre_push_frame =
GST_DEBUG_FUNCPTR (gst_mpeg4vparse_pre_push_frame);
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_set_caps);
* see https://bugzilla.gnome.org/show_bug.cgi?id=650093 */
#define GST_BASE_PARSE_FRAME_FLAG_PARSING 0x10000
-static gboolean
-gst_mpeg4vparse_check_valid_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_mpeg4vparse_handle_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame, gint * skipsize)
{
GstMpeg4VParse *mp4vparse = GST_MPEG4VIDEO_PARSE (parse);
GstMpeg4Packet packet;
gsize size;
gint off = 0;
gboolean ret = FALSE;
+ guint framesize;
gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
data = map.data;
retry:
/* at least start code and subsequent byte */
- if (G_UNLIKELY (size - off < 5))
+ if (G_UNLIKELY (size - off < 5)) {
+ *skipsize = 1;
goto out;
+ }
/* avoid stale cached parsing state */
if (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_PARSING)) {
case (GST_MPEG4_PARSER_ERROR):
/* if draining, take all */
if (GST_BASE_PARSE_DRAINING (parse)) {
- *framesize = size;
+ framesize = size;
ret = TRUE;
} else {
/* resume scan where we left it */
mp4vparse->last_sc = size - 3;
- /* request best next available */
- *framesize = G_MAXUINT;
}
goto out;
break;
off = packet.offset;
if (ret) {
- *framesize = off - 3;
+ framesize = off - 3;
} else {
goto next;
}
out:
gst_buffer_unmap (frame->buffer, &map);
- return ret;
+
+ if (ret) {
+ GstFlowReturn res;
+
+ g_assert (framesize <= map.size);
+ res = gst_mpeg4vparse_parse_frame (parse, frame);
+ if (res == GST_BASE_PARSE_FLOW_DROPPED)
+ frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
+ return gst_base_parse_finish_frame (parse, frame, framesize);
+ }
+
+ return GST_FLOW_OK;
}
static void
superbuf = gst_buffer_merge (mp4vparse->config, buffer);
gst_buffer_copy_into (superbuf, buffer, GST_BUFFER_COPY_METADATA, 0,
csize);
- gst_buffer_replace (&frame->buffer, superbuf);
+ gst_buffer_replace (&frame->out_buffer, superbuf);
gst_buffer_unref (superbuf);
} else {
GST_INFO_OBJECT (parse, "... but avoiding duplication");
static gboolean gst_mpegv_parse_start (GstBaseParse * parse);
static gboolean gst_mpegv_parse_stop (GstBaseParse * parse);
-static gboolean gst_mpegv_parse_check_valid_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
+static GstFlowReturn gst_mpegv_parse_handle_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame, gint * skipsize);
static GstFlowReturn gst_mpegv_parse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
static gboolean gst_mpegv_parse_set_caps (GstBaseParse * parse, GstCaps * caps);
/* Override BaseParse vfuncs */
parse_class->start = GST_DEBUG_FUNCPTR (gst_mpegv_parse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_mpegv_parse_stop);
- parse_class->check_valid_frame =
- GST_DEBUG_FUNCPTR (gst_mpegv_parse_check_valid_frame);
- parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_mpegv_parse_parse_frame);
+ parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_mpegv_parse_handle_frame);
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_mpegv_parse_set_caps);
parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_mpegv_parse_get_caps);
parse_class->pre_push_frame =
}
-static gboolean
-gst_mpegv_parse_check_valid_frame (GstBaseParse * parse,
- GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_mpegv_parse_handle_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame, gint * skipsize)
{
GstMpegvParse *mpvparse = GST_MPEGVIDEO_PARSE (parse);
GstBuffer *buf = frame->buffer;
end:
if (fsize > 0) {
- *framesize = fsize;
ret = TRUE;
} else if (GST_BASE_PARSE_DRAINING (parse)) {
- *framesize = buf_size;
+ fsize = buf_size;
ret = TRUE;
} else {
else
*skipsize = 0;
- /* request best next available */
- *framesize = G_MAXUINT;
ret = FALSE;
}
g_list_free (mpvparse->typeoffsize);
mpvparse->typeoffsize = NULL;
- return ret;
+ if (ret) {
+ GstFlowReturn res;
+
+ *skipsize = 0;
+ g_assert (fsize <= buf_size);
+ res = gst_mpegv_parse_parse_frame (parse, frame);
+ if (res == GST_BASE_PARSE_FLOW_DROPPED)
+ frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
+ return gst_base_parse_finish_frame (parse, frame, fsize);
+ }
+
+ return GST_FLOW_OK;
}
static void