mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
videoparsers: adjust to modified baseparse API
This commit is contained in:
parent
ea6a192b13
commit
b10b9cf109
5 changed files with 111 additions and 133 deletions
|
@ -56,10 +56,8 @@ static gboolean gst_dirac_parse_set_sink_caps (GstBaseParse * parse,
|
||||||
GstCaps * caps);
|
GstCaps * caps);
|
||||||
static GstCaps *gst_dirac_parse_get_sink_caps (GstBaseParse * parse,
|
static GstCaps *gst_dirac_parse_get_sink_caps (GstBaseParse * parse,
|
||||||
GstCaps * filter);
|
GstCaps * filter);
|
||||||
static gboolean gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_dirac_parse_handle_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
|
GstBaseParseFrame * frame, gint * skipsize);
|
||||||
static GstFlowReturn gst_dirac_parse_parse_frame (GstBaseParse * parse,
|
|
||||||
GstBaseParseFrame * frame);
|
|
||||||
static gboolean gst_dirac_parse_convert (GstBaseParse * parse,
|
static gboolean gst_dirac_parse_convert (GstBaseParse * parse,
|
||||||
GstFormat src_format, gint64 src_value, GstFormat dest_format,
|
GstFormat src_format, gint64 src_value, GstFormat dest_format,
|
||||||
gint64 * dest_value);
|
gint64 * dest_value);
|
||||||
|
@ -127,10 +125,8 @@ gst_dirac_parse_class_init (GstDiracParseClass * klass)
|
||||||
GST_DEBUG_FUNCPTR (gst_dirac_parse_set_sink_caps);
|
GST_DEBUG_FUNCPTR (gst_dirac_parse_set_sink_caps);
|
||||||
base_parse_class->get_sink_caps =
|
base_parse_class->get_sink_caps =
|
||||||
GST_DEBUG_FUNCPTR (gst_dirac_parse_get_sink_caps);
|
GST_DEBUG_FUNCPTR (gst_dirac_parse_get_sink_caps);
|
||||||
base_parse_class->check_valid_frame =
|
base_parse_class->handle_frame =
|
||||||
GST_DEBUG_FUNCPTR (gst_dirac_parse_check_valid_frame);
|
GST_DEBUG_FUNCPTR (gst_dirac_parse_handle_frame);
|
||||||
base_parse_class->parse_frame =
|
|
||||||
GST_DEBUG_FUNCPTR (gst_dirac_parse_parse_frame);
|
|
||||||
base_parse_class->convert = GST_DEBUG_FUNCPTR (gst_dirac_parse_convert);
|
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->event = GST_DEBUG_FUNCPTR (gst_dirac_parse_event);
|
||||||
base_parse_class->src_event = GST_DEBUG_FUNCPTR (gst_dirac_parse_src_event);
|
base_parse_class->src_event = GST_DEBUG_FUNCPTR (gst_dirac_parse_src_event);
|
||||||
|
@ -213,9 +209,9 @@ gst_dirac_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static GstFlowReturn
|
||||||
gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
|
gst_dirac_parse_handle_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
{
|
{
|
||||||
int off;
|
int off;
|
||||||
guint32 next_header;
|
guint32 next_header;
|
||||||
|
@ -224,13 +220,16 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
gsize size;
|
gsize size;
|
||||||
gboolean have_picture = FALSE;
|
gboolean have_picture = FALSE;
|
||||||
int offset;
|
int offset;
|
||||||
|
guint framesize = 0;
|
||||||
|
|
||||||
gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
|
gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
|
||||||
data = map.data;
|
data = map.data;
|
||||||
size = map.size;
|
size = map.size;
|
||||||
|
|
||||||
if (G_UNLIKELY (size < 13))
|
if (G_UNLIKELY (size < 13)) {
|
||||||
|
*skipsize = 1;
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG ("%" G_GSIZE_FORMAT ": %02x %02x %02x %02x", size, data[0], data[1],
|
GST_DEBUG ("%" G_GSIZE_FORMAT ": %02x %02x %02x %02x", size, data[0], data[1],
|
||||||
data[2], data[3]);
|
data[2], data[3]);
|
||||||
|
@ -261,7 +260,7 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
GST_DEBUG ("offset %d:", offset);
|
GST_DEBUG ("offset %d:", offset);
|
||||||
|
|
||||||
if (offset + 13 >= size) {
|
if (offset + 13 >= size) {
|
||||||
*framesize = offset + 13;
|
framesize = offset + 13;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,43 +283,21 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
|
|
||||||
offset += next_header;
|
offset += next_header;
|
||||||
if (offset >= size) {
|
if (offset >= size) {
|
||||||
*framesize = offset;
|
framesize = offset;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_unmap (frame->buffer, &map);
|
gst_buffer_unmap (frame->buffer, &map);
|
||||||
|
|
||||||
*framesize = offset;
|
framesize = offset;
|
||||||
GST_DEBUG ("framesize %d", *framesize);
|
GST_DEBUG ("framesize %d", framesize);
|
||||||
|
|
||||||
return TRUE;
|
g_assert (framesize <= size);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (data[4] == SCHRO_PARSE_CODE_SEQUENCE_HEADER) {
|
if (data[4] == SCHRO_PARSE_CODE_SEQUENCE_HEADER) {
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
|
||||||
DiracSequenceHeader sequence_header;
|
DiracSequenceHeader sequence_header;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -349,10 +326,14 @@ gst_dirac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_unmap (frame->buffer, &map);
|
|
||||||
|
|
||||||
gst_base_parse_set_min_frame_size (parse, 13);
|
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;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include <gst/base/gstbytereader.h>
|
#include <gst/base/gstbytereader.h>
|
||||||
#include "gsth263parse.h"
|
#include "gsth263parse.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY (h263_parse_debug);
|
GST_DEBUG_CATEGORY (h263_parse_debug);
|
||||||
#define GST_CAT_DEFAULT h263_parse_debug
|
#define GST_CAT_DEFAULT h263_parse_debug
|
||||||
|
|
||||||
|
@ -54,10 +56,8 @@ static gboolean gst_h263_parse_start (GstBaseParse * parse);
|
||||||
static gboolean gst_h263_parse_stop (GstBaseParse * parse);
|
static gboolean gst_h263_parse_stop (GstBaseParse * parse);
|
||||||
static gboolean gst_h263_parse_sink_event (GstBaseParse * parse,
|
static gboolean gst_h263_parse_sink_event (GstBaseParse * parse,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
static gboolean gst_h263_parse_check_valid_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_h263_parse_handle_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
|
GstBaseParseFrame * frame, gint * skipsize);
|
||||||
static GstFlowReturn gst_h263_parse_parse_frame (GstBaseParse * parse,
|
|
||||||
GstBaseParseFrame * frame);
|
|
||||||
static GstCaps *gst_h263_parse_get_sink_caps (GstBaseParse * parse,
|
static GstCaps *gst_h263_parse_get_sink_caps (GstBaseParse * parse,
|
||||||
GstCaps * filter);
|
GstCaps * filter);
|
||||||
|
|
||||||
|
@ -83,9 +83,7 @@ gst_h263_parse_class_init (GstH263ParseClass * klass)
|
||||||
parse_class->start = GST_DEBUG_FUNCPTR (gst_h263_parse_start);
|
parse_class->start = GST_DEBUG_FUNCPTR (gst_h263_parse_start);
|
||||||
parse_class->stop = GST_DEBUG_FUNCPTR (gst_h263_parse_stop);
|
parse_class->stop = GST_DEBUG_FUNCPTR (gst_h263_parse_stop);
|
||||||
parse_class->event = GST_DEBUG_FUNCPTR (gst_h263_parse_sink_event);
|
parse_class->event = GST_DEBUG_FUNCPTR (gst_h263_parse_sink_event);
|
||||||
parse_class->check_valid_frame =
|
parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_h263_parse_handle_frame);
|
||||||
GST_DEBUG_FUNCPTR (gst_h263_parse_check_valid_frame);
|
|
||||||
parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_h263_parse_parse_frame);
|
|
||||||
parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_h263_parse_get_sink_caps);
|
parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_h263_parse_get_sink_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,21 +254,25 @@ gst_h263_parse_set_src_caps (GstH263Parse * h263parse,
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static GstFlowReturn
|
||||||
gst_h263_parse_check_valid_frame (GstBaseParse * parse,
|
gst_h263_parse_handle_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
{
|
{
|
||||||
GstH263Parse *h263parse;
|
GstH263Parse *h263parse;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
guint psc_pos, next_psc_pos;
|
guint psc_pos, next_psc_pos;
|
||||||
gsize size;
|
gsize size;
|
||||||
|
H263Params params = { 0, };
|
||||||
|
GstFlowReturn res = GST_FLOW_OK;
|
||||||
|
|
||||||
h263parse = GST_H263_PARSE (parse);
|
h263parse = GST_H263_PARSE (parse);
|
||||||
buffer = frame->buffer;
|
buffer = frame->buffer;
|
||||||
size = gst_buffer_get_size (buffer);
|
size = gst_buffer_get_size (buffer);
|
||||||
|
|
||||||
if (size < 3)
|
if (size < 3) {
|
||||||
return FALSE;
|
*skipsize = 1;
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
|
|
||||||
psc_pos = find_psc (buffer, 0);
|
psc_pos = find_psc (buffer, 0);
|
||||||
|
|
||||||
|
@ -283,6 +285,10 @@ gst_h263_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
goto more;
|
goto more;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* need to skip */
|
||||||
|
if (psc_pos > 0)
|
||||||
|
goto more;
|
||||||
|
|
||||||
/* Found the start of the frame, now try to find the end */
|
/* Found the start of the frame, now try to find the end */
|
||||||
next_psc_pos = psc_pos + 3;
|
next_psc_pos = psc_pos + 3;
|
||||||
next_psc_pos = find_psc (buffer, next_psc_pos);
|
next_psc_pos = find_psc (buffer, next_psc_pos);
|
||||||
|
@ -299,9 +305,6 @@ gst_h263_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
|
|
||||||
/* If this is the first frame, parse and set srcpad caps */
|
/* If this is the first frame, parse and set srcpad caps */
|
||||||
if (h263parse->state == PARSING) {
|
if (h263parse->state == PARSING) {
|
||||||
H263Params params = { 0, };
|
|
||||||
GstFlowReturn res;
|
|
||||||
|
|
||||||
res = gst_h263_parse_get_params (¶ms, buffer, FALSE, &h263parse->state);
|
res = gst_h263_parse_get_params (¶ms, buffer, FALSE, &h263parse->state);
|
||||||
if (res != GST_FLOW_OK || h263parse->state != GOT_HEADER) {
|
if (res != GST_FLOW_OK || h263parse->state != GOT_HEADER) {
|
||||||
GST_WARNING ("Couldn't parse header - setting passthrough mode");
|
GST_WARNING ("Couldn't parse header - setting passthrough mode");
|
||||||
|
@ -311,42 +314,18 @@ gst_h263_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
gst_h263_parse_set_src_caps (h263parse, ¶ms);
|
gst_h263_parse_set_src_caps (h263parse, ¶ms);
|
||||||
gst_base_parse_set_passthrough (parse, FALSE);
|
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
|
/* 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? */
|
* 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",
|
GST_DEBUG_OBJECT (h263parse, "found a frame of size %u at pos %u",
|
||||||
*framesize, *skipsize);
|
next_psc_pos, psc_pos);
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
res = gst_h263_parse_get_params (¶ms, buffer, TRUE, &h263parse->state);
|
res = gst_h263_parse_get_params (¶ms, buffer, TRUE, &h263parse->state);
|
||||||
if (res != GST_FLOW_OK)
|
if (res != GST_FLOW_OK)
|
||||||
goto out;
|
goto more;
|
||||||
|
|
||||||
if (h263parse->state == PASSTHROUGH || h263parse->state == PARSING) {
|
if (h263parse->state == PASSTHROUGH || h263parse->state == PARSING) {
|
||||||
/* There's a feature we don't support, or we didn't have enough data to
|
/* There's a feature we don't support, or we didn't have enough data to
|
||||||
|
@ -354,17 +333,18 @@ gst_h263_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
* passthrough mode and let downstream handle it if it can. */
|
* passthrough mode and let downstream handle it if it can. */
|
||||||
GST_WARNING ("Couldn't parse header - setting passthrough mode");
|
GST_WARNING ("Couldn't parse header - setting passthrough mode");
|
||||||
gst_base_parse_set_passthrough (parse, TRUE);
|
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))
|
if (gst_h263_parse_is_delta_unit (¶ms))
|
||||||
GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
else
|
else
|
||||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,8 +79,8 @@ static void gst_h264_parse_finalize (GObject * object);
|
||||||
|
|
||||||
static gboolean gst_h264_parse_start (GstBaseParse * parse);
|
static gboolean gst_h264_parse_start (GstBaseParse * parse);
|
||||||
static gboolean gst_h264_parse_stop (GstBaseParse * parse);
|
static gboolean gst_h264_parse_stop (GstBaseParse * parse);
|
||||||
static gboolean gst_h264_parse_check_valid_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_h264_parse_handle_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
|
GstBaseParseFrame * frame, gint * skipsize);
|
||||||
static GstFlowReturn gst_h264_parse_parse_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_h264_parse_parse_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame);
|
GstBaseParseFrame * frame);
|
||||||
static GstFlowReturn gst_h264_parse_pre_push_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_h264_parse_pre_push_frame (GstBaseParse * parse,
|
||||||
|
@ -124,9 +124,7 @@ gst_h264_parse_class_init (GstH264ParseClass * klass)
|
||||||
/* Override BaseParse vfuncs */
|
/* Override BaseParse vfuncs */
|
||||||
parse_class->start = GST_DEBUG_FUNCPTR (gst_h264_parse_start);
|
parse_class->start = GST_DEBUG_FUNCPTR (gst_h264_parse_start);
|
||||||
parse_class->stop = GST_DEBUG_FUNCPTR (gst_h264_parse_stop);
|
parse_class->stop = GST_DEBUG_FUNCPTR (gst_h264_parse_stop);
|
||||||
parse_class->check_valid_frame =
|
parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_h264_parse_handle_frame);
|
||||||
GST_DEBUG_FUNCPTR (gst_h264_parse_check_valid_frame);
|
|
||||||
parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_h264_parse_parse_frame);
|
|
||||||
parse_class->pre_push_frame =
|
parse_class->pre_push_frame =
|
||||||
GST_DEBUG_FUNCPTR (gst_h264_parse_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);
|
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_h264_parse_set_caps);
|
||||||
|
@ -645,9 +643,9 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data,
|
||||||
* see https://bugzilla.gnome.org/show_bug.cgi?id=650093 */
|
* see https://bugzilla.gnome.org/show_bug.cgi?id=650093 */
|
||||||
#define GST_BASE_PARSE_FRAME_FLAG_PARSING 0x10000
|
#define GST_BASE_PARSE_FRAME_FLAG_PARSING 0x10000
|
||||||
|
|
||||||
static gboolean
|
static GstFlowReturn
|
||||||
gst_h264_parse_check_valid_frame (GstBaseParse * parse,
|
gst_h264_parse_handle_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
{
|
{
|
||||||
GstH264Parse *h264parse = GST_H264_PARSE (parse);
|
GstH264Parse *h264parse = GST_H264_PARSE (parse);
|
||||||
GstBuffer *buffer = frame->buffer;
|
GstBuffer *buffer = frame->buffer;
|
||||||
|
@ -659,6 +657,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
GstH264NalParser *nalparser = h264parse->nalparser;
|
GstH264NalParser *nalparser = h264parse->nalparser;
|
||||||
GstH264NalUnit nalu;
|
GstH264NalUnit nalu;
|
||||||
GstH264ParserResult pres;
|
GstH264ParserResult pres;
|
||||||
|
gint framesize;
|
||||||
|
|
||||||
gst_buffer_map (buffer, &map, GST_MAP_READ);
|
gst_buffer_map (buffer, &map, GST_MAP_READ);
|
||||||
data = map.data;
|
data = map.data;
|
||||||
|
@ -667,7 +666,8 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
/* expect at least 3 bytes startcode == sc, and 2 bytes NALU payload */
|
/* expect at least 3 bytes startcode == sc, and 2 bytes NALU payload */
|
||||||
if (G_UNLIKELY (size < 5)) {
|
if (G_UNLIKELY (size < 5)) {
|
||||||
gst_buffer_unmap (buffer, &map);
|
gst_buffer_unmap (buffer, &map);
|
||||||
return FALSE;
|
*skipsize = 1;
|
||||||
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* need to configure aggregation */
|
/* need to configure aggregation */
|
||||||
|
@ -820,14 +820,15 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
*framesize = nalu.offset + nalu.size;
|
framesize = nalu.offset + nalu.size;
|
||||||
|
|
||||||
gst_buffer_unmap (buffer, &map);
|
gst_buffer_unmap (buffer, &map);
|
||||||
return TRUE;
|
|
||||||
|
gst_h264_parse_parse_frame (parse, frame);
|
||||||
|
|
||||||
|
return gst_base_parse_finish_frame (parse, frame, framesize);
|
||||||
|
|
||||||
more:
|
more:
|
||||||
/* ask for best next available */
|
|
||||||
*framesize = G_MAXUINT;
|
|
||||||
*skipsize = 0;
|
*skipsize = 0;
|
||||||
|
|
||||||
/* Restart parsing from here next time */
|
/* Restart parsing from here next time */
|
||||||
|
@ -837,7 +838,7 @@ more:
|
||||||
/* Fall-through. */
|
/* Fall-through. */
|
||||||
out:
|
out:
|
||||||
gst_buffer_unmap (buffer, &map);
|
gst_buffer_unmap (buffer, &map);
|
||||||
return FALSE;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
GST_DEBUG_OBJECT (h264parse, "skipping %d", *skipsize);
|
GST_DEBUG_OBJECT (h264parse, "skipping %d", *skipsize);
|
||||||
|
@ -1321,7 +1322,7 @@ gst_h264_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
|
|
||||||
buf = gst_adapter_take_buffer (h264parse->frame_out, av);
|
buf = gst_adapter_take_buffer (h264parse->frame_out, av);
|
||||||
gst_buffer_copy_into (buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
|
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);
|
gst_buffer_unref (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1541,7 +1542,7 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
/* should already be keyframe/IDR, but it may not have been,
|
/* should already be keyframe/IDR, but it may not have been,
|
||||||
* so mark it as such to avoid being discarded by picky decoder */
|
* 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_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);
|
gst_buffer_unref (new_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,8 +70,8 @@ G_DEFINE_TYPE (GstMpeg4VParse, gst_mpeg4vparse, GST_TYPE_BASE_PARSE);
|
||||||
|
|
||||||
static gboolean gst_mpeg4vparse_start (GstBaseParse * parse);
|
static gboolean gst_mpeg4vparse_start (GstBaseParse * parse);
|
||||||
static gboolean gst_mpeg4vparse_stop (GstBaseParse * parse);
|
static gboolean gst_mpeg4vparse_stop (GstBaseParse * parse);
|
||||||
static gboolean gst_mpeg4vparse_check_valid_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_mpeg4vparse_handle_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
|
GstBaseParseFrame * frame, gint * skipsize);
|
||||||
static GstFlowReturn gst_mpeg4vparse_parse_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_mpeg4vparse_parse_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame);
|
GstBaseParseFrame * frame);
|
||||||
static GstFlowReturn gst_mpeg4vparse_pre_push_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_mpeg4vparse_pre_push_frame (GstBaseParse * parse,
|
||||||
|
@ -166,9 +166,7 @@ gst_mpeg4vparse_class_init (GstMpeg4VParseClass * klass)
|
||||||
/* Override BaseParse vfuncs */
|
/* Override BaseParse vfuncs */
|
||||||
parse_class->start = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_start);
|
parse_class->start = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_start);
|
||||||
parse_class->stop = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_stop);
|
parse_class->stop = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_stop);
|
||||||
parse_class->check_valid_frame =
|
parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_handle_frame);
|
||||||
GST_DEBUG_FUNCPTR (gst_mpeg4vparse_check_valid_frame);
|
|
||||||
parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_parse_frame);
|
|
||||||
parse_class->pre_push_frame =
|
parse_class->pre_push_frame =
|
||||||
GST_DEBUG_FUNCPTR (gst_mpeg4vparse_pre_push_frame);
|
GST_DEBUG_FUNCPTR (gst_mpeg4vparse_pre_push_frame);
|
||||||
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_set_caps);
|
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_set_caps);
|
||||||
|
@ -363,9 +361,9 @@ gst_mpeg4vparse_process_sc (GstMpeg4VParse * mp4vparse, GstMpeg4Packet * packet,
|
||||||
* see https://bugzilla.gnome.org/show_bug.cgi?id=650093 */
|
* see https://bugzilla.gnome.org/show_bug.cgi?id=650093 */
|
||||||
#define GST_BASE_PARSE_FRAME_FLAG_PARSING 0x10000
|
#define GST_BASE_PARSE_FRAME_FLAG_PARSING 0x10000
|
||||||
|
|
||||||
static gboolean
|
static GstFlowReturn
|
||||||
gst_mpeg4vparse_check_valid_frame (GstBaseParse * parse,
|
gst_mpeg4vparse_handle_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
{
|
{
|
||||||
GstMpeg4VParse *mp4vparse = GST_MPEG4VIDEO_PARSE (parse);
|
GstMpeg4VParse *mp4vparse = GST_MPEG4VIDEO_PARSE (parse);
|
||||||
GstMpeg4Packet packet;
|
GstMpeg4Packet packet;
|
||||||
|
@ -374,6 +372,7 @@ gst_mpeg4vparse_check_valid_frame (GstBaseParse * parse,
|
||||||
gsize size;
|
gsize size;
|
||||||
gint off = 0;
|
gint off = 0;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
guint framesize;
|
||||||
|
|
||||||
gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
|
gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
|
||||||
data = map.data;
|
data = map.data;
|
||||||
|
@ -381,8 +380,10 @@ gst_mpeg4vparse_check_valid_frame (GstBaseParse * parse,
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
/* at least start code and subsequent byte */
|
/* at least start code and subsequent byte */
|
||||||
if (G_UNLIKELY (size - off < 5))
|
if (G_UNLIKELY (size - off < 5)) {
|
||||||
|
*skipsize = 1;
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* avoid stale cached parsing state */
|
/* avoid stale cached parsing state */
|
||||||
if (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_PARSING)) {
|
if (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_PARSING)) {
|
||||||
|
@ -453,13 +454,11 @@ next:
|
||||||
case (GST_MPEG4_PARSER_ERROR):
|
case (GST_MPEG4_PARSER_ERROR):
|
||||||
/* if draining, take all */
|
/* if draining, take all */
|
||||||
if (GST_BASE_PARSE_DRAINING (parse)) {
|
if (GST_BASE_PARSE_DRAINING (parse)) {
|
||||||
*framesize = size;
|
framesize = size;
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
} else {
|
} else {
|
||||||
/* resume scan where we left it */
|
/* resume scan where we left it */
|
||||||
mp4vparse->last_sc = size - 3;
|
mp4vparse->last_sc = size - 3;
|
||||||
/* request best next available */
|
|
||||||
*framesize = G_MAXUINT;
|
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
break;
|
break;
|
||||||
|
@ -472,14 +471,25 @@ next:
|
||||||
off = packet.offset;
|
off = packet.offset;
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
*framesize = off - 3;
|
framesize = off - 3;
|
||||||
} else {
|
} else {
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
gst_buffer_unmap (frame->buffer, &map);
|
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
|
static void
|
||||||
|
@ -694,7 +704,7 @@ gst_mpeg4vparse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
superbuf = gst_buffer_merge (mp4vparse->config, buffer);
|
superbuf = gst_buffer_merge (mp4vparse->config, buffer);
|
||||||
gst_buffer_copy_into (superbuf, buffer, GST_BUFFER_COPY_METADATA, 0,
|
gst_buffer_copy_into (superbuf, buffer, GST_BUFFER_COPY_METADATA, 0,
|
||||||
csize);
|
csize);
|
||||||
gst_buffer_replace (&frame->buffer, superbuf);
|
gst_buffer_replace (&frame->out_buffer, superbuf);
|
||||||
gst_buffer_unref (superbuf);
|
gst_buffer_unref (superbuf);
|
||||||
} else {
|
} else {
|
||||||
GST_INFO_OBJECT (parse, "... but avoiding duplication");
|
GST_INFO_OBJECT (parse, "... but avoiding duplication");
|
||||||
|
|
|
@ -66,8 +66,8 @@ G_DEFINE_TYPE (GstMpegvParse, gst_mpegv_parse, GST_TYPE_BASE_PARSE);
|
||||||
|
|
||||||
static gboolean gst_mpegv_parse_start (GstBaseParse * parse);
|
static gboolean gst_mpegv_parse_start (GstBaseParse * parse);
|
||||||
static gboolean gst_mpegv_parse_stop (GstBaseParse * parse);
|
static gboolean gst_mpegv_parse_stop (GstBaseParse * parse);
|
||||||
static gboolean gst_mpegv_parse_check_valid_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_mpegv_parse_handle_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
|
GstBaseParseFrame * frame, gint * skipsize);
|
||||||
static GstFlowReturn gst_mpegv_parse_parse_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_mpegv_parse_parse_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame);
|
GstBaseParseFrame * frame);
|
||||||
static gboolean gst_mpegv_parse_set_caps (GstBaseParse * parse, GstCaps * caps);
|
static gboolean gst_mpegv_parse_set_caps (GstBaseParse * parse, GstCaps * caps);
|
||||||
|
@ -159,9 +159,7 @@ gst_mpegv_parse_class_init (GstMpegvParseClass * klass)
|
||||||
/* Override BaseParse vfuncs */
|
/* Override BaseParse vfuncs */
|
||||||
parse_class->start = GST_DEBUG_FUNCPTR (gst_mpegv_parse_start);
|
parse_class->start = GST_DEBUG_FUNCPTR (gst_mpegv_parse_start);
|
||||||
parse_class->stop = GST_DEBUG_FUNCPTR (gst_mpegv_parse_stop);
|
parse_class->stop = GST_DEBUG_FUNCPTR (gst_mpegv_parse_stop);
|
||||||
parse_class->check_valid_frame =
|
parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_mpegv_parse_handle_frame);
|
||||||
GST_DEBUG_FUNCPTR (gst_mpegv_parse_check_valid_frame);
|
|
||||||
parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_mpegv_parse_parse_frame);
|
|
||||||
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_mpegv_parse_set_caps);
|
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->get_sink_caps = GST_DEBUG_FUNCPTR (gst_mpegv_parse_get_caps);
|
||||||
parse_class->pre_push_frame =
|
parse_class->pre_push_frame =
|
||||||
|
@ -493,9 +491,9 @@ update_frame_parsing_status (GstMpegvParse * mpvparse,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static GstFlowReturn
|
||||||
gst_mpegv_parse_check_valid_frame (GstBaseParse * parse,
|
gst_mpegv_parse_handle_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
{
|
{
|
||||||
GstMpegvParse *mpvparse = GST_MPEGVIDEO_PARSE (parse);
|
GstMpegvParse *mpvparse = GST_MPEGVIDEO_PARSE (parse);
|
||||||
GstBuffer *buf = frame->buffer;
|
GstBuffer *buf = frame->buffer;
|
||||||
|
@ -547,10 +545,9 @@ gst_mpegv_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (fsize > 0) {
|
if (fsize > 0) {
|
||||||
*framesize = fsize;
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
} else if (GST_BASE_PARSE_DRAINING (parse)) {
|
} else if (GST_BASE_PARSE_DRAINING (parse)) {
|
||||||
*framesize = buf_size;
|
fsize = buf_size;
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -562,8 +559,6 @@ end:
|
||||||
else
|
else
|
||||||
*skipsize = 0;
|
*skipsize = 0;
|
||||||
|
|
||||||
/* request best next available */
|
|
||||||
*framesize = G_MAXUINT;
|
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +566,18 @@ end:
|
||||||
g_list_free (mpvparse->typeoffsize);
|
g_list_free (mpvparse->typeoffsize);
|
||||||
mpvparse->typeoffsize = NULL;
|
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
|
static void
|
||||||
|
|
Loading…
Reference in a new issue