mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 07:28:53 +00:00
Fixed a few bugs in the header checking. Also added descrambling code.
Original commit message from CVS: Fixed a few bugs in the header checking. Also added descrambling code.
This commit is contained in:
parent
46571ec266
commit
1a135b7cda
2 changed files with 178 additions and 63 deletions
|
@ -106,7 +106,7 @@ struct _asf_obj_stream {
|
||||||
guint64 offset;
|
guint64 offset;
|
||||||
guint32 unknown1;
|
guint32 unknown1;
|
||||||
guint32 unknown2;
|
guint32 unknown2;
|
||||||
guint16 flags;
|
guint16 id;
|
||||||
guint32 unknown3;
|
guint32 unknown3;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,7 +125,6 @@ struct _asf_stream_audio {
|
||||||
typedef struct _asf_stream_audio asf_stream_audio;
|
typedef struct _asf_stream_audio asf_stream_audio;
|
||||||
|
|
||||||
struct _asf_stream_correction {
|
struct _asf_stream_correction {
|
||||||
guint8 span;
|
|
||||||
guint16 packet_size;
|
guint16 packet_size;
|
||||||
guint16 chunk_size;
|
guint16 chunk_size;
|
||||||
guint16 data_size;
|
guint16 data_size;
|
||||||
|
@ -199,6 +198,7 @@ struct _asf_segment_info {
|
||||||
guint8 stream_number;
|
guint8 stream_number;
|
||||||
guint32 chunk_size;
|
guint32 chunk_size;
|
||||||
guint32 frag_offset;
|
guint32 frag_offset;
|
||||||
|
guint32 segment_size;
|
||||||
guint32 sequence;
|
guint32 sequence;
|
||||||
guint32 frag_timestamp;
|
guint32 frag_timestamp;
|
||||||
gboolean compressed;
|
gboolean compressed;
|
||||||
|
@ -480,12 +480,15 @@ static gboolean gst_asf_demux_handle_src_query (GstPad *pad,
|
||||||
GstQueryType type,
|
GstQueryType type,
|
||||||
GstFormat *format, gint64 *value);
|
GstFormat *format, gint64 *value);
|
||||||
static gboolean gst_asf_demux_add_video_stream (GstASFDemux *asf_demux,
|
static gboolean gst_asf_demux_add_video_stream (GstASFDemux *asf_demux,
|
||||||
asf_stream_video_format *video_format);
|
asf_stream_video_format *video_format,
|
||||||
|
guint16 id);
|
||||||
static gboolean gst_asf_demux_add_audio_stream (GstASFDemux *asf_demux,
|
static gboolean gst_asf_demux_add_audio_stream (GstASFDemux *asf_demux,
|
||||||
asf_stream_audio *audio);
|
asf_stream_audio *audio,
|
||||||
|
guint16 id);
|
||||||
static gboolean gst_asf_demux_setup_pad (GstASFDemux *asf_demux,
|
static gboolean gst_asf_demux_setup_pad (GstASFDemux *asf_demux,
|
||||||
GstPad *src_pad,
|
GstPad *src_pad,
|
||||||
GstCaps *caps_list);
|
GstCaps *caps_list,
|
||||||
|
guint16 id);
|
||||||
|
|
||||||
static GstElementStateReturn gst_asf_demux_change_state (GstElement *element);
|
static GstElementStateReturn gst_asf_demux_change_state (GstElement *element);
|
||||||
|
|
||||||
|
@ -533,7 +536,7 @@ gst_asf_demux_class_init (GstASFDemuxClass *klass)
|
||||||
static void
|
static void
|
||||||
gst_asf_demux_init (GstASFDemux *asf_demux)
|
gst_asf_demux_init (GstASFDemux *asf_demux)
|
||||||
{
|
{
|
||||||
gint i;
|
guint i;
|
||||||
|
|
||||||
asf_demux->sinkpad = gst_pad_new_from_template(
|
asf_demux->sinkpad = gst_pad_new_from_template(
|
||||||
GST_PAD_TEMPLATE_GET (sink_factory), "sink");
|
GST_PAD_TEMPLATE_GET (sink_factory), "sink");
|
||||||
|
@ -541,12 +544,13 @@ gst_asf_demux_init (GstASFDemux *asf_demux)
|
||||||
|
|
||||||
gst_element_set_loop_function (GST_ELEMENT (asf_demux), gst_asf_demux_loop);
|
gst_element_set_loop_function (GST_ELEMENT (asf_demux), gst_asf_demux_loop);
|
||||||
|
|
||||||
/* I think everything is already zero'd, but oh well*/
|
/* We should zero everything to be on the safe side */
|
||||||
for (i=0; i < GST_ASF_DEMUX_NUM_VIDEO_PADS; i++) {
|
for (i = 0; i < GST_ASF_DEMUX_NUM_VIDEO_PADS; i++) {
|
||||||
asf_demux->video_pad[i] = NULL;
|
asf_demux->video_pad[i] = NULL;
|
||||||
asf_demux->video_PTS[i] = 0;
|
asf_demux->video_PTS[i] = 0;
|
||||||
}
|
}
|
||||||
for (i=0; i < GST_ASF_DEMUX_NUM_AUDIO_PADS; i++) {
|
|
||||||
|
for (i = 0; i < GST_ASF_DEMUX_NUM_AUDIO_PADS; i++) {
|
||||||
asf_demux->audio_pad[i] = NULL;
|
asf_demux->audio_pad[i] = NULL;
|
||||||
asf_demux->audio_PTS[i] = 0;
|
asf_demux->audio_PTS[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -565,7 +569,7 @@ gst_asf_demux_send_event (GstElement *element, GstEvent *event)
|
||||||
|
|
||||||
pads = gst_element_get_pad_list (element);
|
pads = gst_element_get_pad_list (element);
|
||||||
|
|
||||||
while (pads) {
|
while (pads) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
|
||||||
if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
|
if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
|
||||||
|
@ -791,7 +795,8 @@ gst_asf_demux_process_segment (GstASFDemux *asf_demux,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&replicated_data_header, 8);
|
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&replicated_data_header, 8);
|
||||||
segment_info.frag_timestamp = replicated_data_header->frag_timestamp;
|
segment_info.frag_timestamp = GUINT32_FROM_LE (replicated_data_header->frag_timestamp);
|
||||||
|
segment_info.segment_size = GUINT32_FROM_LE (replicated_data_header->object_size);
|
||||||
|
|
||||||
if (replic_size > 8) {
|
if (replic_size > 8) {
|
||||||
gst_asf_demux_read_object_header_rest (asf_demux, replicated_data, replic_size - 8);
|
gst_asf_demux_read_object_header_rest (asf_demux, replicated_data, replic_size - 8);
|
||||||
|
@ -804,6 +809,7 @@ gst_asf_demux_process_segment (GstASFDemux *asf_demux,
|
||||||
segment_info.compressed = TRUE;
|
segment_info.compressed = TRUE;
|
||||||
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&byte, 1); rsize++;
|
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&byte, 1); rsize++;
|
||||||
time_delta = *byte;
|
time_delta = *byte;
|
||||||
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "time_delta %u", time_delta);
|
||||||
} else {
|
} else {
|
||||||
segment_info.compressed = FALSE;
|
segment_info.compressed = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -830,6 +836,7 @@ gst_asf_demux_process_segment (GstASFDemux *asf_demux,
|
||||||
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&byte, 1);
|
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&byte, 1);
|
||||||
packet_info->size_left--;
|
packet_info->size_left--;
|
||||||
segment_info.chunk_size = *byte;
|
segment_info.chunk_size = *byte;
|
||||||
|
segment_info.segment_size = segment_info.chunk_size;
|
||||||
|
|
||||||
if (segment_info.chunk_size > packet_info->size_left) {
|
if (segment_info.chunk_size > packet_info->size_left) {
|
||||||
gst_element_error (GST_ELEMENT (asf_demux), "Payload chunk overruns packet size.");
|
gst_element_error (GST_ELEMENT (asf_demux), "Payload chunk overruns packet size.");
|
||||||
|
@ -875,7 +882,7 @@ gst_asf_demux_process_data (GstASFDemux *asf_demux, guint64 *filepos, guint64 *o
|
||||||
GST_INFO (GST_CAT_PLUGIN_INFO, "Object is data with %llu packets", packets);
|
GST_INFO (GST_CAT_PLUGIN_INFO, "Object is data with %llu packets", packets);
|
||||||
|
|
||||||
for (packet = 0; packet < packets; packet++) {
|
for (packet = 0; packet < packets; packet++) {
|
||||||
GST_INFO (GST_CAT_PLUGIN_INFO, "Process packet %llu", packet);
|
GST_INFO (GST_CAT_PLUGIN_INFO, "\n\nProcess packet %llu", packet);
|
||||||
|
|
||||||
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&buf, 1); rsize=1;
|
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&buf, 1); rsize=1;
|
||||||
if (*buf & 0x80) {
|
if (*buf & 0x80) {
|
||||||
|
@ -965,6 +972,7 @@ gst_asf_demux_process_stream (GstASFDemux *asf_demux, guint64 *filepos, guint64
|
||||||
guint16 size;
|
guint16 size;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
guint32 got_bytes;
|
guint32 got_bytes;
|
||||||
|
guint16 id;
|
||||||
|
|
||||||
/* Get the rest of the header's header */
|
/* Get the rest of the header's header */
|
||||||
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&object, 54);
|
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&object, 54);
|
||||||
|
@ -972,6 +980,7 @@ gst_asf_demux_process_stream (GstASFDemux *asf_demux, guint64 *filepos, guint64
|
||||||
/* Identify the stream type */
|
/* Identify the stream type */
|
||||||
stream_id = gst_asf_demux_identify_guid (asf_demux, asf_stream_guids, &(object->type));
|
stream_id = gst_asf_demux_identify_guid (asf_demux, asf_stream_guids, &(object->type));
|
||||||
correction = gst_asf_demux_identify_guid (asf_demux, asf_correction_guids, &(object->correction));
|
correction = gst_asf_demux_identify_guid (asf_demux, asf_correction_guids, &(object->correction));
|
||||||
|
id = GUINT16_FROM_LE (object->id);
|
||||||
|
|
||||||
switch (stream_id) {
|
switch (stream_id) {
|
||||||
case ASF_STREAM_AUDIO:
|
case ASF_STREAM_AUDIO:
|
||||||
|
@ -981,13 +990,34 @@ gst_asf_demux_process_stream (GstASFDemux *asf_demux, guint64 *filepos, guint64
|
||||||
|
|
||||||
GST_INFO (GST_CAT_PLUGIN_INFO, "Object is an audio stream with %u bytes of additional data.", size);
|
GST_INFO (GST_CAT_PLUGIN_INFO, "Object is an audio stream with %u bytes of additional data.", size);
|
||||||
|
|
||||||
if (!gst_asf_demux_add_audio_stream (asf_demux, audio_object))
|
if (!gst_asf_demux_add_audio_stream (asf_demux, audio_object, id))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
switch (correction) {
|
switch (correction) {
|
||||||
case ASF_CORRECTION_ON:
|
case ASF_CORRECTION_ON:
|
||||||
GST_INFO (GST_CAT_PLUGIN_INFO, "Using error correction");
|
GST_INFO (GST_CAT_PLUGIN_INFO, "Using error correction");
|
||||||
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&correction_object, 8);
|
|
||||||
|
/* Have to read the first byte seperately to avoid endian problems */
|
||||||
|
got_bytes = gst_bytestream_read (asf_demux->bs, &buf, 1);
|
||||||
|
asf_demux->span = *GST_BUFFER_DATA (buf);
|
||||||
|
|
||||||
|
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&correction_object, 7);
|
||||||
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "Descrambling: ps:%d cs:%d ds:%d s:%d sd:%d", GUINT16_FROM_LE(correction_object->packet_size), GUINT16_FROM_LE(correction_object->chunk_size), GUINT16_FROM_LE(correction_object->data_size), asf_demux->span, correction_object->silence_data);
|
||||||
|
|
||||||
|
if (asf_demux->span > 1) {
|
||||||
|
if (!correction_object->chunk_size || ((correction_object->packet_size / correction_object->chunk_size) <= 1))
|
||||||
|
/* Disable descrambling */
|
||||||
|
asf_demux->span = 0;
|
||||||
|
} else {
|
||||||
|
/* Descambling is enabled */
|
||||||
|
asf_demux->ds_packet_size = correction_object->packet_size;
|
||||||
|
asf_demux->ds_chunk_size = correction_object->chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now skip the rest of the silence data */
|
||||||
|
if (correction_object->data_size > 1)
|
||||||
|
gst_bytestream_flush (asf_demux->bs, correction_object->data_size - 1);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ASF_CORRECTION_OFF:
|
case ASF_CORRECTION_OFF:
|
||||||
break;
|
break;
|
||||||
|
@ -996,21 +1026,6 @@ gst_asf_demux_process_stream (GstASFDemux *asf_demux, guint64 *filepos, guint64
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read any additional information */
|
|
||||||
if (size) {
|
|
||||||
got_bytes = gst_bytestream_read (asf_demux->bs, &buf, size);
|
|
||||||
/* There is additional data */
|
|
||||||
while (got_bytes < size) {
|
|
||||||
guint32 remaining;
|
|
||||||
GstEvent *event;
|
|
||||||
|
|
||||||
gst_bytestream_get_status (asf_demux->bs, &remaining, &event);
|
|
||||||
gst_event_unref (event);
|
|
||||||
|
|
||||||
got_bytes = gst_bytestream_read (asf_demux->bs, &buf, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ASF_STREAM_VIDEO:
|
case ASF_STREAM_VIDEO:
|
||||||
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&video_object, 11);
|
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&video_object, 11);
|
||||||
|
@ -1020,7 +1035,7 @@ gst_asf_demux_process_stream (GstASFDemux *asf_demux, guint64 *filepos, guint64
|
||||||
GST_INFO (GST_CAT_PLUGIN_INFO, "Object is a video stream with %u bytes of additional data.", size);
|
GST_INFO (GST_CAT_PLUGIN_INFO, "Object is a video stream with %u bytes of additional data.", size);
|
||||||
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&video_format_object, 40);
|
gst_asf_demux_read_object_header_rest (asf_demux, (guint8**)&video_format_object, 40);
|
||||||
|
|
||||||
if (!gst_asf_demux_add_video_stream (asf_demux, video_format_object))
|
if (!gst_asf_demux_add_video_stream (asf_demux, video_format_object, id))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Read any additional information */
|
/* Read any additional information */
|
||||||
|
@ -1115,9 +1130,68 @@ gst_asf_demux_process_object (GstASFDemux *asf_demux,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean gst_asf_demux_process_chunk (GstASFDemux *asf_demux,
|
|
||||||
asf_packet_info *packet_info,
|
static asf_stream_context *
|
||||||
asf_segment_info *segment_info)
|
gst_asf_demux_get_stream (GstASFDemux *asf_demux,
|
||||||
|
guint16 id)
|
||||||
|
{
|
||||||
|
guint8 i;
|
||||||
|
asf_stream_context *stream;
|
||||||
|
|
||||||
|
for (i = 0; i < asf_demux->num_streams; i++) {
|
||||||
|
stream = &asf_demux->stream[i];
|
||||||
|
if (stream->id == id) {
|
||||||
|
/* We've found the one with the matching id */
|
||||||
|
return &asf_demux->stream[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Base case if we haven't found one at all */
|
||||||
|
gst_element_error (GST_ELEMENT (asf_demux), "Segment found for undefined stream: (%d)", id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gst_asf_demux_descramble_segment (GstASFDemux *asf_demux,
|
||||||
|
asf_segment_info *segment_info,
|
||||||
|
asf_stream_context *stream) {
|
||||||
|
GstBuffer *scrambled_buffer;
|
||||||
|
GstBuffer *descrambled_buffer;
|
||||||
|
GstBuffer *sub_buffer;
|
||||||
|
guint offset;
|
||||||
|
guint off;
|
||||||
|
guint row;
|
||||||
|
guint col;
|
||||||
|
guint idx;
|
||||||
|
|
||||||
|
/* descrambled_buffer is initialised in the first iteration */
|
||||||
|
descrambled_buffer = NULL;
|
||||||
|
scrambled_buffer = stream->payload;
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
|
for (offset = 0; offset < segment_info->segment_size; offset += asf_demux->ds_chunk_size) {
|
||||||
|
off = offset / asf_demux->ds_chunk_size;
|
||||||
|
row = off / asf_demux->span;
|
||||||
|
col = off % asf_demux->span;
|
||||||
|
idx = row + col * asf_demux->ds_packet_size / asf_demux->ds_chunk_size;
|
||||||
|
sub_buffer = gst_buffer_create_sub (scrambled_buffer, idx * asf_demux->ds_chunk_size, asf_demux->ds_chunk_size);
|
||||||
|
if (!offset) {
|
||||||
|
descrambled_buffer = sub_buffer;
|
||||||
|
} else {
|
||||||
|
gst_buffer_merge (descrambled_buffer, sub_buffer);
|
||||||
|
gst_buffer_unref (sub_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->payload = descrambled_buffer;
|
||||||
|
gst_buffer_unref (scrambled_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_asf_demux_process_chunk (GstASFDemux *asf_demux,
|
||||||
|
asf_packet_info *packet_info,
|
||||||
|
asf_segment_info *segment_info)
|
||||||
{
|
{
|
||||||
asf_stream_context *stream;
|
asf_stream_context *stream;
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
|
@ -1126,36 +1200,38 @@ static gboolean gst_asf_demux_process_chunk (GstASFDemux *asf_demux,
|
||||||
GstByteStream *bs = asf_demux->bs;
|
GstByteStream *bs = asf_demux->bs;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
|
|
||||||
if (segment_info->stream_number > asf_demux->num_streams) {
|
if (!(stream = gst_asf_demux_get_stream (asf_demux, segment_info->stream_number)))
|
||||||
gst_element_error (GST_ELEMENT (asf_demux), "Segment found for stream out of range");
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
stream = &asf_demux->stream[segment_info->stream_number - 1];
|
|
||||||
|
|
||||||
GST_DEBUG (GST_CAT_PLUGIN_INFO, "Processing chunk of size %u", segment_info->chunk_size);
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "Processing chunk of size %u (fo = %d)", segment_info->chunk_size, stream->frag_offset);
|
||||||
|
|
||||||
if (stream->frag_offset == 0) {
|
if (stream->frag_offset == 0) {
|
||||||
/* new packet */
|
/* new packet */
|
||||||
stream->sequence = segment_info->sequence;
|
stream->sequence = segment_info->sequence;
|
||||||
asf_demux->pts = segment_info->frag_timestamp - asf_demux->preroll;
|
asf_demux->pts = segment_info->frag_timestamp - asf_demux->preroll;
|
||||||
got_bytes = gst_bytestream_peek (bs, &buffer, segment_info->chunk_size);
|
got_bytes = gst_bytestream_peek (bs, &buffer, segment_info->chunk_size);
|
||||||
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "BUFFER: Copied stream to buffer (%p - %d)", buffer, GST_BUFFER_REFCOUNT_VALUE(buffer));
|
||||||
stream->payload = buffer;
|
stream->payload = buffer;
|
||||||
} else {
|
} else {
|
||||||
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "segment_info->sequence = %d, stream->sequence = %d, segment_info->frag_offset = %d, stream->frag_offset = %d", segment_info->sequence, stream->sequence, segment_info->frag_offset, stream->frag_offset);
|
||||||
if (segment_info->sequence == stream->sequence &&
|
if (segment_info->sequence == stream->sequence &&
|
||||||
segment_info->frag_offset == stream->frag_offset) {
|
segment_info->frag_offset == stream->frag_offset) {
|
||||||
GstBuffer *new_buffer;
|
GstBuffer *new_buffer;
|
||||||
/* continuing packet */
|
/* continuing packet */
|
||||||
GST_INFO (GST_CAT_PLUGIN_INFO, "A continuation packet");
|
GST_INFO (GST_CAT_PLUGIN_INFO, "A continuation packet");
|
||||||
got_bytes = gst_bytestream_peek (bs, &buffer, segment_info->chunk_size);
|
got_bytes = gst_bytestream_peek (bs, &buffer, segment_info->chunk_size);
|
||||||
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "Copied stream to buffer (%p - %d)", buffer, GST_BUFFER_REFCOUNT_VALUE(buffer));
|
||||||
new_buffer = gst_buffer_merge (stream->payload, buffer);
|
new_buffer = gst_buffer_merge (stream->payload, buffer);
|
||||||
//gst_buffer_unref (stream->payload);
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "BUFFER: Merged new_buffer (%p - %d) from stream->payload(%p - %d) and buffer (%p - %d)", new_buffer, GST_BUFFER_REFCOUNT_VALUE(new_buffer), stream->payload, GST_BUFFER_REFCOUNT_VALUE(stream->payload), buffer, GST_BUFFER_REFCOUNT_VALUE(buffer));
|
||||||
//gst_buffer_unref (buffer);
|
gst_buffer_unref (stream->payload);
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
stream->payload = new_buffer;
|
stream->payload = new_buffer;
|
||||||
} else {
|
} else {
|
||||||
/* cannot continue current packet: free it */
|
/* cannot continue current packet: free it */
|
||||||
stream->frag_offset = 0;
|
stream->frag_offset = 0;
|
||||||
if (segment_info->frag_offset != 0) {
|
if (segment_info->frag_offset != 0) {
|
||||||
/* cannot create new packet */
|
/* cannot create new packet */
|
||||||
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "BUFFER: Freeing stream->payload (%p)", stream->payload);
|
||||||
gst_buffer_free(stream->payload);
|
gst_buffer_free(stream->payload);
|
||||||
gst_bytestream_flush (bs, segment_info->chunk_size);
|
gst_bytestream_flush (bs, segment_info->chunk_size);
|
||||||
packet_info->size_left -= segment_info->chunk_size;
|
packet_info->size_left -= segment_info->chunk_size;
|
||||||
|
@ -1167,14 +1243,25 @@ static gboolean gst_asf_demux_process_chunk (GstASFDemux *asf_demux,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet_info->size_left == segment_info->chunk_size) {
|
stream->frag_offset +=segment_info->chunk_size;
|
||||||
|
|
||||||
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "frag_offset = %d segment_size = %d ", stream->frag_offset, segment_info->segment_size);
|
||||||
|
|
||||||
|
if (stream->frag_offset < segment_info->segment_size) {
|
||||||
/* We don't have the whole packet yet */
|
/* We don't have the whole packet yet */
|
||||||
stream->frag_offset = segment_info->chunk_size;
|
} else {
|
||||||
} else {
|
/* We have the whole packet now so we should push the packet to
|
||||||
|
the src pad now. First though we should check if we need to do
|
||||||
|
descrambling */
|
||||||
|
if (asf_demux->span > 1) {
|
||||||
|
gst_asf_demux_descramble_segment (asf_demux, segment_info, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the timestamp */
|
||||||
format = GST_FORMAT_TIME;
|
format = GST_FORMAT_TIME;
|
||||||
gst_pad_query (stream->pad, GST_QUERY_POSITION, &format, &next_ts);
|
gst_pad_query (stream->pad, GST_QUERY_POSITION, &format, &next_ts);
|
||||||
|
|
||||||
GST_DEBUG (GST_CAT_PLUGIN_INFO, "Nextts is %llu\n", next_ts);
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "Nextts is %llu", next_ts);
|
||||||
|
|
||||||
if (GST_PAD_IS_USABLE (stream->pad)) {
|
if (GST_PAD_IS_USABLE (stream->pad)) {
|
||||||
GST_DEBUG (GST_CAT_PLUGIN_INFO, "New buffer is at: %p size: %u", GST_BUFFER_DATA(stream->payload), GST_BUFFER_SIZE(stream->payload));
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "New buffer is at: %p size: %u", GST_BUFFER_DATA(stream->payload), GST_BUFFER_SIZE(stream->payload));
|
||||||
|
@ -1182,16 +1269,20 @@ static gboolean gst_asf_demux_process_chunk (GstASFDemux *asf_demux,
|
||||||
GST_BUFFER_TIMESTAMP (stream->payload) = next_ts;
|
GST_BUFFER_TIMESTAMP (stream->payload) = next_ts;
|
||||||
|
|
||||||
/*!!! Should handle flush events here? */
|
/*!!! Should handle flush events here? */
|
||||||
GST_DEBUG (GST_CAT_PLUGIN_INFO, "Sending strem %d of size %d", stream->num , segment_info->chunk_size);
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, "Sending strem %d of size %d", stream->id , segment_info->chunk_size);
|
||||||
|
|
||||||
GST_INFO (GST_CAT_PLUGIN_INFO, "Pushing pad");
|
GST_INFO (GST_CAT_PLUGIN_INFO, "Pushing pad");
|
||||||
gst_pad_push (stream->pad, stream->payload);
|
gst_pad_push (stream->pad, stream->payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stream->frag_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_bytestream_flush (bs, segment_info->chunk_size);
|
gst_bytestream_flush (bs, segment_info->chunk_size);
|
||||||
packet_info->size_left -= segment_info->chunk_size;
|
packet_info->size_left -= segment_info->chunk_size;
|
||||||
|
|
||||||
|
GST_DEBUG (GST_CAT_PLUGIN_INFO, " ");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1411,13 +1502,17 @@ gst_asf_demux_identify_guid (GstASFDemux *asf_demux,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_asf_demux_add_audio_stream (GstASFDemux *asf_demux,
|
gst_asf_demux_add_audio_stream (GstASFDemux *asf_demux,
|
||||||
asf_stream_audio *audio)
|
asf_stream_audio *audio,
|
||||||
|
guint16 id)
|
||||||
{
|
{
|
||||||
GstPad *src_pad;
|
GstPad *src_pad;
|
||||||
GstCaps *new_caps = NULL;
|
GstCaps *new_caps = NULL;
|
||||||
GstCaps *caps_list = NULL;
|
GstCaps *caps_list = NULL;
|
||||||
gchar *name = NULL;
|
gchar *name = NULL;
|
||||||
GstPadTemplate *new_template = NULL;
|
GstPadTemplate *new_template = NULL;
|
||||||
|
guint16 size_left = 0;
|
||||||
|
|
||||||
|
size_left = GUINT16_FROM_LE(audio->size);
|
||||||
|
|
||||||
/* Create the audio pad */
|
/* Create the audio pad */
|
||||||
name = g_strdup_printf ("audio_%02d", asf_demux->num_audio_streams);
|
name = g_strdup_printf ("audio_%02d", asf_demux->num_audio_streams);
|
||||||
|
@ -1477,6 +1572,12 @@ gst_asf_demux_add_audio_stream (GstASFDemux *asf_demux,
|
||||||
"audio/a52",
|
"audio/a52",
|
||||||
NULL);
|
NULL);
|
||||||
break;
|
break;
|
||||||
|
case GST_RIFF_WAVE_FORMAT_DIVX:
|
||||||
|
case GST_RIFF_WAVE_FORMAT_divx:
|
||||||
|
new_caps = gst_caps_new ("asf_demux_audio_src",
|
||||||
|
"unknown/unknown",
|
||||||
|
NULL);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_warning ("asfdemux: unkown audio format %d", GUINT16_FROM_LE(audio->codec_tag));
|
g_warning ("asfdemux: unkown audio format %d", GUINT16_FROM_LE(audio->codec_tag));
|
||||||
break;
|
break;
|
||||||
|
@ -1487,13 +1588,20 @@ gst_asf_demux_add_audio_stream (GstASFDemux *asf_demux,
|
||||||
GST_INFO (GST_CAT_PLUGIN_INFO, "Adding audio stream %u codec %u (0x%x)", asf_demux->num_video_streams, GUINT16_FROM_LE(audio->codec_tag), GUINT16_FROM_LE(audio->codec_tag));
|
GST_INFO (GST_CAT_PLUGIN_INFO, "Adding audio stream %u codec %u (0x%x)", asf_demux->num_video_streams, GUINT16_FROM_LE(audio->codec_tag), GUINT16_FROM_LE(audio->codec_tag));
|
||||||
|
|
||||||
asf_demux->num_audio_streams++;
|
asf_demux->num_audio_streams++;
|
||||||
|
|
||||||
|
/* Swallow up any left over data */
|
||||||
|
if (size_left) {
|
||||||
|
g_warning ("asfdemux: Audio header contains %d bytes of surplus data", size_left);
|
||||||
|
gst_bytestream_flush (asf_demux->bs, size_left);
|
||||||
|
}
|
||||||
|
|
||||||
return gst_asf_demux_setup_pad (asf_demux, src_pad, caps_list);
|
return gst_asf_demux_setup_pad (asf_demux, src_pad, caps_list, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_asf_demux_add_video_stream (GstASFDemux *asf_demux,
|
gst_asf_demux_add_video_stream (GstASFDemux *asf_demux,
|
||||||
asf_stream_video_format *video_format) {
|
asf_stream_video_format *video_format,
|
||||||
|
guint16 id) {
|
||||||
GstPad *src_pad;
|
GstPad *src_pad;
|
||||||
GstCaps *new_caps = NULL;
|
GstCaps *new_caps = NULL;
|
||||||
GstCaps *caps_list = NULL;
|
GstCaps *caps_list = NULL;
|
||||||
|
@ -1511,18 +1619,17 @@ gst_asf_demux_add_video_stream (GstASFDemux *asf_demux,
|
||||||
"asf_demux_video_src",
|
"asf_demux_video_src",
|
||||||
"video/avi",
|
"video/avi",
|
||||||
"format", GST_PROPS_STRING ("strf_vids"),
|
"format", GST_PROPS_STRING ("strf_vids"),
|
||||||
//"size", GST_PROPS_INT (GUINT32_FROM_LE (video_format->size)),
|
"size", GST_PROPS_INT (GUINT32_FROM_LE (video_format->size)),
|
||||||
"width",GST_PROPS_INT (GUINT32_FROM_LE (video_format->width)),
|
"width",GST_PROPS_INT (GUINT32_FROM_LE (video_format->width)),
|
||||||
"height", GST_PROPS_INT (GUINT32_FROM_LE (video_format->height)),
|
"height", GST_PROPS_INT (GUINT32_FROM_LE (video_format->height)),
|
||||||
//"planes", GST_PROPS_INT (GUINT16_FROM_LE (video_format->planes)),
|
"planes", GST_PROPS_INT (GUINT16_FROM_LE (video_format->planes)),
|
||||||
//"bit_cnt", GST_PROPS_INT (GUINT16_FROM_LE (video_format->depth)),
|
"bit_cnt", GST_PROPS_INT (GUINT16_FROM_LE (video_format->depth)),
|
||||||
//"compression", GST_PROPS_FOURCC (GUINT32_FROM_LE (video_format->tag)),
|
"compression", GST_PROPS_FOURCC (GUINT32_FROM_LE (video_format->tag)),
|
||||||
"compression", GST_PROPS_FOURCC (GST_MAKE_FOURCC('D','I','V','3'))
|
"image_size", GST_PROPS_INT (GUINT32_FROM_LE (video_format->image_size)),
|
||||||
//"image_size", GST_PROPS_INT (GUINT32_FROM_LE (video_format->image_size)),
|
"xpels_meter", GST_PROPS_INT (GUINT32_FROM_LE (video_format->xpels_meter)),
|
||||||
//"xpels_meter", GST_PROPS_INT (GUINT32_FROM_LE (video_format->xpels_meter)),
|
"ypels_meter", GST_PROPS_INT (GUINT32_FROM_LE (video_format->ypels_meter)),
|
||||||
//"ypels_meter", GST_PROPS_INT (GUINT32_FROM_LE (video_format->ypels_meter)),
|
"num_colors", GST_PROPS_INT (GUINT32_FROM_LE (video_format->num_colors)),
|
||||||
//"num_colors", GST_PROPS_INT (GUINT32_FROM_LE (video_format->num_colors)),
|
"imp_colors", GST_PROPS_INT (GUINT32_FROM_LE (video_format->imp_colors))
|
||||||
//"imp_colors", GST_PROPS_INT (GUINT32_FROM_LE (video_format->imp_colors))
|
|
||||||
));
|
));
|
||||||
|
|
||||||
/* Now try some gstreamer formatted MIME types (from gst_avi_demux_strf_vids) */
|
/* Now try some gstreamer formatted MIME types (from gst_avi_demux_strf_vids) */
|
||||||
|
@ -1563,14 +1670,15 @@ gst_asf_demux_add_video_stream (GstASFDemux *asf_demux,
|
||||||
|
|
||||||
asf_demux->num_video_streams++;
|
asf_demux->num_video_streams++;
|
||||||
|
|
||||||
return gst_asf_demux_setup_pad (asf_demux, src_pad, caps_list);
|
return gst_asf_demux_setup_pad (asf_demux, src_pad, caps_list, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_asf_demux_setup_pad (GstASFDemux *asf_demux,
|
gst_asf_demux_setup_pad (GstASFDemux *asf_demux,
|
||||||
GstPad *src_pad,
|
GstPad *src_pad,
|
||||||
GstCaps *caps_list)
|
GstCaps *caps_list,
|
||||||
|
guint16 id)
|
||||||
{
|
{
|
||||||
asf_stream_context *stream;
|
asf_stream_context *stream;
|
||||||
|
|
||||||
|
@ -1583,7 +1691,7 @@ gst_asf_demux_setup_pad (GstASFDemux *asf_demux,
|
||||||
|
|
||||||
stream = &asf_demux->stream[asf_demux->num_streams];
|
stream = &asf_demux->stream[asf_demux->num_streams];
|
||||||
stream->pad = src_pad;
|
stream->pad = src_pad;
|
||||||
stream->num = asf_demux->num_streams;
|
stream->id = id;
|
||||||
stream->frag_offset = 0;
|
stream->frag_offset = 0;
|
||||||
stream->sequence = 0;
|
stream->sequence = 0;
|
||||||
stream->delay = 0LL;
|
stream->delay = 0LL;
|
||||||
|
|
|
@ -65,7 +65,7 @@ struct _GstASFStreamContext {
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
guint32 num;
|
guint16 id;
|
||||||
guint32 frag_offset;
|
guint32 frag_offset;
|
||||||
guint32 sequence;
|
guint32 sequence;
|
||||||
guint64 delay;
|
guint64 delay;
|
||||||
|
@ -82,7 +82,7 @@ struct _GstASFDemux {
|
||||||
|
|
||||||
#define GST_ASF_DEMUX_NUM_VIDEO_PADS 16
|
#define GST_ASF_DEMUX_NUM_VIDEO_PADS 16
|
||||||
#define GST_ASF_DEMUX_NUM_AUDIO_PADS 32
|
#define GST_ASF_DEMUX_NUM_AUDIO_PADS 32
|
||||||
#define GST_ASF_DEMUX_NUM_STREAMS 48
|
#define GST_ASF_DEMUX_NUM_STREAMS 16
|
||||||
|
|
||||||
/* stream output pads */
|
/* stream output pads */
|
||||||
GstPad *video_pad[GST_ASF_DEMUX_NUM_VIDEO_PADS];
|
GstPad *video_pad[GST_ASF_DEMUX_NUM_VIDEO_PADS];
|
||||||
|
@ -106,6 +106,13 @@ struct _GstASFDemux {
|
||||||
|
|
||||||
guint64 preroll;
|
guint64 preroll;
|
||||||
guint64 pts;
|
guint64 pts;
|
||||||
|
|
||||||
|
/* Descrambler settings */
|
||||||
|
guint8 span;
|
||||||
|
guint16 ds_packet_size;
|
||||||
|
guint16 ds_chunk_size;
|
||||||
|
guint16 ds_data_size;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstASFDemuxClass {
|
struct _GstASFDemuxClass {
|
||||||
|
|
Loading…
Reference in a new issue