rawparse: port to 0.11

This commit is contained in:
Mark Nauwelaerts 2012-03-20 20:21:37 +01:00
parent 7c4dfc7d7c
commit cc7918de19
6 changed files with 315 additions and 384 deletions

View file

@ -306,7 +306,7 @@ GST_PLUGINS_NONPORTED=" aiff asfmux \
hdvparse hls id3tag inter interlace ivfparse jpegformat jp2kdecimator \
kate liveadder legacyresample librfb mpegtsmux \
mpegpsmux mve mxf mythtv nsf nuvdemux \
patchdetect pnm rawparse real \
patchdetect pnm real \
sdi siren speed subenc stereo tta videofilters \
videomeasure videosignal vmnc \
decklink fbdev linsys shm vcd \

View file

@ -28,14 +28,17 @@
# include "config.h"
#endif
/* FIXME 0.11: suppress warnings for deprecated API such as g_value_array stuff
* for now with newer GLib versions (>= 2.31.0) */
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#include "gstaudioparse.h"
#include <gst/audio/multichannel.h>
#include <string.h>
typedef enum
{
GST_AUDIO_PARSE_FORMAT_INT,
GST_AUDIO_PARSE_FORMAT_FLOAT,
GST_AUDIO_PARSE_FORMAT_RAW,
GST_AUDIO_PARSE_FORMAT_MULAW,
GST_AUDIO_PARSE_FORMAT_ALAW
} GstAudioParseFormat;
@ -63,24 +66,20 @@ enum
{
PROP_0,
PROP_FORMAT,
PROP_RAW_FORMAT,
PROP_RATE,
PROP_CHANNELS,
PROP_ENDIANNESS,
PROP_WIDTH,
PROP_DEPTH,
PROP_SIGNED,
PROP_INTERLEAVED,
PROP_CHANNEL_POSITIONS
};
#define GST_AUDIO_PARSE_FORMAT (gst_audio_parse_format_get_type ())
static GType
gst_audio_parse_format_get_type (void)
{
static GType audio_parse_format_type = 0;
static const GEnumValue format_types[] = {
{GST_AUDIO_PARSE_FORMAT_INT, "Integer", "int"},
{GST_AUDIO_PARSE_FORMAT_FLOAT, "Floating Point", "float"},
{GST_AUDIO_PARSE_FORMAT_RAW, "Raw", "raw"},
{GST_AUDIO_PARSE_FORMAT_ALAW, "A-Law", "alaw"},
{GST_AUDIO_PARSE_FORMAT_MULAW, "\302\265-Law", "mulaw"},
{0, NULL, NULL}
@ -94,68 +93,17 @@ gst_audio_parse_format_get_type (void)
return audio_parse_format_type;
}
#define GST_AUDIO_PARSE_ENDIANNESS (gst_audio_parse_endianness_get_type ())
static GType
gst_audio_parse_endianness_get_type (void)
{
static GType audio_parse_endianness_type = 0;
static const GEnumValue endian_types[] = {
{GST_AUDIO_PARSE_ENDIANNESS_LITTLE, "Little Endian", "little"},
{GST_AUDIO_PARSE_ENDIANNESS_BIG, "Big Endian", "big"},
{0, NULL, NULL}
};
if (!audio_parse_endianness_type) {
audio_parse_endianness_type =
g_enum_register_static ("GstAudioParseEndianness", endian_types);
}
return audio_parse_endianness_type;
}
GST_BOILERPLATE (GstAudioParse, gst_audio_parse, GstRawParse,
GST_TYPE_RAW_PARSE);
static void
gst_audio_parse_base_init (gpointer g_class)
{
GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (g_class);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
GstCaps *caps;
GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0,
"audioparse element");
gst_element_class_set_details_simple (gstelement_class, "Audio Parse",
"Filter/Audio",
"Converts stream into audio frames",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
caps =
gst_caps_from_string ("audio/x-raw-int,"
" depth=(int) [ 1, 32 ],"
" width=(int) { 8, 16, 24, 32 },"
" endianness=(int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
" signed=(bool) { TRUE, FALSE },"
" rate=(int) [ 1, MAX ],"
" channels=(int) [ 1, MAX ]; "
"audio/x-raw-float,"
" width=(int) { 32, 64 },"
" endianness=(int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
" rate=(int)[1,MAX], channels=(int)[1,MAX]; "
"audio/x-alaw, rate=(int)[1,MAX], channels=(int)[1,MAX]; "
"audio/x-mulaw, rate=(int)[1,MAX], channels=(int)[1,MAX]");
gst_raw_parse_class_set_src_pad_template (rp_class, caps);
gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, TRUE);
gst_caps_unref (caps);
}
#define gst_audio_parse_parent_class parent_class
G_DEFINE_TYPE (GstAudioParse, gst_audio_parse, GST_TYPE_RAW_PARSE);
static void
gst_audio_parse_class_init (GstAudioParseClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (klass);
GstCaps *caps;
gobject_class->set_property = gst_audio_parse_set_property;
gobject_class->get_property = gst_audio_parse_get_property;
@ -166,37 +114,26 @@ gst_audio_parse_class_init (GstAudioParseClass * klass)
g_object_class_install_property (gobject_class, PROP_FORMAT,
g_param_spec_enum ("format", "Format",
"Format of audio samples in raw stream", GST_AUDIO_PARSE_FORMAT,
GST_AUDIO_PARSE_FORMAT_INT,
GST_AUDIO_PARSE_FORMAT_RAW,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_RAW_FORMAT,
g_param_spec_enum ("raw-format", "Raw Format",
"Format of audio samples in raw stream", GST_TYPE_AUDIO_FORMAT,
GST_AUDIO_FORMAT_S16, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_RATE,
g_param_spec_int ("rate", "Rate", "Rate of audio samples in raw stream",
1, INT_MAX, 44100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_CHANNELS,
g_param_spec_int ("channels", "Channels",
"Number of channels in raw stream", 1, INT_MAX, 2,
"Number of channels in raw stream", 1, 64, 2,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_WIDTH,
g_param_spec_int ("width", "Width",
"Width of audio samples in raw stream", 1, INT_MAX, 16,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_DEPTH,
g_param_spec_int ("depth", "Depth",
"Depth of audio samples in raw stream", 1, INT_MAX, 16,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_SIGNED,
g_param_spec_boolean ("signed", "signed",
"Sign of audio samples in raw stream", TRUE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_ENDIANNESS,
g_param_spec_enum ("endianness", "Endianness",
"Endianness of audio samples in raw stream",
GST_AUDIO_PARSE_ENDIANNESS, G_BYTE_ORDER,
g_object_class_install_property (gobject_class, PROP_INTERLEAVED,
g_param_spec_boolean ("interleaved", "Interleaved Layout",
"True if audio has interleaved layout", TRUE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_CHANNEL_POSITIONS,
@ -208,17 +145,32 @@ gst_audio_parse_class_init (GstAudioParseClass * klass)
GST_AUDIO_CHANNEL_POSITION_NONE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_details_simple (gstelement_class, "Audio Parse",
"Filter/Audio",
"Converts stream into audio frames",
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
caps = gst_caps_from_string (GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL)
", layout = (string) { interleaved, non-interleaved }; "
"audio/x-alaw, rate=(int)[1,MAX], channels=(int)[1,MAX]; "
"audio/x-mulaw, rate=(int)[1,MAX], channels=(int)[1,MAX]");
gst_raw_parse_class_set_src_pad_template (rp_class, caps);
gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, TRUE);
gst_caps_unref (caps);
GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0,
"audioparse element");
}
static void
gst_audio_parse_init (GstAudioParse * ap, GstAudioParseClass * g_class)
gst_audio_parse_init (GstAudioParse * ap)
{
ap->format = GST_AUDIO_PARSE_FORMAT_INT;
ap->format = GST_AUDIO_PARSE_FORMAT_RAW;
ap->raw_format = GST_AUDIO_FORMAT_S16;
ap->channels = 2;
ap->width = 16;
ap->depth = 16;
ap->signedness = TRUE;
ap->endianness = G_BYTE_ORDER;
ap->interleaved = TRUE;
gst_audio_parse_update_frame_size (ap);
gst_raw_parse_set_fps (GST_RAW_PARSE (ap), 44100, 1);
@ -236,23 +188,17 @@ gst_audio_parse_set_property (GObject * object, guint prop_id,
case PROP_FORMAT:
ap->format = g_value_get_enum (value);
break;
case PROP_RAW_FORMAT:
ap->raw_format = g_value_get_enum (value);
break;
case PROP_RATE:
gst_raw_parse_set_fps (GST_RAW_PARSE (ap), g_value_get_int (value), 1);
break;
case PROP_CHANNELS:
ap->channels = g_value_get_int (value);
break;
case PROP_WIDTH:
ap->width = g_value_get_int (value);
break;
case PROP_DEPTH:
ap->depth = g_value_get_int (value);
break;
case PROP_SIGNED:
ap->signedness = g_value_get_boolean (value);
break;
case PROP_ENDIANNESS:
ap->endianness = g_value_get_enum (value);
case PROP_INTERLEAVED:
ap->interleaved = g_value_get_boolean (value);
break;
case PROP_CHANNEL_POSITIONS:
if (ap->channel_positions)
@ -278,6 +224,9 @@ gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_FORMAT:
g_value_set_enum (value, ap->format);
break;
case PROP_RAW_FORMAT:
g_value_set_enum (value, ap->raw_format);
break;
case PROP_RATE:{
gint fps_n, fps_d;
@ -288,17 +237,8 @@ gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_CHANNELS:
g_value_set_int (value, ap->channels);
break;
case PROP_WIDTH:
g_value_set_int (value, ap->width);
break;
case PROP_DEPTH:
g_value_set_int (value, ap->depth);
break;
case PROP_SIGNED:
g_value_set_boolean (value, ap->signedness);
break;
case PROP_ENDIANNESS:
g_value_set_enum (value, ap->endianness);
case PROP_INTERLEAVED:
g_value_set_boolean (value, ap->interleaved);
break;
case PROP_CHANNEL_POSITIONS:
g_value_set_boxed (value, ap->channel_positions);
@ -319,6 +259,9 @@ gst_audio_parse_finalize (GObject * object)
ap->channel_positions = NULL;
}
g_free (ap->channel_pos);
g_free (ap->channel_order);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -332,11 +275,18 @@ gst_audio_parse_update_frame_size (GstAudioParse * ap)
case GST_AUDIO_PARSE_FORMAT_MULAW:
width = 8;
break;
case GST_AUDIO_PARSE_FORMAT_INT:
case GST_AUDIO_PARSE_FORMAT_FLOAT:
case GST_AUDIO_PARSE_FORMAT_RAW:
default:
width = ap->width;
{
GstAudioInfo info;
gst_audio_info_init (&info);
/* rate, etc do not really matter here */
gst_audio_info_set_format (&info, ap->raw_format, 44100, ap->channels,
NULL);
width = GST_AUDIO_INFO_WIDTH (&info);
break;
}
}
framesize = (width / 8) * ap->channels;
@ -344,13 +294,12 @@ gst_audio_parse_update_frame_size (GstAudioParse * ap)
gst_raw_parse_set_framesize (GST_RAW_PARSE (ap), framesize);
}
static gboolean
gst_audio_parse_check_channel_positions (GValueArray * positions)
static GstAudioChannelPosition *
gst_audio_parse_get_channel_positions (GValueArray * positions)
{
gint i;
guint channels;
GstAudioChannelPosition *pos;
gboolean ret;
channels = positions->n_values;
pos = g_new (GstAudioChannelPosition, positions->n_values);
@ -361,86 +310,89 @@ gst_audio_parse_check_channel_positions (GValueArray * positions)
pos[i] = g_value_get_enum (v);
}
ret = gst_audio_check_channel_positions (pos, channels);
g_free (pos);
return ret;
return pos;
}
static void
gst_audio_parse_set_channel_positions (GstAudioParse * ap, GstStructure * s)
gst_audio_parse_setup_channel_positions (GstAudioParse * ap)
{
GValue pos_array = { 0, };
gint i;
GstAudioChannelPosition *pos, *to;
if (!ap->channel_positions && ap->channels <= 2) {
/* Implicit mapping for 1- and 2-channel audio is okay */
g_free (ap->channel_pos);
g_free (ap->channel_order);
ap->channel_pos = NULL;
ap->channel_order = NULL;
if (!ap->channel_positions) {
GST_DEBUG_OBJECT (ap, "no channel positions");
/* implicit mapping for 1- and 2-channel audio is okay */
/* will come up with one in other cases also */
return;
}
g_value_init (&pos_array, GST_TYPE_ARRAY);
if (ap->channel_positions
&& ap->channels == ap->channel_positions->n_values
&& gst_audio_parse_check_channel_positions (ap->channel_positions)) {
GST_DEBUG_OBJECT (ap, "Using provided channel positions");
for (i = 0; i < ap->channels; i++)
gst_value_array_append_value (&pos_array,
g_value_array_get_nth (ap->channel_positions, i));
} else {
/* >2 channels and no explicit mapping */
GValue pos_none = { 0, };
GST_WARNING_OBJECT (ap, "Using NONE channel positions");
g_value_init (&pos_none, GST_TYPE_AUDIO_CHANNEL_POSITION);
g_value_set_enum (&pos_none, GST_AUDIO_CHANNEL_POSITION_NONE);
for (i = 0; i < ap->channels; i++)
gst_value_array_append_value (&pos_array, &pos_none);
g_value_unset (&pos_none);
pos = gst_audio_parse_get_channel_positions (ap->channel_positions);
if (ap->channels != ap->channel_positions->n_values ||
!gst_audio_check_valid_channel_positions (pos, ap->channels, FALSE)) {
GST_DEBUG_OBJECT (ap, "invalid channel position");
g_free (pos);
return;
}
gst_structure_set_value (s, "channel-positions", &pos_array);
g_value_unset (&pos_array);
/* ok, got something we can work with now */
to = g_new (GstAudioChannelPosition, ap->channels);
memcpy (to, pos, ap->channels * sizeof (to[0]));
gst_audio_channel_positions_to_valid_order (to, ap->channels);
ap->channel_pos = pos;
ap->channel_order = to;
}
static GstCaps *
gst_audio_parse_get_caps (GstRawParse * rp)
{
GstAudioParse *ap = GST_AUDIO_PARSE (rp);
GstCaps *caps;
GstCaps *caps, *ncaps;
GstAudioInfo info;
gint fps_n, fps_d;
const GValue *val;
gst_raw_parse_get_fps (rp, &fps_n, &fps_d);
gst_audio_parse_setup_channel_positions (ap);
/* yes, even when format not raw */
gst_audio_info_init (&info);
gst_audio_info_set_format (&info, ap->raw_format, fps_n, ap->channels,
ap->channel_order);
info.layout = ap->interleaved ? GST_AUDIO_LAYOUT_INTERLEAVED :
GST_AUDIO_LAYOUT_NON_INTERLEAVED;
caps = gst_audio_info_to_caps (&info);
switch (ap->format) {
case GST_AUDIO_PARSE_FORMAT_INT:
caps = gst_caps_new_simple ("audio/x-raw-int",
"rate", G_TYPE_INT, fps_n,
"channels", G_TYPE_INT, ap->channels,
"width", G_TYPE_INT, ap->width,
"depth", G_TYPE_INT, ap->depth,
"signed", G_TYPE_BOOLEAN, ap->signedness,
"endianness", G_TYPE_INT, ap->endianness, NULL);
break;
case GST_AUDIO_PARSE_FORMAT_FLOAT:
caps = gst_caps_new_simple ("audio/x-raw-float",
"rate", G_TYPE_INT, fps_n,
"channels", G_TYPE_INT, ap->channels,
"width", G_TYPE_INT, ap->width,
"endianness", G_TYPE_INT, ap->endianness, NULL);
case GST_AUDIO_PARSE_FORMAT_RAW:
break;
case GST_AUDIO_PARSE_FORMAT_ALAW:
caps = gst_caps_new_simple ("audio/x-alaw",
ncaps = gst_caps_new_simple ("audio/x-alaw",
"rate", G_TYPE_INT, fps_n,
"channels", G_TYPE_INT, ap->channels, NULL);
/* pick mask stuff from faked raw format */
val = gst_structure_get_value (gst_caps_get_structure (caps, 0),
"channel-mask");
if (val)
gst_caps_set_value (ncaps, "channel-mask", val);
gst_caps_unref (caps);
caps = ncaps;
break;
case GST_AUDIO_PARSE_FORMAT_MULAW:
caps = gst_caps_new_simple ("audio/x-mulaw",
ncaps = gst_caps_new_simple ("audio/x-mulaw",
"rate", G_TYPE_INT, fps_n,
"channels", G_TYPE_INT, ap->channels, NULL);
/* pick mask stuff from faked raw format */
val = gst_structure_get_value (gst_caps_get_structure (caps, 0),
"channel-mask");
if (val)
gst_caps_set_value (ncaps, "channel-mask", val);
gst_caps_unref (caps);
caps = ncaps;
break;
default:
caps = gst_caps_new_empty ();
@ -448,7 +400,5 @@ gst_audio_parse_get_caps (GstRawParse * rp)
break;
}
gst_audio_parse_set_channel_positions (ap, gst_caps_get_structure (caps, 0));
return caps;
}

View file

@ -25,6 +25,7 @@
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <gst/base/gstadapter.h>
#include <gst/audio/audio.h>
#include "gstrawparse.h"
@ -48,12 +49,13 @@ struct _GstAudioParse
/* properties */
gint format;
GstAudioFormat raw_format;
gint channels;
gint width;
gint depth;
gint signedness;
gint endianness;
gboolean interleaved;
GValueArray *channel_positions;
GstAudioChannelPosition *channel_pos;
GstAudioChannelPosition *channel_order;
};
struct _GstAudioParseClass

View file

@ -41,20 +41,23 @@
static void gst_raw_parse_dispose (GObject * object);
static gboolean gst_raw_parse_sink_activate (GstPad * sinkpad);
static gboolean gst_raw_parse_sink_activatepull (GstPad * sinkpad,
gboolean active);
static gboolean gst_raw_parse_sink_activate (GstPad * sinkpad,
GstObject * parent);
static gboolean gst_raw_parse_sink_activatemode (GstPad * sinkpad,
GstObject * parent, GstPadMode mode, gboolean active);
static void gst_raw_parse_loop (GstElement * element);
static GstStateChangeReturn gst_raw_parse_change_state (GstElement * element,
GstStateChange transition);
static GstFlowReturn gst_raw_parse_chain (GstPad * pad, GstBuffer * buffer);
static gboolean gst_raw_parse_sink_event (GstPad * pad, GstEvent * event);
static gboolean gst_raw_parse_src_event (GstPad * pad, GstEvent * event);
static const GstQueryType *gst_raw_parse_src_query_type (GstPad * pad);
static gboolean gst_raw_parse_src_query (GstPad * pad, GstQuery * query);
static gboolean gst_raw_parse_convert (GstRawParse * rp,
GstFormat src_format, gint64 src_value,
GstFormat dest_format, gint64 * dest_value);
static GstFlowReturn gst_raw_parse_chain (GstPad * pad, GstObject * parent,
GstBuffer * buffer);
static gboolean gst_raw_parse_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event);
static gboolean gst_raw_parse_src_event (GstPad * pad, GstObject * parent,
GstEvent * event);
static gboolean gst_raw_parse_src_query (GstPad * pad, GstObject * parent,
GstQuery * query);
static gboolean gst_raw_parse_convert (GstRawParse * rp, GstFormat src_format,
gint64 src_value, GstFormat dest_format, gint64 * dest_value);
static gboolean gst_raw_parse_handle_seek_pull (GstRawParse * rp,
GstEvent * event);
@ -69,18 +72,29 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_DEBUG_CATEGORY_STATIC (gst_raw_parse_debug);
#define GST_CAT_DEFAULT gst_raw_parse_debug
GST_BOILERPLATE (GstRawParse, gst_raw_parse, GstElement, GST_TYPE_ELEMENT);
static void gst_raw_parse_class_init (GstRawParseClass * klass);
static void gst_raw_parse_init (GstRawParse * clip, GstRawParseClass * g_class);
static void
gst_raw_parse_base_init (gpointer g_class)
static GstElementClass *parent_class;
/* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init
* method to get to the padtemplates */
GType
gst_raw_parse_get_type (void)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
static volatile gsize raw_parse_type = 0;
GST_DEBUG_CATEGORY_INIT (gst_raw_parse_debug, "rawparse", 0,
"rawparse element");
if (g_once_init_enter (&raw_parse_type)) {
GType _type;
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&gst_raw_parse_sink_pad_template));
_type = g_type_register_static_simple (GST_TYPE_ELEMENT,
"GstRawParse", sizeof (GstRawParseClass),
(GClassInitFunc) gst_raw_parse_class_init, sizeof (GstRawParse),
(GInstanceInitFunc) gst_raw_parse_init, G_TYPE_FLAG_ABSTRACT);
g_once_init_leave (&raw_parse_type, _type);
}
return raw_parse_type;
}
static void
@ -89,10 +103,18 @@ gst_raw_parse_class_init (GstRawParseClass * klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
gobject_class->dispose = gst_raw_parse_dispose;
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_raw_parse_change_state);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&gst_raw_parse_sink_pad_template));
GST_DEBUG_CATEGORY_INIT (gst_raw_parse_debug, "rawparse", 0,
"rawparse element");
}
static void
@ -110,8 +132,8 @@ gst_raw_parse_init (GstRawParse * rp, GstRawParseClass * g_class)
GST_DEBUG_FUNCPTR (gst_raw_parse_sink_event));
gst_pad_set_activate_function (rp->sinkpad,
GST_DEBUG_FUNCPTR (gst_raw_parse_sink_activate));
gst_pad_set_activatepull_function (rp->sinkpad,
GST_DEBUG_FUNCPTR (gst_raw_parse_sink_activatepull));
gst_pad_set_activatemode_function (rp->sinkpad,
GST_DEBUG_FUNCPTR (gst_raw_parse_sink_activatemode));
gst_element_add_pad (GST_ELEMENT (rp), rp->sinkpad);
src_pad_template = gst_element_class_get_pad_template (element_class, "src");
@ -125,8 +147,6 @@ gst_raw_parse_init (GstRawParse * rp, GstRawParseClass * g_class)
gst_pad_set_event_function (rp->srcpad,
GST_DEBUG_FUNCPTR (gst_raw_parse_src_event));
gst_pad_set_query_type_function (rp->srcpad,
GST_DEBUG_FUNCPTR (gst_raw_parse_src_query_type));
gst_pad_set_query_function (rp->srcpad,
GST_DEBUG_FUNCPTR (gst_raw_parse_src_query));
gst_element_add_pad (GST_ELEMENT (rp), rp->srcpad);
@ -218,7 +238,7 @@ gst_raw_parse_push_buffer (GstRawParse * rp, GstBuffer * buffer)
rpclass = GST_RAW_PARSE_GET_CLASS (rp);
nframes = GST_BUFFER_SIZE (buffer) / rp->framesize;
nframes = gst_buffer_get_size (buffer) / rp->framesize;
if (rp->segment.rate < 0) {
rp->n_frames -= nframes;
@ -238,7 +258,6 @@ gst_raw_parse_push_buffer (GstRawParse * rp, GstBuffer * buffer)
GST_BUFFER_TIMESTAMP (buffer) = rp->segment.start;
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
}
gst_buffer_set_caps (buffer, GST_PAD_CAPS (rp->srcpad));
if (rpclass->set_buffer_flags) {
rpclass->set_buffer_flags (rp, buffer);
@ -250,11 +269,11 @@ gst_raw_parse_push_buffer (GstRawParse * rp, GstBuffer * buffer)
}
if (rp->segment.rate >= 0) {
rp->offset += GST_BUFFER_SIZE (buffer);
rp->offset += gst_buffer_get_size (buffer);
rp->n_frames += nframes;
}
rp->segment.last_stop = GST_BUFFER_TIMESTAMP (buffer);
rp->segment.position = GST_BUFFER_TIMESTAMP (buffer);
GST_LOG_OBJECT (rp, "Pushing buffer with time %" GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
@ -265,9 +284,9 @@ gst_raw_parse_push_buffer (GstRawParse * rp, GstBuffer * buffer)
}
static GstFlowReturn
gst_raw_parse_chain (GstPad * pad, GstBuffer * buffer)
gst_raw_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (pad));
GstRawParse *rp = GST_RAW_PARSE (parent);
GstFlowReturn ret = GST_FLOW_OK;
GstRawParseClass *rp_class = GST_RAW_PARSE_GET_CLASS (rp);
guint buffersize;
@ -298,7 +317,6 @@ gst_raw_parse_chain (GstPad * pad, GstBuffer * buffer)
break;
}
done:
gst_object_unref (rp);
return ret;
@ -323,11 +341,6 @@ gst_raw_parse_loop (GstElement * element)
if (!gst_raw_parse_set_src_caps (rp))
goto no_caps;
if (rp->close_segment) {
GST_DEBUG_OBJECT (rp, "sending close segment");
gst_pad_push_event (rp->srcpad, rp->close_segment);
rp->close_segment = NULL;
}
if (rp->start_segment) {
GST_DEBUG_OBJECT (rp, "sending start segment");
gst_pad_push_event (rp->srcpad, rp->start_segment);
@ -343,13 +356,12 @@ gst_raw_parse_loop (GstElement * element)
if (rp->offset + size > rp->upstream_length) {
GstFormat fmt = GST_FORMAT_BYTES;
if (!gst_pad_query_peer_duration (rp->sinkpad, &fmt,
&rp->upstream_length)) {
if (!gst_pad_peer_query_duration (rp->sinkpad, fmt, &rp->upstream_length)) {
GST_WARNING_OBJECT (rp,
"Could not get upstream duration, trying to pull frame by frame");
size = rp->framesize;
} else if (rp->upstream_length < rp->offset + rp->framesize) {
ret = GST_FLOW_UNEXPECTED;
ret = GST_FLOW_EOS;
goto pause;
} else if (rp->offset + size > rp->upstream_length) {
size = rp->upstream_length - rp->offset;
@ -358,7 +370,7 @@ gst_raw_parse_loop (GstElement * element)
}
} else {
if (rp->offset == 0) {
ret = GST_FLOW_UNEXPECTED;
ret = GST_FLOW_EOS;
goto pause;
} else if (rp->offset < size) {
size -= rp->offset;
@ -376,17 +388,18 @@ gst_raw_parse_loop (GstElement * element)
goto pause;
}
if (GST_BUFFER_SIZE (buffer) < size) {
if (gst_buffer_get_size (buffer) < size) {
GST_DEBUG_OBJECT (rp, "Short read at offset %" G_GINT64_FORMAT
", got only %u of %u bytes", rp->offset, GST_BUFFER_SIZE (buffer),
", got only %u of %u bytes", rp->offset, gst_buffer_get_size (buffer),
size);
if (size > rp->framesize) {
GST_BUFFER_SIZE (buffer) -= GST_BUFFER_SIZE (buffer) % rp->framesize;
gst_buffer_set_size (buffer, gst_buffer_get_size (buffer) -
gst_buffer_get_size (buffer) % rp->framesize);
} else {
gst_buffer_unref (buffer);
buffer = NULL;
ret = GST_FLOW_UNEXPECTED;
ret = GST_FLOW_EOS;
goto pause;
}
}
@ -411,7 +424,7 @@ pause:
GST_LOG_OBJECT (rp, "pausing task, reason %s", reason);
gst_pad_pause_task (rp->sinkpad);
if (ret == GST_FLOW_UNEXPECTED) {
if (ret == GST_FLOW_EOS) {
if (rp->segment.flags & GST_SEEK_FLAG_SEGMENT) {
GstClockTime stop;
@ -427,7 +440,7 @@ pause:
GST_LOG_OBJECT (rp, "Sending EOS, at end of stream");
gst_pad_push_event (rp->srcpad, gst_event_new_eos ());
}
} else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
} else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
GST_ELEMENT_ERROR (rp, STREAM, FAILED,
("Internal data stream error."),
("stream stopped, reason %s", reason));
@ -438,50 +451,68 @@ pause:
}
static gboolean
gst_raw_parse_sink_activate (GstPad * sinkpad)
gst_raw_parse_sink_activate (GstPad * sinkpad, GstObject * parent)
{
if (gst_pad_check_pull_range (sinkpad)) {
GST_RAW_PARSE (GST_PAD_PARENT (sinkpad))->mode = GST_PAD_ACTIVATE_PULL;
return gst_pad_activate_pull (sinkpad, TRUE);
GstQuery *query;
gboolean pull_mode = FALSE;
query = gst_query_new_scheduling ();
if (gst_pad_peer_query (sinkpad, query))
pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
gst_query_unref (query);
if (pull_mode) {
GST_DEBUG ("going to pull mode");
return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
} else {
GST_RAW_PARSE (GST_PAD_PARENT (sinkpad))->mode = GST_PAD_ACTIVATE_PUSH;
return gst_pad_activate_push (sinkpad, TRUE);
GST_DEBUG ("going to push (streaming) mode");
return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
}
}
static gboolean
gst_raw_parse_sink_activatepull (GstPad * sinkpad, gboolean active)
gst_raw_parse_sink_activatemode (GstPad * sinkpad, GstObject * parent,
GstPadMode mode, gboolean active)
{
GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (sinkpad));
GstRawParse *rp = GST_RAW_PARSE (parent);
gboolean result;
if (active) {
GstFormat format;
gint64 duration;
switch (mode) {
case GST_PAD_MODE_PULL:
if (active) {
GstFormat format;
gint64 duration;
/* get the duration in bytes */
format = GST_FORMAT_BYTES;
result = gst_pad_query_peer_duration (sinkpad, &format, &duration);
if (result) {
GST_DEBUG_OBJECT (rp, "got duration %" GST_TIME_FORMAT,
GST_TIME_ARGS (duration));
rp->upstream_length = duration;
/* convert to time */
gst_raw_parse_convert (rp, format, duration, GST_FORMAT_TIME, &duration);
} else {
rp->upstream_length = -1;
duration = -1;
}
gst_segment_set_duration (&rp->segment, GST_FORMAT_TIME, duration);
/* get the duration in bytes */
format = GST_FORMAT_BYTES;
result = gst_pad_peer_query_duration (sinkpad, format, &duration);
if (result) {
GST_DEBUG_OBJECT (rp, "got duration %" GST_TIME_FORMAT,
GST_TIME_ARGS (duration));
rp->upstream_length = duration;
/* convert to time */
gst_raw_parse_convert (rp, format, duration, GST_FORMAT_TIME,
&duration);
} else {
rp->upstream_length = -1;
duration = -1;
}
rp->segment.duration = duration;
result = gst_raw_parse_handle_seek_pull (rp, NULL);
} else {
result = gst_pad_stop_task (sinkpad);
result = gst_raw_parse_handle_seek_pull (rp, NULL);
rp->mode = mode;
} else {
result = gst_pad_stop_task (sinkpad);
}
return result;
case GST_PAD_MODE_PUSH:
rp->mode = mode;
return TRUE;
default:
return FALSE;
}
gst_object_unref (rp);
return result;
}
static GstStateChangeReturn
@ -493,7 +524,7 @@ gst_raw_parse_change_state (GstElement * element, GstStateChange transition)
switch (transition) {
case GST_STATE_CHANGE_READY_TO_PAUSED:
gst_segment_init (&rp->segment, GST_FORMAT_TIME);
rp->segment.last_stop = 0;
rp->segment.position = 0;
default:
break;
}
@ -614,9 +645,9 @@ done:
static gboolean
gst_raw_parse_sink_event (GstPad * pad, GstEvent * event)
gst_raw_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (pad));
GstRawParse *rp = GST_RAW_PARSE (parent);
gboolean ret;
switch (GST_EVENT_TYPE (event)) {
@ -626,54 +657,44 @@ gst_raw_parse_sink_event (GstPad * pad, GstEvent * event)
gst_raw_parse_reset (rp);
ret = gst_pad_push_event (rp->srcpad, event);
break;
case GST_EVENT_NEWSEGMENT:
case GST_EVENT_SEGMENT:
{
GstClockTimeDiff start, stop, time;
gdouble rate, arate;
gboolean update;
GstFormat format;
GstSegment segment;
/* Only happens in push mode */
gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
&start, &stop, &time);
if (format == GST_FORMAT_TIME) {
gst_segment_set_newsegment_full (&rp->segment, update, rate, arate,
GST_FORMAT_TIME, start, stop, time);
ret = gst_pad_push_event (rp->srcpad, event);
} else {
gst_event_copy_segment (event, &segment);
if (segment.format != GST_FORMAT_TIME) {
gst_event_unref (event);
ret =
gst_raw_parse_convert (rp, format, start, GST_FORMAT_TIME, &start);
ret &= gst_raw_parse_convert (rp, format, time, GST_FORMAT_TIME, &time);
ret &= gst_raw_parse_convert (rp, format, stop, GST_FORMAT_TIME, &stop);
gst_raw_parse_convert (rp, segment.format, segment.start,
GST_FORMAT_TIME, (gint64 *) & segment.start);
ret &= gst_raw_parse_convert (rp, segment.format, segment.time,
GST_FORMAT_TIME, (gint64 *) & segment.time);
ret &= gst_raw_parse_convert (rp, segment.format, segment.stop,
GST_FORMAT_TIME, (gint64 *) & segment.stop);
if (!ret) {
GST_ERROR_OBJECT (rp,
"Failed converting to GST_FORMAT_TIME format (%d)", format);
"Failed converting to GST_FORMAT_TIME format (%d)",
segment.format);
break;
}
gst_segment_set_newsegment_full (&rp->segment, update, rate, arate,
GST_FORMAT_TIME, start, stop, time);
/* create new segment with the fields converted to time */
event = gst_event_new_new_segment_full (update, rate, arate,
GST_FORMAT_TIME, start, stop, time);
ret = gst_pad_push_event (rp->srcpad, event);
event = gst_event_new_segment (&segment);
}
gst_segment_copy_into (&segment, &rp->segment);
ret = gst_pad_push_event (rp->srcpad, event);
break;
}
default:
ret = gst_pad_event_default (rp->sinkpad, event);
ret = gst_pad_event_default (rp->sinkpad, parent, event);
break;
}
gst_object_unref (rp);
return ret;
}
@ -785,12 +806,12 @@ gst_raw_parse_handle_seek_pull (GstRawParse * rp, GstEvent * event)
if (event) {
/* configure the seek values */
gst_segment_set_seek (&seeksegment, rate, format, flags,
gst_segment_do_seek (&seeksegment, rate, format, flags,
start_type, start, stop_type, stop, NULL);
}
/* get the desired position */
last_stop = seeksegment.last_stop;
last_stop = seeksegment.position;
GST_LOG_OBJECT (rp, "seeking to %" GST_TIME_FORMAT,
GST_TIME_ARGS (last_stop));
@ -803,21 +824,8 @@ gst_raw_parse_handle_seek_pull (GstRawParse * rp, GstEvent * event)
/* prepare for streaming */
if (flush) {
GST_LOG_OBJECT (rp, "stop flush");
gst_pad_push_event (rp->sinkpad, gst_event_new_flush_stop ());
gst_pad_push_event (rp->srcpad, gst_event_new_flush_stop ());
} else if (ret && rp->running) {
/* we are running the current segment and doing a non-flushing seek,
* close the segment first based on the last_stop. */
GST_DEBUG_OBJECT (rp, "prepare close segment %" G_GINT64_FORMAT
" to %" G_GINT64_FORMAT, rp->segment.start, rp->segment.last_stop);
/* queue the segment for sending in the stream thread */
if (rp->close_segment)
gst_event_unref (rp->close_segment);
rp->close_segment =
gst_event_new_new_segment_full (TRUE,
rp->segment.rate, rp->segment.applied_rate, rp->segment.format,
rp->segment.start, rp->segment.last_stop, rp->segment.time);
gst_pad_push_event (rp->sinkpad, gst_event_new_flush_stop (TRUE));
gst_pad_push_event (rp->srcpad, gst_event_new_flush_stop (TRUE));
}
if (ret) {
@ -836,7 +844,7 @@ gst_raw_parse_handle_seek_pull (GstRawParse * rp, GstEvent * event)
if (rp->segment.flags & GST_SEEK_FLAG_SEGMENT) {
gst_element_post_message (GST_ELEMENT_CAST (rp),
gst_message_new_segment_start (GST_OBJECT_CAST (rp),
rp->segment.format, rp->segment.last_stop));
rp->segment.format, rp->segment.position));
}
/* for deriving a stop position for the playback segment from the seek
@ -851,25 +859,11 @@ gst_raw_parse_handle_seek_pull (GstRawParse * rp, GstEvent * event)
* next time it is scheduled. */
if (rp->start_segment)
gst_event_unref (rp->start_segment);
if (rp->segment.rate >= 0.0) {
/* forward, we send data from last_stop to stop */
rp->start_segment =
gst_event_new_new_segment_full (FALSE,
rp->segment.rate, rp->segment.applied_rate, rp->segment.format,
rp->segment.last_stop, stop, rp->segment.time);
} else {
/* reverse, we send data from last_stop to start */
rp->start_segment =
gst_event_new_new_segment_full (FALSE,
rp->segment.rate, rp->segment.applied_rate, rp->segment.format,
rp->segment.start, rp->segment.last_stop, rp->segment.time);
}
rp->start_segment = gst_event_new_segment (&rp->segment);
}
rp->discont = TRUE;
GST_LOG_OBJECT (rp, "start streaming");
rp->running = TRUE;
gst_pad_start_task (rp->sinkpad, (GstTaskFunction) gst_raw_parse_loop, rp);
GST_PAD_STREAM_UNLOCK (rp->sinkpad);
@ -885,46 +879,30 @@ convert_failed:
}
static gboolean
gst_raw_parse_src_event (GstPad * pad, GstEvent * event)
gst_raw_parse_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (pad));
GstRawParse *rp = GST_RAW_PARSE (parent);
gboolean ret;
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
if (rp->mode == GST_PAD_ACTIVATE_PUSH)
if (rp->mode == GST_PAD_MODE_PUSH)
ret = gst_raw_parse_handle_seek_push (rp, event);
else
ret = gst_raw_parse_handle_seek_pull (rp, event);
break;
default:
ret = gst_pad_event_default (rp->srcpad, event);
ret = gst_pad_event_default (rp->srcpad, parent, event);
break;
}
gst_object_unref (rp);
return ret;
}
static const GstQueryType *
gst_raw_parse_src_query_type (GstPad * pad)
{
static const GstQueryType types[] = {
GST_QUERY_POSITION,
GST_QUERY_DURATION,
GST_QUERY_CONVERT,
GST_QUERY_SEEKING,
0
};
return types;
}
static gboolean
gst_raw_parse_src_query (GstPad * pad, GstQuery * query)
gst_raw_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (pad));
GstRawParse *rp = GST_RAW_PARSE (parent);
gboolean ret = FALSE;
GST_DEBUG ("src_query %s", gst_query_type_get_name (GST_QUERY_TYPE (query)));
@ -939,7 +917,7 @@ gst_raw_parse_src_query (GstPad * pad, GstQuery * query)
gst_query_parse_position (query, &format, NULL);
time = rp->segment.last_stop;
time = rp->segment.position;
ret = gst_raw_parse_convert (rp, GST_FORMAT_TIME, time, format, &value);
gst_query_set_position (query, format, value);
@ -1001,7 +979,7 @@ gst_raw_parse_src_query (GstPad * pad, GstQuery * query)
if (fmt != GST_FORMAT_TIME && fmt != GST_FORMAT_DEFAULT
&& fmt != GST_FORMAT_BYTES) {
gst_query_set_seeking (query, fmt, FALSE, -1, -1);
} else if (rp->mode == GST_PAD_ACTIVATE_PUSH) {
} else if (rp->mode == GST_PAD_MODE_PUSH) {
GstQuery *peerquery = gst_query_new_seeking (GST_FORMAT_BYTES);
gboolean seekable;
@ -1018,12 +996,11 @@ gst_raw_parse_src_query (GstPad * pad, GstQuery * query)
}
default:
/* else forward upstream */
ret = gst_pad_peer_query (rp->sinkpad, query);
ret = gst_pad_query_default (rp->sinkpad, parent, query);
break;
}
done:
gst_object_unref (rp);
return ret;
/* ERRORS */
@ -1040,6 +1017,7 @@ gst_raw_parse_set_framesize (GstRawParse * rp, int framesize)
g_return_if_fail (GST_IS_RAW_PARSE (rp));
g_return_if_fail (!rp->negotiated);
GST_DEBUG_OBJECT (rp, "framesize %d", framesize);
rp->framesize = framesize;
}

View file

@ -52,7 +52,7 @@ struct _GstRawParse
GstPad *sinkpad;
GstPad *srcpad;
GstPadActivateMode mode;
GstPadMode mode;
GstAdapter *adapter;
gint framesize;
@ -66,8 +66,6 @@ struct _GstRawParse
gint64 offset;
GstSegment segment;
gboolean running;
GstEvent *close_segment;
GstEvent *start_segment;
gboolean negotiated;

View file

@ -57,39 +57,16 @@ enum
PROP_TOP_FIELD_FIRST
};
GST_BOILERPLATE (GstVideoParse, gst_video_parse, GstRawParse,
GST_TYPE_RAW_PARSE);
static void
gst_video_parse_base_init (gpointer g_class)
{
GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (g_class);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
GstCaps *caps;
GST_DEBUG_CATEGORY_INIT (gst_video_parse_debug, "videoparse", 0,
"videoparse element");
gst_element_class_set_details_simple (gstelement_class, "Video Parse",
"Filter/Video",
"Converts stream into video frames",
"David Schleef <ds@schleef.org>, "
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
caps =
gst_caps_from_string
("video/x-raw-rgb; video/x-raw-yuv; video/x-raw-gray; video/x-raw-bayer");
gst_raw_parse_class_set_src_pad_template (rp_class, caps);
gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, FALSE);
gst_caps_unref (caps);
}
#define gst_video_parse_parent_class parent_class
G_DEFINE_TYPE (GstVideoParse, gst_video_parse, GST_TYPE_RAW_PARSE);
static void
gst_video_parse_class_init (GstVideoParseClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (klass);
GstCaps *caps;
gobject_class->set_property = gst_video_parse_set_property;
gobject_class->get_property = gst_video_parse_get_property;
@ -123,10 +100,25 @@ gst_video_parse_class_init (GstVideoParseClass * klass)
g_param_spec_boolean ("top-field-first", "Top field first",
"True if top field is earlier than bottom field", TRUE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_details_simple (gstelement_class, "Video Parse",
"Filter/Video",
"Converts stream into video frames",
"David Schleef <ds@schleef.org>, "
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
caps = gst_caps_from_string ("video/x-raw; video/x-raw-bayer");
gst_raw_parse_class_set_src_pad_template (rp_class, caps);
gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, FALSE);
gst_caps_unref (caps);
GST_DEBUG_CATEGORY_INIT (gst_video_parse_debug, "videoparse", 0,
"videoparse element");
}
static void
gst_video_parse_init (GstVideoParse * vp, GstVideoParseClass * g_class)
gst_video_parse_init (GstVideoParse * vp)
{
vp->width = 320;
vp->height = 240;
@ -221,8 +213,11 @@ void
gst_video_parse_update_frame_size (GstVideoParse * vp)
{
gint framesize;
GstVideoInfo info;
framesize = gst_video_format_get_size (vp->format, vp->width, vp->height);
gst_video_info_init (&info);
gst_video_info_set_format (&info, vp->format, vp->width, vp->height);
framesize = GST_VIDEO_INFO_SIZE (&info);
gst_raw_parse_set_framesize (GST_RAW_PARSE (vp), framesize);
}
@ -231,15 +226,23 @@ static GstCaps *
gst_video_parse_get_caps (GstRawParse * rp)
{
GstVideoParse *vp = GST_VIDEO_PARSE (rp);
GstVideoInfo info;
GstCaps *caps;
gint fps_n, fps_d;
gst_raw_parse_get_fps (rp, &fps_n, &fps_d);
caps =
gst_video_format_new_caps_interlaced (vp->format, vp->width, vp->height,
fps_n, fps_d, vp->par_n, vp->par_d, vp->interlaced);
gst_video_info_init (&info);
gst_video_info_set_format (&info, vp->format, vp->width, vp->height);
info.fps_n = fps_n;
info.fps_d = fps_d;
info.par_n = vp->par_n;
info.par_d = vp->par_d;
info.interlace_mode = vp->interlaced ?
GST_VIDEO_INTERLACE_MODE_INTERLEAVED :
GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
caps = gst_video_info_to_caps (&info);
return caps;
}
@ -251,9 +254,9 @@ gst_video_parse_set_buffer_flags (GstRawParse * rp, GstBuffer * buffer)
if (vp->interlaced) {
if (vp->top_field_first) {
GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_TFF);
GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_TFF);
} else {
GST_BUFFER_FLAG_UNSET (buffer, GST_VIDEO_BUFFER_TFF);
GST_BUFFER_FLAG_UNSET (buffer, GST_VIDEO_BUFFER_FLAG_TFF);
}
}
}