mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 14:36:24 +00:00
realmedia: port to 0.11
This commit is contained in:
parent
76a13cbcdc
commit
9a7cbf8f0a
9 changed files with 359 additions and 346 deletions
|
@ -52,7 +52,7 @@ static gboolean
|
|||
read_packet_header (GstRDTPacket * packet)
|
||||
{
|
||||
guint8 *data;
|
||||
guint size;
|
||||
gsize size;
|
||||
guint offset;
|
||||
guint length;
|
||||
guint length_offset;
|
||||
|
@ -60,15 +60,14 @@ read_packet_header (GstRDTPacket * packet)
|
|||
g_return_val_if_fail (packet != NULL, FALSE);
|
||||
g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
|
||||
|
||||
data = GST_BUFFER_DATA (packet->buffer);
|
||||
size = GST_BUFFER_SIZE (packet->buffer);
|
||||
data = gst_buffer_map (packet->buffer, &size, NULL, GST_MAP_READ);
|
||||
|
||||
offset = packet->offset;
|
||||
|
||||
/* check if we are at the end of the buffer, we add 3 because we also want to
|
||||
* ensure we can read the type, which is always at offset 1 and 2 bytes long. */
|
||||
if (offset + 3 > size)
|
||||
return FALSE;
|
||||
goto packet_end;
|
||||
|
||||
/* read type */
|
||||
packet->type = GST_READ_UINT16_BE (&data[offset + 1]);
|
||||
|
@ -165,6 +164,7 @@ read_packet_header (GstRDTPacket * packet)
|
|||
/* length is remainder of packet */
|
||||
packet->length = size - offset;
|
||||
}
|
||||
gst_buffer_unmap (packet->buffer, data, size);
|
||||
|
||||
/* the length should be smaller than the remaining size */
|
||||
if (packet->length + offset > size)
|
||||
|
@ -173,9 +173,15 @@ read_packet_header (GstRDTPacket * packet)
|
|||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
packet_end:
|
||||
{
|
||||
gst_buffer_unmap (packet->buffer, data, size);
|
||||
return FALSE;
|
||||
}
|
||||
unknown_packet:
|
||||
{
|
||||
packet->type = GST_RDT_TYPE_INVALID;
|
||||
gst_buffer_unmap (packet->buffer, data, size);
|
||||
return FALSE;
|
||||
}
|
||||
invalid_length:
|
||||
|
@ -260,7 +266,8 @@ gst_rdt_packet_to_buffer (GstRDTPacket * packet)
|
|||
g_return_val_if_fail (packet->type != GST_RDT_TYPE_INVALID, NULL);
|
||||
|
||||
result =
|
||||
gst_buffer_create_sub (packet->buffer, packet->offset, packet->length);
|
||||
gst_buffer_copy_region (packet->buffer, GST_BUFFER_COPY_ALL,
|
||||
packet->offset, packet->length);
|
||||
/* timestamp applies to all packets in this buffer */
|
||||
GST_BUFFER_TIMESTAMP (result) = GST_BUFFER_TIMESTAMP (packet->buffer);
|
||||
|
||||
|
@ -278,22 +285,26 @@ gst_rdt_packet_data_get_seq (GstRDTPacket * packet)
|
|||
{
|
||||
guint header;
|
||||
guint8 *bufdata;
|
||||
guint16 result;
|
||||
|
||||
g_return_val_if_fail (packet != NULL, FALSE);
|
||||
g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), FALSE);
|
||||
|
||||
bufdata = GST_BUFFER_DATA (packet->buffer);
|
||||
bufdata = gst_buffer_map (packet->buffer, NULL, NULL, GST_MAP_READ);
|
||||
|
||||
/* skip header bits */
|
||||
header = packet->offset + 1;
|
||||
|
||||
/* read seq_no */
|
||||
return GST_READ_UINT16_BE (&bufdata[header]);
|
||||
result = GST_READ_UINT16_BE (&bufdata[header]);
|
||||
|
||||
gst_buffer_unmap (packet->buffer, bufdata, -1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rdt_packet_data_peek_data (GstRDTPacket * packet, guint8 ** data,
|
||||
guint * size)
|
||||
guint8 *
|
||||
gst_rdt_packet_data_map (GstRDTPacket * packet, guint * size)
|
||||
{
|
||||
guint header;
|
||||
guint8 *bufdata;
|
||||
|
@ -302,10 +313,11 @@ gst_rdt_packet_data_peek_data (GstRDTPacket * packet, guint8 ** data,
|
|||
guint8 stream_id;
|
||||
guint8 asm_rule_number;
|
||||
|
||||
g_return_val_if_fail (packet != NULL, FALSE);
|
||||
g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), FALSE);
|
||||
g_return_val_if_fail (packet != NULL, NULL);
|
||||
g_return_val_if_fail (packet->data == NULL, NULL);
|
||||
g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), NULL);
|
||||
|
||||
bufdata = GST_BUFFER_DATA (packet->buffer);
|
||||
bufdata = gst_buffer_map (packet->buffer, NULL, NULL, GST_MAP_READ);
|
||||
|
||||
header = packet->offset;
|
||||
|
||||
|
@ -338,11 +350,23 @@ gst_rdt_packet_data_peek_data (GstRDTPacket * packet, guint8 ** data,
|
|||
header += 2;
|
||||
}
|
||||
|
||||
if (data)
|
||||
*data = &bufdata[header];
|
||||
if (size)
|
||||
*size = packet->length - (header - packet->offset);
|
||||
|
||||
packet->data = bufdata;
|
||||
|
||||
return &bufdata[header];
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rdt_packet_data_unmap (GstRDTPacket * packet)
|
||||
{
|
||||
g_return_val_if_fail (packet != NULL, FALSE);
|
||||
g_return_val_if_fail (packet->data != NULL, FALSE);
|
||||
|
||||
gst_buffer_unmap (packet->buffer, packet->data, -1);
|
||||
packet->data = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -357,7 +381,7 @@ gst_rdt_packet_data_get_stream_id (GstRDTPacket * packet)
|
|||
g_return_val_if_fail (packet != NULL, 0);
|
||||
g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);
|
||||
|
||||
bufdata = GST_BUFFER_DATA (packet->buffer);
|
||||
bufdata = gst_buffer_map (packet->buffer, NULL, NULL, GST_MAP_READ);
|
||||
|
||||
header = packet->offset;
|
||||
|
||||
|
@ -377,6 +401,8 @@ gst_rdt_packet_data_get_stream_id (GstRDTPacket * packet)
|
|||
/* stream_id_expansion */
|
||||
result = GST_READ_UINT16_BE (&bufdata[header]);
|
||||
}
|
||||
gst_buffer_unmap (packet->buffer, bufdata, -1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -386,11 +412,12 @@ gst_rdt_packet_data_get_timestamp (GstRDTPacket * packet)
|
|||
guint header;
|
||||
gboolean length_included_flag;
|
||||
guint8 *bufdata;
|
||||
guint32 result;
|
||||
|
||||
g_return_val_if_fail (packet != NULL, 0);
|
||||
g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);
|
||||
|
||||
bufdata = GST_BUFFER_DATA (packet->buffer);
|
||||
bufdata = gst_buffer_map (packet->buffer, NULL, NULL, GST_MAP_READ);
|
||||
|
||||
header = packet->offset;
|
||||
|
||||
|
@ -407,12 +434,16 @@ gst_rdt_packet_data_get_timestamp (GstRDTPacket * packet)
|
|||
header += 1;
|
||||
|
||||
/* get timestamp */
|
||||
return GST_READ_UINT32_BE (&bufdata[header]);
|
||||
result = GST_READ_UINT32_BE (&bufdata[header]);
|
||||
gst_buffer_unmap (packet->buffer, bufdata, -1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
guint8
|
||||
gst_rdt_packet_data_get_flags (GstRDTPacket * packet)
|
||||
{
|
||||
guint8 result;
|
||||
guint header;
|
||||
gboolean length_included_flag;
|
||||
guint8 *bufdata;
|
||||
|
@ -420,7 +451,7 @@ gst_rdt_packet_data_get_flags (GstRDTPacket * packet)
|
|||
g_return_val_if_fail (packet != NULL, 0);
|
||||
g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);
|
||||
|
||||
bufdata = GST_BUFFER_DATA (packet->buffer);
|
||||
bufdata = gst_buffer_map (packet->buffer, NULL, NULL, GST_MAP_READ);
|
||||
|
||||
header = packet->offset;
|
||||
|
||||
|
@ -434,5 +465,8 @@ gst_rdt_packet_data_get_flags (GstRDTPacket * packet)
|
|||
header += 2;
|
||||
}
|
||||
/* get flags */
|
||||
return bufdata[header];
|
||||
result = bufdata[header];
|
||||
gst_buffer_unmap (packet->buffer, bufdata, -1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ struct _GstRDTPacket
|
|||
/*< private >*/
|
||||
GstRDTType type; /* type of current packet */
|
||||
guint16 length; /* length of current packet in bytes */
|
||||
guint8 *data; /* last mapped data */
|
||||
};
|
||||
|
||||
/* validate buffers */
|
||||
|
@ -105,7 +106,8 @@ GstBuffer* gst_rdt_packet_to_buffer (GstRDTPacket *packet);
|
|||
|
||||
/* data packets */
|
||||
guint16 gst_rdt_packet_data_get_seq (GstRDTPacket *packet);
|
||||
gboolean gst_rdt_packet_data_peek_data (GstRDTPacket *packet, guint8 **data, guint *size);
|
||||
guint8 * gst_rdt_packet_data_map (GstRDTPacket *packet, guint *size);
|
||||
gboolean gst_rdt_packet_data_unmap (GstRDTPacket *packet);
|
||||
guint16 gst_rdt_packet_data_get_stream_id (GstRDTPacket *packet);
|
||||
guint32 gst_rdt_packet_data_get_timestamp (GstRDTPacket *packet);
|
||||
|
||||
|
|
|
@ -56,21 +56,9 @@ static GstFlowReturn gst_pnm_src_create (GstPushSrc * psrc, GstBuffer ** buf);
|
|||
static void gst_pnm_src_uri_handler_init (gpointer g_iface,
|
||||
gpointer iface_data);
|
||||
|
||||
static void
|
||||
_do_init (GType pnmsrc_type)
|
||||
{
|
||||
static const GInterfaceInfo urihandler_info = {
|
||||
gst_pnm_src_uri_handler_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
g_type_add_interface_static (pnmsrc_type, GST_TYPE_URI_HANDLER,
|
||||
&urihandler_info);
|
||||
}
|
||||
|
||||
GST_BOILERPLATE_FULL (GstPNMSrc, gst_pnm_src, GstPushSrc, GST_TYPE_PUSH_SRC,
|
||||
_do_init);
|
||||
#define gst_pnm_src_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstPNMSrc, gst_pnm_src, GST_TYPE_PUSH_SRC,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_pnm_src_uri_handler_init));
|
||||
|
||||
static void gst_pnm_src_finalize (GObject * object);
|
||||
|
||||
|
@ -79,31 +67,15 @@ static void gst_pnm_src_set_property (GObject * object, guint prop_id,
|
|||
static void gst_pnm_src_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
|
||||
static void
|
||||
gst_pnm_src_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_pnm_src_template));
|
||||
|
||||
gst_element_class_set_details_simple (element_class, "PNM packet receiver",
|
||||
"Source/Network",
|
||||
"Receive data over the network via PNM",
|
||||
"Wim Taymans <wim.taymans@gmail.com>");
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (pnmsrc_debug, "pnmsrc",
|
||||
0, "Source for the pnm:// uri");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pnm_src_class_init (GstPNMSrcClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstPushSrcClass *gstpushsrc_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gstpushsrc_class = (GstPushSrcClass *) klass;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
@ -118,11 +90,23 @@ gst_pnm_src_class_init (GstPNMSrcClass * klass)
|
|||
"Location of the PNM url to read",
|
||||
DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_pnm_src_template));
|
||||
|
||||
gst_element_class_set_details_simple (gstelement_class, "PNM packet receiver",
|
||||
"Source/Network",
|
||||
"Receive data over the network via PNM",
|
||||
"Wim Taymans <wim.taymans@gmail.com>");
|
||||
|
||||
gstpushsrc_class->create = gst_pnm_src_create;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (pnmsrc_debug, "pnmsrc",
|
||||
0, "Source for the pnm:// uri");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pnm_src_init (GstPNMSrc * pnmsrc, GstPNMSrcClass * klass)
|
||||
gst_pnm_src_init (GstPNMSrc * pnmsrc)
|
||||
{
|
||||
pnmsrc->location = g_strdup (DEFAULT_LOCATION);
|
||||
}
|
||||
|
@ -210,13 +194,13 @@ gst_pnm_src_create (GstPushSrc * psrc, GstBuffer ** buf)
|
|||
/*** GSTURIHANDLER INTERFACE *************************************************/
|
||||
|
||||
static GstURIType
|
||||
gst_pnm_src_uri_get_type (void)
|
||||
gst_pnm_src_uri_get_type (GType type)
|
||||
{
|
||||
return GST_URI_SRC;
|
||||
}
|
||||
|
||||
static gchar **
|
||||
gst_pnm_src_uri_get_protocols (void)
|
||||
gst_pnm_src_uri_get_protocols (GType type)
|
||||
{
|
||||
static gchar *protocols[] = { (gchar *) "pnm", NULL };
|
||||
|
||||
|
|
|
@ -61,8 +61,8 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
|||
GST_DEBUG_CATEGORY_STATIC (real_audio_demux_debug);
|
||||
#define GST_CAT_DEFAULT real_audio_demux_debug
|
||||
|
||||
GST_BOILERPLATE (GstRealAudioDemux, gst_real_audio_demux, GstElement,
|
||||
GST_TYPE_ELEMENT);
|
||||
#define gst_real_audio_demux_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstRealAudioDemux, gst_real_audio_demux, GST_TYPE_ELEMENT);
|
||||
|
||||
static GstStateChangeReturn gst_real_audio_demux_change_state (GstElement * e,
|
||||
GstStateChange transition);
|
||||
|
@ -77,24 +77,6 @@ static gboolean gst_real_audio_demux_sink_activate_push (GstPad * sinkpad,
|
|||
static gboolean gst_real_audio_demux_sink_activate_pull (GstPad * sinkpad,
|
||||
gboolean active);
|
||||
|
||||
static void
|
||||
gst_real_audio_demux_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&src_template));
|
||||
gst_element_class_set_details_simple (element_class, "RealAudio Demuxer",
|
||||
"Codec/Demuxer",
|
||||
"Demultiplex a RealAudio file",
|
||||
"Tim-Philipp Müller <tim centricular net>");
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (real_audio_demux_debug, "rademux",
|
||||
0, "Demuxer for RealAudio streams");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_real_audio_demux_finalize (GObject * obj)
|
||||
{
|
||||
|
@ -113,8 +95,21 @@ gst_real_audio_demux_class_init (GstRealAudioDemuxClass * klass)
|
|||
|
||||
gobject_class->finalize = gst_real_audio_demux_finalize;
|
||||
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&sink_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&src_template));
|
||||
|
||||
gst_element_class_set_details_simple (gstelement_class, "RealAudio Demuxer",
|
||||
"Codec/Demuxer",
|
||||
"Demultiplex a RealAudio file",
|
||||
"Tim-Philipp Müller <tim centricular net>");
|
||||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_real_audio_demux_change_state);
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (real_audio_demux_debug, "rademux",
|
||||
0, "Demuxer for RealAudio streams");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -159,8 +154,7 @@ gst_real_audio_demux_reset (GstRealAudioDemux * demux)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_real_audio_demux_init (GstRealAudioDemux * demux,
|
||||
GstRealAudioDemuxClass * klass)
|
||||
gst_real_audio_demux_init (GstRealAudioDemux * demux)
|
||||
{
|
||||
demux->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
|
||||
|
||||
|
@ -184,9 +178,27 @@ gst_real_audio_demux_init (GstRealAudioDemux * demux,
|
|||
static gboolean
|
||||
gst_real_audio_demux_sink_activate (GstPad * sinkpad)
|
||||
{
|
||||
if (gst_pad_check_pull_range (sinkpad)) {
|
||||
return gst_pad_activate_pull (sinkpad, TRUE);
|
||||
} else {
|
||||
GstQuery *query;
|
||||
gboolean pull_mode;
|
||||
|
||||
query = gst_query_new_scheduling ();
|
||||
|
||||
if (!gst_pad_peer_query (sinkpad, query)) {
|
||||
gst_query_unref (query);
|
||||
goto activate_push;
|
||||
}
|
||||
|
||||
gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!pull_mode)
|
||||
goto activate_push;
|
||||
|
||||
GST_DEBUG_OBJECT (sinkpad, "activating pull");
|
||||
return gst_pad_activate_pull (sinkpad, TRUE);
|
||||
|
||||
activate_push:
|
||||
{
|
||||
GST_DEBUG_OBJECT (sinkpad, "activating push");
|
||||
return gst_pad_activate_push (sinkpad, TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -224,14 +236,14 @@ gst_real_audio_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
|
|||
static GstFlowReturn
|
||||
gst_real_audio_demux_parse_marker (GstRealAudioDemux * demux)
|
||||
{
|
||||
const guint8 *data;
|
||||
guint8 data[6];
|
||||
|
||||
if (gst_adapter_available (demux->adapter) < 6) {
|
||||
GST_LOG_OBJECT (demux, "need at least 6 bytes, waiting for more data");
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
data = gst_adapter_peek (demux->adapter, 6);
|
||||
gst_adapter_copy (demux->adapter, data, 0, 6);
|
||||
if (memcmp (data, ".ra\375", 4) != 0)
|
||||
goto wrong_format;
|
||||
|
||||
|
@ -278,10 +290,9 @@ gst_real_demux_get_timestamp_from_offset (GstRealAudioDemux * demux,
|
|||
static gboolean
|
||||
gst_real_audio_demux_get_data_offset_from_header (GstRealAudioDemux * demux)
|
||||
{
|
||||
const guint8 *data;
|
||||
guint8 data[16];
|
||||
|
||||
data = gst_adapter_peek (demux->adapter, 16);
|
||||
g_assert (data != NULL);
|
||||
gst_adapter_copy (demux->adapter, data, 0, 16);
|
||||
|
||||
switch (demux->ra_version) {
|
||||
case 3:
|
||||
|
@ -323,7 +334,7 @@ gst_real_audio_demux_parse_header (GstRealAudioDemux * demux)
|
|||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
data = gst_adapter_peek (demux->adapter, demux->data_offset - 6);
|
||||
data = gst_adapter_map (demux->adapter, demux->data_offset - 6);
|
||||
g_assert (data);
|
||||
|
||||
switch (demux->ra_version) {
|
||||
|
@ -440,7 +451,7 @@ gst_real_audio_demux_parse_header (GstRealAudioDemux * demux)
|
|||
demux->byterate_num, demux->byterate_denom,
|
||||
demux->byterate_num / demux->byterate_denom);
|
||||
|
||||
if (gst_pad_query_peer_duration (demux->sinkpad, &bformat, &size_bytes)) {
|
||||
if (gst_pad_query_peer_duration (demux->sinkpad, bformat, &size_bytes)) {
|
||||
demux->duration =
|
||||
gst_real_demux_get_timestamp_from_offset (demux, size_bytes);
|
||||
demux->upstream_size = size_bytes;
|
||||
|
@ -462,7 +473,7 @@ gst_real_audio_demux_parse_header (GstRealAudioDemux * demux)
|
|||
g_free (codec_name);
|
||||
}
|
||||
|
||||
gst_adapter_flush (demux->adapter, demux->data_offset - 6);
|
||||
gst_adapter_unmap (demux->adapter, demux->data_offset - 6);
|
||||
|
||||
demux->state = REAL_AUDIO_DEMUX_STATE_DATA;
|
||||
demux->need_newsegment = TRUE;
|
||||
|
@ -503,22 +514,14 @@ gst_real_audio_demux_parse_data (GstRealAudioDemux * demux)
|
|||
|
||||
while (ret == GST_FLOW_OK && unit_size > 0 && avail >= unit_size) {
|
||||
GstClockTime ts;
|
||||
const guint8 *data;
|
||||
GstBuffer *buf = NULL;
|
||||
GstBuffer *buf;
|
||||
|
||||
buf = gst_buffer_new_and_alloc (unit_size);
|
||||
gst_buffer_set_caps (buf, GST_PAD_CAPS (demux->srcpad));
|
||||
|
||||
data = gst_adapter_peek (demux->adapter, unit_size);
|
||||
memcpy (GST_BUFFER_DATA (buf), data, unit_size);
|
||||
gst_adapter_flush (demux->adapter, unit_size);
|
||||
buf = gst_adapter_take_buffer (demux->adapter, unit_size);
|
||||
avail -= unit_size;
|
||||
|
||||
if (demux->need_newsegment) {
|
||||
gst_pad_push_event (demux->srcpad,
|
||||
gst_event_new_new_segment_full (FALSE, demux->segment.rate,
|
||||
demux->segment.applied_rate, GST_FORMAT_TIME,
|
||||
demux->segment.start, demux->segment.stop, demux->segment.time));
|
||||
gst_event_new_segment (&demux->segment));
|
||||
demux->need_newsegment = FALSE;
|
||||
}
|
||||
|
||||
|
@ -535,7 +538,7 @@ gst_real_audio_demux_parse_data (GstRealAudioDemux * demux)
|
|||
ts = gst_real_demux_get_timestamp_from_offset (demux, demux->offset);
|
||||
GST_BUFFER_TIMESTAMP (buf) = ts;
|
||||
|
||||
gst_segment_set_last_stop (&demux->segment, GST_FORMAT_TIME, ts);
|
||||
demux->segment.position = ts;
|
||||
|
||||
ret = gst_pad_push (demux->srcpad, buf);
|
||||
}
|
||||
|
@ -626,7 +629,7 @@ gst_real_audio_demux_loop (GstRealAudioDemux * demux)
|
|||
if (ret != GST_FLOW_OK)
|
||||
goto pull_range_error;
|
||||
|
||||
if (GST_BUFFER_SIZE (buf) != bytes_needed)
|
||||
if (gst_buffer_get_size (buf) != bytes_needed)
|
||||
goto pull_range_short_read;
|
||||
|
||||
ret = gst_real_audio_demux_handle_buffer (demux, buf);
|
||||
|
@ -637,8 +640,8 @@ gst_real_audio_demux_loop (GstRealAudioDemux * demux)
|
|||
demux->offset += bytes_needed;
|
||||
|
||||
/* check for the end of the segment */
|
||||
if (demux->segment.stop != -1 && demux->segment.last_stop != -1 &&
|
||||
demux->segment.last_stop > demux->segment.stop) {
|
||||
if (demux->segment.stop != -1 && demux->segment.position != -1 &&
|
||||
demux->segment.position > demux->segment.stop) {
|
||||
GST_DEBUG_OBJECT (demux, "reached end of segment");
|
||||
goto eos;
|
||||
}
|
||||
|
@ -664,7 +667,7 @@ pull_range_error:
|
|||
pull_range_short_read:
|
||||
{
|
||||
GST_WARNING_OBJECT (demux, "pull range short read: wanted %u bytes, but "
|
||||
"got only %u bytes", bytes_needed, GST_BUFFER_SIZE (buf));
|
||||
"got only %u bytes", bytes_needed, gst_buffer_get_size (buf));
|
||||
gst_buffer_unref (buf);
|
||||
goto eos;
|
||||
}
|
||||
|
@ -712,7 +715,7 @@ gst_real_audio_demux_sink_event (GstPad * pad, GstEvent * event)
|
|||
demux = GST_REAL_AUDIO_DEMUX (gst_pad_get_parent (pad));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_NEWSEGMENT:{
|
||||
case GST_EVENT_SEGMENT:{
|
||||
/* FIXME */
|
||||
gst_event_unref (event);
|
||||
demux->need_newsegment = TRUE;
|
||||
|
@ -768,20 +771,7 @@ gst_real_audio_demux_handle_seek (GstRealAudioDemux * demux, GstEvent * event)
|
|||
|
||||
GST_PAD_STREAM_LOCK (demux->sinkpad);
|
||||
|
||||
if (demux->segment_running && !flush) {
|
||||
GstEvent *newseg;
|
||||
|
||||
newseg = gst_event_new_new_segment_full (TRUE, demux->segment.rate,
|
||||
demux->segment.applied_rate, GST_FORMAT_TIME, demux->segment.start,
|
||||
demux->segment.last_stop, demux->segment.time);
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "sending NEWSEGMENT event to close the current "
|
||||
"segment: %" GST_PTR_FORMAT, newseg);
|
||||
|
||||
gst_pad_push_event (demux->srcpad, newseg);
|
||||
}
|
||||
|
||||
gst_segment_set_seek (&demux->segment, rate, format, flags,
|
||||
gst_segment_do_seek (&demux->segment, rate, format, flags,
|
||||
cur_type, cur, stop_type, stop, &update);
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "segment: %" GST_SEGMENT_FORMAT, &demux->segment);
|
||||
|
@ -796,8 +786,8 @@ gst_real_audio_demux_handle_seek (GstRealAudioDemux * demux, GstEvent * event)
|
|||
GST_DEBUG_OBJECT (demux, "seek_pos = %" G_GUINT64_FORMAT, seek_pos);
|
||||
|
||||
/* stop flushing */
|
||||
gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ());
|
||||
gst_pad_push_event (demux->srcpad, gst_event_new_flush_stop ());
|
||||
gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop (TRUE));
|
||||
gst_pad_push_event (demux->srcpad, gst_event_new_flush_stop (TRUE));
|
||||
|
||||
demux->offset = seek_pos;
|
||||
demux->need_newsegment = TRUE;
|
||||
|
@ -806,7 +796,7 @@ gst_real_audio_demux_handle_seek (GstRealAudioDemux * demux, GstEvent * event)
|
|||
if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
|
||||
gst_element_post_message (GST_ELEMENT (demux),
|
||||
gst_message_new_segment_start (GST_OBJECT (demux),
|
||||
GST_FORMAT_TIME, demux->segment.last_stop));
|
||||
GST_FORMAT_TIME, demux->segment.position));
|
||||
}
|
||||
|
||||
demux->segment_running = TRUE;
|
||||
|
|
|
@ -64,37 +64,17 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
)
|
||||
);
|
||||
|
||||
GST_BOILERPLATE (GstRDTDepay, gst_rdt_depay, GstElement, GST_TYPE_ELEMENT);
|
||||
#define gst_rdt_depay_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstRDTDepay, gst_rdt_depay, GST_TYPE_ELEMENT);
|
||||
|
||||
static void gst_rdt_depay_finalize (GObject * object);
|
||||
|
||||
static GstStateChangeReturn gst_rdt_depay_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
|
||||
static gboolean gst_rdt_depay_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static gboolean gst_rdt_depay_sink_event (GstPad * pad, GstEvent * event);
|
||||
static GstFlowReturn gst_rdt_depay_chain (GstPad * pad, GstBuffer * buf);
|
||||
|
||||
static void
|
||||
gst_rdt_depay_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rdt_depay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rdt_depay_sink_template));
|
||||
|
||||
gst_element_class_set_details_simple (element_class, "RDT packet parser",
|
||||
"Codec/Depayloader/Network",
|
||||
"Extracts RealMedia from RDT packets",
|
||||
"Lutz Mueller <lutz at topfrose dot de>, "
|
||||
"Wim Taymans <wim@fluendo.com>");
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (rdtdepay_debug, "rdtdepay",
|
||||
0, "Depayloader for RDT RealMedia packets");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rdt_depay_class_init (GstRDTDepayClass * klass)
|
||||
{
|
||||
|
@ -109,16 +89,29 @@ gst_rdt_depay_class_init (GstRDTDepayClass * klass)
|
|||
gobject_class->finalize = gst_rdt_depay_finalize;
|
||||
|
||||
gstelement_class->change_state = gst_rdt_depay_change_state;
|
||||
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rdt_depay_src_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rdt_depay_sink_template));
|
||||
|
||||
gst_element_class_set_details_simple (gstelement_class, "RDT packet parser",
|
||||
"Codec/Depayloader/Network",
|
||||
"Extracts RealMedia from RDT packets",
|
||||
"Lutz Mueller <lutz at topfrose dot de>, "
|
||||
"Wim Taymans <wim@fluendo.com>");
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (rdtdepay_debug, "rdtdepay",
|
||||
0, "Depayloader for RDT RealMedia packets");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rdt_depay_init (GstRDTDepay * rdtdepay, GstRDTDepayClass * klass)
|
||||
gst_rdt_depay_init (GstRDTDepay * rdtdepay)
|
||||
{
|
||||
rdtdepay->sinkpad =
|
||||
gst_pad_new_from_static_template (&gst_rdt_depay_sink_template, "sink");
|
||||
gst_pad_set_chain_function (rdtdepay->sinkpad, gst_rdt_depay_chain);
|
||||
gst_pad_set_event_function (rdtdepay->sinkpad, gst_rdt_depay_sink_event);
|
||||
gst_pad_set_setcaps_function (rdtdepay->sinkpad, gst_rdt_depay_setcaps);
|
||||
gst_element_add_pad (GST_ELEMENT_CAST (rdtdepay), rdtdepay->sinkpad);
|
||||
|
||||
rdtdepay->srcpad =
|
||||
|
@ -226,6 +219,15 @@ gst_rdt_depay_sink_event (GstPad * pad, GstEvent * event)
|
|||
depay = GST_RDT_DEPAY (GST_OBJECT_PARENT (pad));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_CAPS:
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
gst_event_parse_caps (event, &caps);
|
||||
res = gst_rdt_depay_setcaps (pad, caps);
|
||||
gst_event_unref (event);
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
res = gst_pad_push_event (depay->srcpad, event);
|
||||
|
||||
|
@ -233,19 +235,9 @@ gst_rdt_depay_sink_event (GstPad * pad, GstEvent * event)
|
|||
depay->need_newsegment = TRUE;
|
||||
depay->next_seqnum = -1;
|
||||
break;
|
||||
case GST_EVENT_NEWSEGMENT:
|
||||
case GST_EVENT_SEGMENT:
|
||||
{
|
||||
gboolean update;
|
||||
gdouble rate;
|
||||
GstFormat fmt;
|
||||
gint64 start, stop, position;
|
||||
|
||||
gst_event_parse_new_segment (event, &update, &rate, &fmt, &start, &stop,
|
||||
&position);
|
||||
|
||||
gst_segment_set_newsegment (&depay->segment, update, rate, fmt,
|
||||
start, stop, position);
|
||||
|
||||
gst_event_copy_segment (event, &depay->segment);
|
||||
/* don't pass the event downstream, we generate our own segment
|
||||
* including the NTP time and other things we receive in caps */
|
||||
gst_event_unref (event);
|
||||
|
@ -263,19 +255,21 @@ static GstEvent *
|
|||
create_segment_event (GstRDTDepay * depay, gboolean update,
|
||||
GstClockTime position)
|
||||
{
|
||||
GstEvent *event;
|
||||
GstClockTime stop;
|
||||
GstSegment segment;
|
||||
|
||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||
segment.rate = depay->play_speed;
|
||||
segment.applied_rate = depay->play_scale;
|
||||
segment.start = position;
|
||||
|
||||
if (depay->npt_stop != -1)
|
||||
stop = depay->npt_stop - depay->npt_start;
|
||||
segment.stop = depay->npt_stop - depay->npt_start;
|
||||
else
|
||||
stop = -1;
|
||||
segment.stop = -1;
|
||||
|
||||
event = gst_event_new_new_segment_full (update, depay->play_speed,
|
||||
depay->play_scale, GST_FORMAT_TIME, position, stop,
|
||||
position + depay->npt_start);
|
||||
segment.time = position + depay->npt_start;
|
||||
|
||||
return event;
|
||||
return gst_event_new_segment (&segment);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -292,8 +286,6 @@ gst_rdt_depay_push (GstRDTDepay * rdtdepay, GstBuffer * buffer)
|
|||
rdtdepay->need_newsegment = FALSE;
|
||||
}
|
||||
|
||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (rdtdepay->srcpad));
|
||||
|
||||
if (rdtdepay->discont) {
|
||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
|
||||
rdtdepay->discont = FALSE;
|
||||
|
@ -319,10 +311,9 @@ gst_rdt_depay_handle_data (GstRDTDepay * rdtdepay, GstClockTime outtime,
|
|||
guint16 outflags;
|
||||
|
||||
/* get pointers to the packet data */
|
||||
gst_rdt_packet_data_peek_data (packet, &data, &size);
|
||||
data = gst_rdt_packet_data_map (packet, &size);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (12 + size);
|
||||
outdata = GST_BUFFER_DATA (outbuf);
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = outtime;
|
||||
|
||||
GST_DEBUG_OBJECT (rdtdepay, "have size %u", size);
|
||||
|
@ -372,12 +363,16 @@ gst_rdt_depay_handle_data (GstRDTDepay * rdtdepay, GstClockTime outtime,
|
|||
else
|
||||
outflags = 0;
|
||||
|
||||
outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
|
||||
GST_WRITE_UINT16_BE (outdata + 0, 0); /* version */
|
||||
GST_WRITE_UINT16_BE (outdata + 2, size + 12); /* length */
|
||||
GST_WRITE_UINT16_BE (outdata + 4, stream_id); /* stream */
|
||||
GST_WRITE_UINT32_BE (outdata + 6, timestamp); /* timestamp */
|
||||
GST_WRITE_UINT16_BE (outdata + 10, outflags); /* flags */
|
||||
memcpy (outdata + 12, data, size);
|
||||
gst_buffer_unmap (outbuf, outdata, 12 + size);
|
||||
|
||||
gst_rdt_packet_data_unmap (packet);
|
||||
|
||||
GST_DEBUG_OBJECT (rdtdepay, "Pushing packet, outtime %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (outtime));
|
||||
|
|
|
@ -128,12 +128,12 @@ static GstClock *gst_rdt_manager_provide_clock (GstElement * element);
|
|||
static GstStateChangeReturn gst_rdt_manager_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
static GstPad *gst_rdt_manager_request_new_pad (GstElement * element,
|
||||
GstPadTemplate * templ, const gchar * name);
|
||||
GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
|
||||
static void gst_rdt_manager_release_pad (GstElement * element, GstPad * pad);
|
||||
|
||||
static gboolean gst_rdt_manager_parse_caps (GstRDTManager * rdtmanager,
|
||||
GstRDTManagerSession * session, GstCaps * caps);
|
||||
static gboolean gst_rdt_manager_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static gboolean gst_rdt_manager_event_rdt (GstPad * pad, GstEvent * event);
|
||||
|
||||
static GstFlowReturn gst_rdt_manager_chain_rdt (GstPad * pad,
|
||||
GstBuffer * buffer);
|
||||
|
@ -317,29 +317,8 @@ free_session (GstRDTManagerSession * session)
|
|||
g_free (session);
|
||||
}
|
||||
|
||||
GST_BOILERPLATE (GstRDTManager, gst_rdt_manager, GstElement, GST_TYPE_ELEMENT);
|
||||
|
||||
static void
|
||||
gst_rdt_manager_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
/* sink pads */
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rdt_manager_recv_rtp_sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rdt_manager_recv_rtcp_sink_template));
|
||||
/* src pads */
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rdt_manager_recv_rtp_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rdt_manager_rtcp_src_template));
|
||||
|
||||
gst_element_class_set_details_simple (element_class, "RTP Decoder",
|
||||
"Codec/Parser/Network",
|
||||
"Accepts raw RTP and RTCP packets and sends them forward",
|
||||
"Wim Taymans <wim@fluendo.com>");
|
||||
}
|
||||
#define gst_rdt_manager_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstRDTManager, gst_rdt_manager, GST_TYPE_ELEMENT);
|
||||
|
||||
/* BOXED:UINT,UINT */
|
||||
#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
|
||||
|
@ -505,11 +484,27 @@ gst_rdt_manager_class_init (GstRDTManagerClass * g_class)
|
|||
gstelement_class->release_pad =
|
||||
GST_DEBUG_FUNCPTR (gst_rdt_manager_release_pad);
|
||||
|
||||
/* sink pads */
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rdt_manager_recv_rtp_sink_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rdt_manager_recv_rtcp_sink_template));
|
||||
/* src pads */
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rdt_manager_recv_rtp_src_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rdt_manager_rtcp_src_template));
|
||||
|
||||
gst_element_class_set_details_simple (gstelement_class, "RTP Decoder",
|
||||
"Codec/Parser/Network",
|
||||
"Accepts raw RTP and RTCP packets and sends them forward",
|
||||
"Wim Taymans <wim@fluendo.com>");
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (rdtmanager_debug, "rdtmanager", 0, "RTP decoder");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rdt_manager_init (GstRDTManager * rdtmanager, GstRDTManagerClass * klass)
|
||||
gst_rdt_manager_init (GstRDTManager * rdtmanager)
|
||||
{
|
||||
rdtmanager->provided_clock = gst_system_clock_obtain ();
|
||||
rdtmanager->latency = DEFAULT_LATENCY_MS;
|
||||
|
@ -714,7 +709,7 @@ wrong_rate:
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_rdt_manager_setcaps (GstPad * pad, GstCaps * caps)
|
||||
gst_rdt_manager_event_rdt (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
GstRDTManager *rdtmanager;
|
||||
GstRDTManagerSession *session;
|
||||
|
@ -724,8 +719,20 @@ gst_rdt_manager_setcaps (GstPad * pad, GstCaps * caps)
|
|||
/* find session */
|
||||
session = gst_pad_get_element_private (pad);
|
||||
|
||||
res = gst_rdt_manager_parse_caps (rdtmanager, session, caps);
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_CAPS:
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
gst_event_parse_caps (event, &caps);
|
||||
res = gst_rdt_manager_parse_caps (rdtmanager, session, caps);
|
||||
gst_event_unref (event);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_event_default (pad, event);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -843,7 +850,6 @@ gst_rdt_manager_loop (GstPad * pad)
|
|||
session->discont = FALSE;
|
||||
}
|
||||
|
||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (session->recv_rtp_src));
|
||||
JBUF_UNLOCK (session);
|
||||
|
||||
result = gst_pad_push (session->recv_rtp_src, buffer);
|
||||
|
@ -1146,8 +1152,8 @@ create_recv_rtp (GstRDTManager * rdtmanager, GstPadTemplate * templ,
|
|||
|
||||
session->recv_rtp_sink = gst_pad_new_from_template (templ, name);
|
||||
gst_pad_set_element_private (session->recv_rtp_sink, session);
|
||||
gst_pad_set_setcaps_function (session->recv_rtp_sink,
|
||||
gst_rdt_manager_setcaps);
|
||||
gst_pad_set_event_function (session->recv_rtp_sink,
|
||||
gst_rdt_manager_event_rdt);
|
||||
gst_pad_set_chain_function (session->recv_rtp_sink,
|
||||
gst_rdt_manager_chain_rdt);
|
||||
gst_pad_set_active (session->recv_rtp_sink, TRUE);
|
||||
|
@ -1279,7 +1285,7 @@ existed:
|
|||
*/
|
||||
static GstPad *
|
||||
gst_rdt_manager_request_new_pad (GstElement * element,
|
||||
GstPadTemplate * templ, const gchar * name)
|
||||
GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
|
||||
{
|
||||
GstRDTManager *rdtmanager;
|
||||
GstElementClass *klass;
|
||||
|
|
|
@ -277,7 +277,7 @@ gst_rmdemux_sink_event (GstPad * pad, GstEvent * event)
|
|||
GST_LOG_OBJECT (pad, "%s event", GST_EVENT_TYPE_NAME (event));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_NEWSEGMENT:
|
||||
case GST_EVENT_SEGMENT:
|
||||
gst_event_unref (event);
|
||||
ret = TRUE;
|
||||
break;
|
||||
|
@ -350,6 +350,7 @@ gst_rmdemux_validate_offset (GstRMDemux * rmdemux)
|
|||
GstFlowReturn flowret;
|
||||
guint16 version, length;
|
||||
gboolean ret = TRUE;
|
||||
guint8 *data;
|
||||
|
||||
flowret = gst_pad_pull_range (rmdemux->sinkpad, rmdemux->offset, 4, &buffer);
|
||||
|
||||
|
@ -367,19 +368,21 @@ gst_rmdemux_validate_offset (GstRMDemux * rmdemux)
|
|||
* 4 bytes, and we can check that it won't take us past our known total size
|
||||
*/
|
||||
|
||||
version = RMDEMUX_GUINT16_GET (GST_BUFFER_DATA (buffer));
|
||||
data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_READ);
|
||||
version = RMDEMUX_GUINT16_GET (data);
|
||||
if (version != 0 && version != 1) {
|
||||
GST_DEBUG_OBJECT (rmdemux, "Expected version 0 or 1, got %d",
|
||||
(int) version);
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
length = RMDEMUX_GUINT16_GET (GST_BUFFER_DATA (buffer) + 2);
|
||||
length = RMDEMUX_GUINT16_GET (data + 2);
|
||||
/* TODO: Also check against total stream length */
|
||||
if (length < 4) {
|
||||
GST_DEBUG_OBJECT (rmdemux, "Expected length >= 4, got %d", (int) length);
|
||||
ret = FALSE;
|
||||
}
|
||||
gst_buffer_unmap (buffer, data, -1);
|
||||
|
||||
if (ret) {
|
||||
rmdemux->offset += 4;
|
||||
|
@ -388,6 +391,7 @@ gst_rmdemux_validate_offset (GstRMDemux * rmdemux)
|
|||
} else {
|
||||
GST_WARNING_OBJECT (rmdemux, "Failed to validate seek offset at %d",
|
||||
rmdemux->offset);
|
||||
gst_buffer_unref (buffer);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -522,19 +526,8 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event)
|
|||
|
||||
GST_LOG_OBJECT (rmdemux, "Took streamlock");
|
||||
|
||||
/* close current segment first */
|
||||
if (rmdemux->segment_running && !flush) {
|
||||
GstEvent *newseg;
|
||||
|
||||
newseg = gst_event_new_new_segment (TRUE, rmdemux->segment.rate,
|
||||
GST_FORMAT_TIME, rmdemux->segment.start,
|
||||
rmdemux->segment.last_stop, rmdemux->segment.time);
|
||||
|
||||
gst_rmdemux_send_event (rmdemux, newseg);
|
||||
}
|
||||
|
||||
if (event) {
|
||||
gst_segment_set_seek (&rmdemux->segment, rate, format, flags,
|
||||
gst_segment_do_seek (&rmdemux->segment, rate, format, flags,
|
||||
cur_type, cur, stop_type, stop, &update);
|
||||
}
|
||||
|
||||
|
@ -544,7 +537,7 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event)
|
|||
|
||||
/* we need to stop flushing on the sinkpad as we're going to use it
|
||||
* next. We can do this as we have the STREAM lock now. */
|
||||
gst_pad_push_event (rmdemux->sinkpad, gst_event_new_flush_stop ());
|
||||
gst_pad_push_event (rmdemux->sinkpad, gst_event_new_flush_stop (TRUE));
|
||||
|
||||
GST_LOG_OBJECT (rmdemux, "Pushed FLUSH_STOP event");
|
||||
|
||||
|
@ -557,7 +550,7 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event)
|
|||
* offset we just tried. If we run out of places to try, treat that as a fatal
|
||||
* error.
|
||||
*/
|
||||
if (!find_seek_offset_time (rmdemux, rmdemux->segment.last_stop)) {
|
||||
if (!find_seek_offset_time (rmdemux, rmdemux->segment.position)) {
|
||||
GST_LOG_OBJECT (rmdemux, "Failed to find seek offset by time");
|
||||
ret = FALSE;
|
||||
goto done;
|
||||
|
@ -583,7 +576,7 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event)
|
|||
rmdemux->state = RMDEMUX_STATE_DATA_PACKET;
|
||||
|
||||
if (flush)
|
||||
gst_rmdemux_send_event (rmdemux, gst_event_new_flush_stop ());
|
||||
gst_rmdemux_send_event (rmdemux, gst_event_new_flush_stop (TRUE));
|
||||
|
||||
/* must send newsegment event from streaming thread, so just set flag */
|
||||
rmdemux->need_newsegment = TRUE;
|
||||
|
@ -592,7 +585,7 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event)
|
|||
if (rmdemux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
|
||||
gst_element_post_message (GST_ELEMENT_CAST (rmdemux),
|
||||
gst_message_new_segment_start (GST_OBJECT_CAST (rmdemux),
|
||||
GST_FORMAT_TIME, rmdemux->segment.last_stop));
|
||||
GST_FORMAT_TIME, rmdemux->segment.position));
|
||||
}
|
||||
|
||||
/* restart our task since it might have been stopped when we did the
|
||||
|
@ -770,9 +763,28 @@ gst_rmdemux_change_state (GstElement * element, GstStateChange transition)
|
|||
static gboolean
|
||||
gst_rmdemux_sink_activate (GstPad * sinkpad)
|
||||
{
|
||||
if (gst_pad_check_pull_range (sinkpad)) {
|
||||
return gst_pad_activate_pull (sinkpad, TRUE);
|
||||
} else {
|
||||
|
||||
GstQuery *query;
|
||||
gboolean pull_mode;
|
||||
|
||||
query = gst_query_new_scheduling ();
|
||||
|
||||
if (!gst_pad_peer_query (sinkpad, query)) {
|
||||
gst_query_unref (query);
|
||||
goto activate_push;
|
||||
}
|
||||
|
||||
gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!pull_mode)
|
||||
goto activate_push;
|
||||
|
||||
GST_DEBUG_OBJECT (sinkpad, "activating pull");
|
||||
return gst_pad_activate_pull (sinkpad, TRUE);
|
||||
|
||||
activate_push:
|
||||
{
|
||||
GST_DEBUG_OBJECT (sinkpad, "activating push");
|
||||
return gst_pad_activate_push (sinkpad, TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -870,8 +882,6 @@ gst_rmdemux_loop (GstPad * pad)
|
|||
}
|
||||
}
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
|
||||
/* Defer to the chain function */
|
||||
ret = gst_rmdemux_chain (pad, buffer);
|
||||
if (ret != GST_FLOW_OK) {
|
||||
|
@ -880,7 +890,7 @@ gst_rmdemux_loop (GstPad * pad)
|
|||
goto need_pause;
|
||||
}
|
||||
|
||||
rmdemux->offset += size;
|
||||
rmdemux->offset += gst_buffer_get_size (buffer);
|
||||
|
||||
switch (rmdemux->loop_state) {
|
||||
case RMDEMUX_LOOP_STATE_HEADER:
|
||||
|
@ -980,7 +990,7 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
gst_adapter_push (rmdemux->adapter, buffer);
|
||||
|
||||
GST_LOG_OBJECT (rmdemux, "Chaining buffer of size %d",
|
||||
GST_BUFFER_SIZE (buffer));
|
||||
gst_buffer_get_size (buffer));
|
||||
|
||||
while (TRUE) {
|
||||
avail = gst_adapter_available (rmdemux->adapter);
|
||||
|
@ -992,7 +1002,7 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
if (gst_adapter_available (rmdemux->adapter) < HEADER_SIZE)
|
||||
goto unlock;
|
||||
|
||||
data = gst_adapter_peek (rmdemux->adapter, HEADER_SIZE);
|
||||
data = gst_adapter_map (rmdemux->adapter, HEADER_SIZE);
|
||||
|
||||
rmdemux->object_id = RMDEMUX_FOURCC_GET (data + 0);
|
||||
rmdemux->size = RMDEMUX_GUINT32_GET (data + 4) - HEADER_SIZE;
|
||||
|
@ -1006,7 +1016,7 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
* happen. */
|
||||
GST_WARNING_OBJECT (rmdemux, "Bogus looking header, unprintable "
|
||||
"FOURCC");
|
||||
gst_adapter_flush (rmdemux->adapter, 4);
|
||||
gst_adapter_unmap (rmdemux->adapter, 4);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1017,7 +1027,7 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
GST_FOURCC_ARGS (rmdemux->object_id), rmdemux->size,
|
||||
rmdemux->object_version);
|
||||
|
||||
gst_adapter_flush (rmdemux->adapter, HEADER_SIZE);
|
||||
gst_adapter_unmap (rmdemux->adapter, HEADER_SIZE);
|
||||
|
||||
switch (rmdemux->object_id) {
|
||||
case GST_MAKE_FOURCC ('.', 'R', 'M', 'F'):
|
||||
|
@ -1062,12 +1072,12 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
goto unlock;
|
||||
|
||||
if ((rmdemux->object_version == 0) || (rmdemux->object_version == 1)) {
|
||||
data = gst_adapter_peek (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
data = gst_adapter_map (rmdemux->adapter, rmdemux->size);
|
||||
gst_rmdemux_parse__rmf (rmdemux, data, rmdemux->size);
|
||||
gst_adapter_unmap (rmdemux->adapter, rmdemux->size);
|
||||
} else {
|
||||
gst_adapter_flush (rmdemux->adapter, rmdemux->size);
|
||||
}
|
||||
|
||||
gst_adapter_flush (rmdemux->adapter, rmdemux->size);
|
||||
rmdemux->state = RMDEMUX_STATE_HEADER;
|
||||
break;
|
||||
}
|
||||
|
@ -1075,11 +1085,11 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
{
|
||||
if (gst_adapter_available (rmdemux->adapter) < rmdemux->size)
|
||||
goto unlock;
|
||||
data = gst_adapter_peek (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
data = gst_adapter_map (rmdemux->adapter, rmdemux->size);
|
||||
gst_rmdemux_parse_prop (rmdemux, data, rmdemux->size);
|
||||
gst_adapter_unmap (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
gst_adapter_flush (rmdemux->adapter, rmdemux->size);
|
||||
rmdemux->state = RMDEMUX_STATE_HEADER;
|
||||
break;
|
||||
}
|
||||
|
@ -1087,11 +1097,11 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
{
|
||||
if (gst_adapter_available (rmdemux->adapter) < rmdemux->size)
|
||||
goto unlock;
|
||||
data = gst_adapter_peek (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
data = gst_adapter_map (rmdemux->adapter, rmdemux->size);
|
||||
gst_rmdemux_parse_mdpr (rmdemux, data, rmdemux->size);
|
||||
gst_adapter_unmap (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
gst_adapter_flush (rmdemux->adapter, rmdemux->size);
|
||||
rmdemux->state = RMDEMUX_STATE_HEADER;
|
||||
break;
|
||||
}
|
||||
|
@ -1099,11 +1109,11 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
{
|
||||
if (gst_adapter_available (rmdemux->adapter) < rmdemux->size)
|
||||
goto unlock;
|
||||
data = gst_adapter_peek (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
data = gst_adapter_map (rmdemux->adapter, rmdemux->size);
|
||||
gst_rmdemux_parse_cont (rmdemux, data, rmdemux->size);
|
||||
gst_adapter_unmap (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
gst_adapter_flush (rmdemux->adapter, rmdemux->size);
|
||||
rmdemux->state = RMDEMUX_STATE_HEADER;
|
||||
break;
|
||||
}
|
||||
|
@ -1123,11 +1133,9 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
if (gst_adapter_available (rmdemux->adapter) < rmdemux->size)
|
||||
goto unlock;
|
||||
|
||||
data = gst_adapter_peek (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
data = gst_adapter_map (rmdemux->adapter, rmdemux->size);
|
||||
gst_rmdemux_parse_data (rmdemux, data, rmdemux->size);
|
||||
|
||||
gst_adapter_flush (rmdemux->adapter, rmdemux->size);
|
||||
gst_adapter_unmap (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
rmdemux->state = RMDEMUX_STATE_DATA_PACKET;
|
||||
break;
|
||||
|
@ -1136,12 +1144,11 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
{
|
||||
if (gst_adapter_available (rmdemux->adapter) < rmdemux->size)
|
||||
goto unlock;
|
||||
data = gst_adapter_peek (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
data = gst_adapter_map (rmdemux->adapter, rmdemux->size);
|
||||
rmdemux->size = gst_rmdemux_parse_indx (rmdemux, data, rmdemux->size);
|
||||
|
||||
/* Only flush the header */
|
||||
gst_adapter_flush (rmdemux->adapter, HEADER_SIZE);
|
||||
gst_adapter_unmap (rmdemux->adapter, HEADER_SIZE);
|
||||
|
||||
rmdemux->state = RMDEMUX_STATE_INDX_DATA;
|
||||
break;
|
||||
|
@ -1153,11 +1160,9 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
if (gst_adapter_available (rmdemux->adapter) < rmdemux->size)
|
||||
goto unlock;
|
||||
|
||||
data = gst_adapter_peek (rmdemux->adapter, rmdemux->size);
|
||||
|
||||
data = gst_adapter_map (rmdemux->adapter, rmdemux->size);
|
||||
gst_rmdemux_parse_indx_data (rmdemux, data, rmdemux->size);
|
||||
|
||||
gst_adapter_flush (rmdemux->adapter, rmdemux->size);
|
||||
gst_adapter_unmap (rmdemux->adapter, rmdemux->size);
|
||||
}
|
||||
|
||||
rmdemux->state = RMDEMUX_STATE_HEADER;
|
||||
|
@ -1165,11 +1170,13 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
}
|
||||
case RMDEMUX_STATE_DATA_PACKET:
|
||||
{
|
||||
guint8 header[4];
|
||||
|
||||
if (gst_adapter_available (rmdemux->adapter) < 2)
|
||||
goto unlock;
|
||||
|
||||
data = gst_adapter_peek (rmdemux->adapter, 2);
|
||||
version = RMDEMUX_GUINT16_GET (data);
|
||||
gst_adapter_copy (rmdemux->adapter, header, 0, 2);
|
||||
version = RMDEMUX_GUINT16_GET (header);
|
||||
GST_LOG_OBJECT (rmdemux, "Data packet with version=%d", version);
|
||||
|
||||
if (version == 0 || version == 1) {
|
||||
|
@ -1177,9 +1184,10 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
|
||||
if (gst_adapter_available (rmdemux->adapter) < 4)
|
||||
goto unlock;
|
||||
data = gst_adapter_peek (rmdemux->adapter, 4);
|
||||
|
||||
length = RMDEMUX_GUINT16_GET (data + 2);
|
||||
gst_adapter_copy (rmdemux->adapter, header, 0, 4);
|
||||
|
||||
length = RMDEMUX_GUINT16_GET (header + 2);
|
||||
GST_LOG_OBJECT (rmdemux, "Got length %d", length);
|
||||
|
||||
if (length < 4) {
|
||||
|
@ -1310,7 +1318,7 @@ gst_rmdemux_add_stream (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
|
|||
break;
|
||||
default:
|
||||
stream_caps = gst_caps_new_simple ("video/x-unknown-fourcc",
|
||||
"fourcc", GST_TYPE_FOURCC, stream->fourcc, NULL);
|
||||
"fourcc", G_TYPE_UINT, stream->fourcc, NULL);
|
||||
GST_WARNING_OBJECT (rmdemux,
|
||||
"Unknown video FOURCC code \"%" GST_FOURCC_FORMAT "\" (%08x)",
|
||||
GST_FOURCC_ARGS (stream->fourcc), stream->fourcc);
|
||||
|
@ -1422,7 +1430,7 @@ gst_rmdemux_add_stream (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
|
|||
|
||||
default:
|
||||
stream_caps = gst_caps_new_simple ("video/x-unknown-fourcc",
|
||||
"fourcc", GST_TYPE_FOURCC, stream->fourcc, NULL);
|
||||
"fourcc", G_TYPE_UINT, stream->fourcc, NULL);
|
||||
GST_WARNING_OBJECT (rmdemux,
|
||||
"Unknown audio FOURCC code \"%" GST_FOURCC_FORMAT "\" (%08x)",
|
||||
GST_FOURCC_ARGS (stream->fourcc), stream->fourcc);
|
||||
|
@ -1472,8 +1480,7 @@ gst_rmdemux_add_stream (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
|
|||
GstBuffer *buffer;
|
||||
|
||||
buffer = gst_buffer_new_and_alloc (stream->extra_data_size);
|
||||
memcpy (GST_BUFFER_DATA (buffer), stream->extra_data,
|
||||
stream->extra_data_size);
|
||||
gst_buffer_fill (buffer, 0, stream->extra_data, stream->extra_data_size);
|
||||
|
||||
gst_caps_set_simple (stream_caps, "codec_data", GST_TYPE_BUFFER,
|
||||
buffer, NULL);
|
||||
|
@ -1924,6 +1931,7 @@ gst_rmdemux_descramble_audio (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
|
|||
{
|
||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
||||
GstBuffer *outbuf;
|
||||
guint8 *outdata;
|
||||
guint packet_size = stream->packet_size;
|
||||
guint height = stream->subpackets->len;
|
||||
guint leaf_size = stream->leaf_size;
|
||||
|
@ -1935,11 +1943,11 @@ gst_rmdemux_descramble_audio (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
|
|||
leaf_size, height);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (height * packet_size);
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (stream->pad));
|
||||
outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
|
||||
|
||||
for (p = 0; p < height; ++p) {
|
||||
GstBuffer *b = g_ptr_array_index (stream->subpackets, p);
|
||||
guint8 *b_data = GST_BUFFER_DATA (b);
|
||||
guint8 *b_data = gst_buffer_map (b, NULL, NULL, GST_MAP_READ);
|
||||
|
||||
if (p == 0)
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (b);
|
||||
|
@ -1948,17 +1956,21 @@ gst_rmdemux_descramble_audio (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
|
|||
guint idx;
|
||||
|
||||
idx = height * x + ((height + 1) / 2) * (p % 2) + (p / 2);
|
||||
|
||||
/* GST_LOG ("%3u => %3u", (height * p) + x, idx); */
|
||||
memcpy (GST_BUFFER_DATA (outbuf) + leaf_size * idx, b_data, leaf_size);
|
||||
b_data += leaf_size;
|
||||
memcpy (outdata + leaf_size * idx, b_data + leaf_size * x, leaf_size);
|
||||
}
|
||||
gst_buffer_unmap (b, b_data, -1);
|
||||
}
|
||||
gst_buffer_unmap (outbuf, outdata, -1);
|
||||
|
||||
/* some decoders, such as realaudiodec, need to be fed in packet units */
|
||||
for (p = 0; p < height; ++p) {
|
||||
GstBuffer *subbuf;
|
||||
|
||||
subbuf = gst_buffer_create_sub (outbuf, p * packet_size, packet_size);
|
||||
subbuf =
|
||||
gst_buffer_copy_region (outbuf, GST_BUFFER_COPY_ALL, p * packet_size,
|
||||
packet_size);
|
||||
|
||||
GST_LOG_OBJECT (rmdemux, "pushing buffer timestamp %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (subbuf)));
|
||||
|
@ -1968,7 +1980,6 @@ gst_rmdemux_descramble_audio (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
|
|||
stream->discont = FALSE;
|
||||
}
|
||||
|
||||
gst_buffer_set_caps (subbuf, GST_PAD_CAPS (stream->pad));
|
||||
ret = gst_pad_push (stream->pad, subbuf);
|
||||
if (ret != GST_FLOW_OK)
|
||||
break;
|
||||
|
@ -2016,7 +2027,7 @@ gst_rmdemux_descramble_mp4a_audio (GstRMDemux * rmdemux,
|
|||
g_ptr_array_index (stream->subpackets, 0) = NULL;
|
||||
g_ptr_array_set_size (stream->subpackets, 0);
|
||||
|
||||
data = GST_BUFFER_DATA (buf);
|
||||
data = gst_buffer_map (buf, NULL, NULL, GST_MAP_READ);
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buf);
|
||||
|
||||
frames = (data[1] & 0xf0) >> 4;
|
||||
|
@ -2025,10 +2036,9 @@ gst_rmdemux_descramble_mp4a_audio (GstRMDemux * rmdemux,
|
|||
for (i = 0; i < frames; i++) {
|
||||
guint len = (data[i * 2 + 2] << 8) | data[i * 2 + 3];
|
||||
|
||||
outbuf = gst_buffer_create_sub (buf, index, len);
|
||||
outbuf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, index, len);
|
||||
if (i == 0)
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (stream->pad));
|
||||
|
||||
index += len;
|
||||
|
||||
|
@ -2040,6 +2050,7 @@ gst_rmdemux_descramble_mp4a_audio (GstRMDemux * rmdemux,
|
|||
if (res != GST_FLOW_OK)
|
||||
break;
|
||||
}
|
||||
gst_buffer_unmap (buf, data, -1);
|
||||
gst_buffer_unref (buf);
|
||||
return res;
|
||||
}
|
||||
|
@ -2050,6 +2061,7 @@ gst_rmdemux_descramble_sipr_audio (GstRMDemux * rmdemux,
|
|||
{
|
||||
GstFlowReturn ret;
|
||||
GstBuffer *outbuf;
|
||||
guint8 *outdata;
|
||||
guint packet_size = stream->packet_size;
|
||||
guint height = stream->subpackets->len;
|
||||
guint p;
|
||||
|
@ -2060,17 +2072,17 @@ gst_rmdemux_descramble_sipr_audio (GstRMDemux * rmdemux,
|
|||
stream->leaf_size, height);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (height * packet_size);
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (stream->pad));
|
||||
outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
|
||||
|
||||
for (p = 0; p < height; ++p) {
|
||||
GstBuffer *b = g_ptr_array_index (stream->subpackets, p);
|
||||
guint8 *b_data = GST_BUFFER_DATA (b);
|
||||
|
||||
if (p == 0)
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (b);
|
||||
|
||||
memcpy (GST_BUFFER_DATA (outbuf) + packet_size * p, b_data, packet_size);
|
||||
gst_buffer_extract (b, 0, outdata + packet_size * p, packet_size);
|
||||
}
|
||||
gst_buffer_unmap (outbuf, outdata, -1);
|
||||
|
||||
GST_LOG_OBJECT (rmdemux, "pushing buffer timestamp %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
|
||||
|
@ -2082,7 +2094,6 @@ gst_rmdemux_descramble_sipr_audio (GstRMDemux * rmdemux,
|
|||
|
||||
outbuf = gst_rm_utils_descramble_sipr_buffer (outbuf);
|
||||
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (stream->pad));
|
||||
ret = gst_pad_push (stream->pad, outbuf);
|
||||
|
||||
gst_rmdemux_stream_clear_cached_subpackets (rmdemux, stream);
|
||||
|
@ -2100,7 +2111,7 @@ gst_rmdemux_handle_scrambled_packet (GstRMDemux * rmdemux,
|
|||
stream->subpackets = g_ptr_array_sized_new (stream->subpackets_needed);
|
||||
|
||||
GST_LOG ("Got subpacket %u/%u, len=%u, key=%d", stream->subpackets->len + 1,
|
||||
stream->subpackets_needed, GST_BUFFER_SIZE (buf), keyframe);
|
||||
stream->subpackets_needed, gst_buffer_get_size (buf), keyframe);
|
||||
|
||||
if (keyframe && stream->subpackets->len > 0) {
|
||||
gst_rmdemux_stream_clear_cached_subpackets (rmdemux, stream);
|
||||
|
@ -2289,12 +2300,15 @@ gst_rmdemux_parse_video_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
|
|||
GstClockTime timestamp, gboolean key)
|
||||
{
|
||||
GstFlowReturn ret;
|
||||
const guint8 *data, *base;
|
||||
guint size;
|
||||
const guint8 *data;
|
||||
guint8 *base;
|
||||
gsize size;
|
||||
|
||||
base = gst_buffer_map (in, &size, NULL, GST_MAP_READ);
|
||||
|
||||
base = GST_BUFFER_DATA (in);
|
||||
data = base + offset;
|
||||
size = GST_BUFFER_SIZE (in) - offset;
|
||||
size -= offset;
|
||||
|
||||
/* if size <= 2, we want this method to return the same GstFlowReturn as it
|
||||
* was previously for that given stream. */
|
||||
ret = stream->last_flow;
|
||||
|
@ -2358,7 +2372,9 @@ gst_rmdemux_parse_video_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
|
|||
GST_DEBUG_OBJECT (rmdemux, "fragment size %d", fragment_size);
|
||||
|
||||
/* get the fragment */
|
||||
fragment = gst_buffer_create_sub (in, data - base, fragment_size);
|
||||
fragment =
|
||||
gst_buffer_copy_region (in, GST_BUFFER_COPY_ALL, data - base,
|
||||
fragment_size);
|
||||
|
||||
if (pkg_subseq == 1) {
|
||||
GST_DEBUG_OBJECT (rmdemux, "start new fragment");
|
||||
|
@ -2388,7 +2404,7 @@ gst_rmdemux_parse_video_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
|
|||
/* flush fragment when complete */
|
||||
if (stream->frag_current >= stream->frag_length) {
|
||||
GstBuffer *out;
|
||||
guint8 *outdata;
|
||||
guint8 *outdata, *outbase;
|
||||
guint header_size;
|
||||
gint i, avail;
|
||||
|
||||
|
@ -2411,7 +2427,8 @@ gst_rmdemux_parse_video_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
|
|||
avail = gst_adapter_available (stream->adapter);
|
||||
|
||||
out = gst_buffer_new_and_alloc (header_size + avail);
|
||||
outdata = GST_BUFFER_DATA (out);
|
||||
outbase = gst_buffer_map (out, NULL, NULL, GST_MAP_WRITE);
|
||||
outdata = outbase;
|
||||
|
||||
/* create header */
|
||||
*outdata++ = stream->frag_count - 1;
|
||||
|
@ -2430,8 +2447,6 @@ gst_rmdemux_parse_video_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
|
|||
stream->frag_count = 0;
|
||||
stream->frag_length = 0;
|
||||
|
||||
gst_buffer_set_caps (out, GST_PAD_CAPS (stream->pad));
|
||||
|
||||
if (timestamp != -1) {
|
||||
if (rmdemux->first_ts != -1 && timestamp > rmdemux->first_ts)
|
||||
timestamp -= rmdemux->first_ts;
|
||||
|
@ -2444,6 +2459,8 @@ gst_rmdemux_parse_video_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
|
|||
timestamp =
|
||||
gst_rmdemux_fix_timestamp (rmdemux, stream, outdata, timestamp);
|
||||
|
||||
gst_buffer_unmap (out, outbase, -1);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (out) = timestamp;
|
||||
|
||||
GST_LOG_OBJECT (rmdemux, "pushing timestamp %" GST_TIME_FORMAT,
|
||||
|
@ -2470,6 +2487,8 @@ gst_rmdemux_parse_video_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
|
|||
}
|
||||
GST_DEBUG_OBJECT (rmdemux, "%d bytes left", size);
|
||||
|
||||
done:
|
||||
gst_buffer_unmap (in, base, -1);
|
||||
gst_buffer_unref (in);
|
||||
|
||||
return ret;
|
||||
|
@ -2479,16 +2498,16 @@ not_enough_data:
|
|||
{
|
||||
GST_ELEMENT_WARNING (rmdemux, STREAM, DECODE, ("Skipping bad packet."),
|
||||
(NULL));
|
||||
gst_buffer_unref (in);
|
||||
return GST_FLOW_OK;
|
||||
ret = GST_FLOW_OK;
|
||||
goto done;
|
||||
}
|
||||
too_many_fragments:
|
||||
{
|
||||
GST_ELEMENT_ERROR (rmdemux, STREAM, DECODE,
|
||||
("Got more fragments (%u) than can be handled (%u)",
|
||||
stream->frag_count, MAX_FRAGS), (NULL));
|
||||
gst_buffer_unref (in);
|
||||
return GST_FLOW_ERROR;
|
||||
ret = GST_FLOW_ERROR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2499,16 +2518,8 @@ gst_rmdemux_parse_audio_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
|
|||
{
|
||||
GstFlowReturn ret;
|
||||
GstBuffer *buffer;
|
||||
const guint8 *data;
|
||||
guint size;
|
||||
|
||||
data = GST_BUFFER_DATA (in) + offset;
|
||||
size = GST_BUFFER_SIZE (in) - offset;
|
||||
|
||||
buffer = gst_buffer_new_and_alloc (size);
|
||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (stream->pad));
|
||||
|
||||
memcpy (GST_BUFFER_DATA (buffer), (guint8 *) data, size);
|
||||
buffer = gst_buffer_copy_region (in, GST_BUFFER_COPY_MEMORY, offset, -1);
|
||||
|
||||
if (rmdemux->first_ts != -1 && timestamp > rmdemux->first_ts)
|
||||
timestamp -= rmdemux->first_ts;
|
||||
|
@ -2527,7 +2538,7 @@ gst_rmdemux_parse_audio_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
|
|||
} else {
|
||||
GST_LOG_OBJECT (rmdemux,
|
||||
"Pushing buffer of size %d, timestamp %" GST_TIME_FORMAT "to pad %s",
|
||||
GST_BUFFER_SIZE (buffer), GST_TIME_ARGS (timestamp),
|
||||
gst_buffer_get_size (buffer), GST_TIME_ARGS (timestamp),
|
||||
GST_PAD_NAME (stream->pad));
|
||||
|
||||
if (stream->discont) {
|
||||
|
@ -2547,7 +2558,7 @@ gst_rmdemux_parse_packet (GstRMDemux * rmdemux, GstBuffer * in, guint16 version)
|
|||
{
|
||||
guint16 id;
|
||||
GstRMDemuxStream *stream;
|
||||
guint size;
|
||||
gsize size, offset;
|
||||
GstFlowReturn cret, ret;
|
||||
GstClockTime timestamp;
|
||||
gboolean key;
|
||||
|
@ -2555,8 +2566,7 @@ gst_rmdemux_parse_packet (GstRMDemux * rmdemux, GstBuffer * in, guint16 version)
|
|||
guint8 flags;
|
||||
guint32 ts;
|
||||
|
||||
base = data = GST_BUFFER_DATA (in);
|
||||
size = GST_BUFFER_SIZE (in);
|
||||
base = data = gst_buffer_map (in, &size, NULL, GST_MAP_READ);
|
||||
|
||||
/* stream number */
|
||||
id = RMDEMUX_GUINT16_GET (data);
|
||||
|
@ -2569,7 +2579,7 @@ gst_rmdemux_parse_packet (GstRMDemux * rmdemux, GstBuffer * in, guint16 version)
|
|||
ts = RMDEMUX_GUINT32_GET (data + 2);
|
||||
timestamp = ts * GST_MSECOND;
|
||||
|
||||
gst_segment_set_last_stop (&rmdemux->segment, GST_FORMAT_TIME, timestamp);
|
||||
rmdemux->segment.position = timestamp;
|
||||
|
||||
GST_LOG_OBJECT (rmdemux, "Parsing a packet for stream=%d, timestamp=%"
|
||||
GST_TIME_FORMAT ", size %u, version=%d, ts=%u", id,
|
||||
|
@ -2596,15 +2606,16 @@ gst_rmdemux_parse_packet (GstRMDemux * rmdemux, GstBuffer * in, guint16 version)
|
|||
data += 1;
|
||||
size -= 1;
|
||||
}
|
||||
offset = data - base;
|
||||
gst_buffer_unmap (in, base, -1);
|
||||
|
||||
key = (flags & 0x02) != 0;
|
||||
GST_DEBUG_OBJECT (rmdemux, "flags %d, Keyframe %d", flags, key);
|
||||
|
||||
if (rmdemux->need_newsegment) {
|
||||
GstEvent *event;
|
||||
|
||||
event = gst_event_new_new_segment (FALSE, rmdemux->segment.rate,
|
||||
rmdemux->segment.format, rmdemux->segment.start,
|
||||
rmdemux->segment.stop, rmdemux->segment.time);
|
||||
event = gst_event_new_segment (&rmdemux->segment);
|
||||
|
||||
GST_DEBUG_OBJECT (rmdemux, "sending NEWSEGMENT event, segment.start= %"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (rmdemux->segment.start));
|
||||
|
@ -2630,20 +2641,23 @@ gst_rmdemux_parse_packet (GstRMDemux * rmdemux, GstBuffer * in, guint16 version)
|
|||
"Stream %d is skipping: seek_offset=%d, offset=%d, size=%u",
|
||||
stream->id, stream->seek_offset, rmdemux->offset, size);
|
||||
cret = GST_FLOW_OK;
|
||||
gst_buffer_unref (in);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
/* do special headers */
|
||||
if (stream->subtype == GST_RMDEMUX_STREAM_VIDEO) {
|
||||
ret =
|
||||
gst_rmdemux_parse_video_packet (rmdemux, stream, in, data - base,
|
||||
gst_rmdemux_parse_video_packet (rmdemux, stream, in, offset,
|
||||
version, timestamp, key);
|
||||
} else if (stream->subtype == GST_RMDEMUX_STREAM_AUDIO) {
|
||||
ret =
|
||||
gst_rmdemux_parse_audio_packet (rmdemux, stream, in, data - base,
|
||||
gst_rmdemux_parse_audio_packet (rmdemux, stream, in, offset,
|
||||
version, timestamp, key);
|
||||
} else
|
||||
} else {
|
||||
gst_buffer_unref (in);
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
|
||||
cret = gst_rmdemux_combine_flows (rmdemux, stream, ret);
|
||||
|
||||
|
@ -2655,6 +2669,8 @@ unknown_stream:
|
|||
{
|
||||
GST_WARNING_OBJECT (rmdemux, "No stream for stream id %d in parsing "
|
||||
"data packet", id);
|
||||
gst_buffer_unmap (in, base, -1);
|
||||
gst_buffer_unref (in);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,13 +125,15 @@ gst_rm_utils_read_tags (const guint8 * data, guint datalen,
|
|||
GstBuffer *
|
||||
gst_rm_utils_descramble_dnet_buffer (GstBuffer * buf)
|
||||
{
|
||||
guint8 *data, *end, tmp;
|
||||
guint8 *base, *data, *end, tmp;
|
||||
gsize size;
|
||||
|
||||
buf = gst_buffer_make_writable (buf);
|
||||
|
||||
/* dnet = byte-order swapped AC3 */
|
||||
data = GST_BUFFER_DATA (buf);
|
||||
end = GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf);
|
||||
base = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
|
||||
data = base;
|
||||
end = data + size;
|
||||
while ((data + 1) < end) {
|
||||
/* byte-swap */
|
||||
tmp = data[0];
|
||||
|
@ -139,6 +141,7 @@ gst_rm_utils_descramble_dnet_buffer (GstBuffer * buf)
|
|||
data[1] = tmp;
|
||||
data += sizeof (guint16);
|
||||
}
|
||||
gst_buffer_unmap (buf, base, size);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -221,10 +224,10 @@ GstBuffer *
|
|||
gst_rm_utils_descramble_sipr_buffer (GstBuffer * buf)
|
||||
{
|
||||
guint8 *data;
|
||||
guint size;
|
||||
gsize size;
|
||||
gint n, bs;
|
||||
|
||||
size = GST_BUFFER_SIZE (buf);
|
||||
size = gst_buffer_get_size (buf);
|
||||
|
||||
/* split the packet in 96 blocks of nibbles */
|
||||
bs = size * 2 / 96;
|
||||
|
@ -233,7 +236,7 @@ gst_rm_utils_descramble_sipr_buffer (GstBuffer * buf)
|
|||
|
||||
buf = gst_buffer_make_writable (buf);
|
||||
|
||||
data = GST_BUFFER_DATA (buf);
|
||||
data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
|
||||
|
||||
/* we need to perform 38 swaps on the blocks */
|
||||
for (n = 0; n < 38; n++) {
|
||||
|
@ -246,6 +249,8 @@ gst_rm_utils_descramble_sipr_buffer (GstBuffer * buf)
|
|||
/* swap the blocks */
|
||||
gst_rm_utils_swap_nibbles (data, idx1, idx2, bs);
|
||||
}
|
||||
gst_buffer_unmap (buf, data, size);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -582,10 +582,7 @@ rtsp_ext_real_parse_sdp (GstRTSPExtension * ext, GstSDPMessage * sdp,
|
|||
GST_WRITE_UINT32_BE (datap + 14, 0); /* next data header */
|
||||
offset += size;
|
||||
|
||||
buf = gst_buffer_new ();
|
||||
GST_BUFFER_DATA (buf) = data;
|
||||
GST_BUFFER_MALLOCDATA (buf) = data;
|
||||
GST_BUFFER_SIZE (buf) = offset;
|
||||
buf = gst_buffer_new_wrapped (data, offset);
|
||||
|
||||
/* Set on caps */
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
|
||||
|
@ -666,46 +663,30 @@ static void gst_rtsp_real_extension_init (gpointer g_iface,
|
|||
gpointer iface_data);
|
||||
static void gst_rtsp_real_finalize (GObject * obj);
|
||||
|
||||
static void
|
||||
_do_init (GType rtspreal_type)
|
||||
{
|
||||
static const GInterfaceInfo rtspextension_info = {
|
||||
gst_rtsp_real_extension_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
g_type_add_interface_static (rtspreal_type, GST_TYPE_RTSP_EXTENSION,
|
||||
&rtspextension_info);
|
||||
}
|
||||
|
||||
GST_BOILERPLATE_FULL (GstRTSPReal, gst_rtsp_real, GstElement, GST_TYPE_ELEMENT,
|
||||
_do_init);
|
||||
|
||||
static void
|
||||
gst_rtsp_real_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_set_details_simple (element_class,
|
||||
"RealMedia RTSP Extension", "Network/Extension/Protocol",
|
||||
"Extends RTSP so that it can handle RealMedia setup",
|
||||
"Wim Taymans <wim.taymans@gmail.com>");
|
||||
}
|
||||
#define gst_rtsp_real_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstRTSPReal, gst_rtsp_real, GST_TYPE_ELEMENT,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_RTSP_EXTENSION,
|
||||
gst_rtsp_real_extension_init));
|
||||
|
||||
static void
|
||||
gst_rtsp_real_class_init (GstRTSPRealClass * g_class)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) g_class;
|
||||
GstElementClass *gstelement_class = (GstElementClass *) g_class;
|
||||
|
||||
gobject_class->finalize = gst_rtsp_real_finalize;
|
||||
|
||||
gst_element_class_set_details_simple (gstelement_class,
|
||||
"RealMedia RTSP Extension", "Network/Extension/Protocol",
|
||||
"Extends RTSP so that it can handle RealMedia setup",
|
||||
"Wim Taymans <wim.taymans@gmail.com>");
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (rtspreal_debug, "rtspreal", 0,
|
||||
"RealMedia RTSP extension");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_real_init (GstRTSPReal * rtspreal, GstRTSPRealClass * klass)
|
||||
gst_rtsp_real_init (GstRTSPReal * rtspreal)
|
||||
{
|
||||
rtspreal->isreal = FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue