mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
Fix ASF demuxing. It works for me now, but I only tested it on one file. Please continue testing.
Original commit message from CVS: Fix ASF demuxing. It works for me now, but I only tested it on one file. Please continue testing.
This commit is contained in:
parent
72e48d3129
commit
87c829fb48
1 changed files with 75 additions and 81 deletions
|
@ -78,7 +78,7 @@ GST_PAD_TEMPLATE_FACTORY (sink_factory,
|
|||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_CAPS_NEW ("asf_asf_demux_sink",
|
||||
"video/x-asf",
|
||||
"video/x-ms-asf",
|
||||
NULL)
|
||||
);
|
||||
|
||||
|
@ -87,8 +87,7 @@ static void gst_asf_demux_init (GstASFDemux *asf_demux);
|
|||
static gboolean gst_asf_demux_send_event (GstElement *element,
|
||||
GstEvent *event);
|
||||
static void gst_asf_demux_loop (GstElement *element);
|
||||
static gboolean gst_asf_demux_process_object (GstASFDemux *asf_demux,
|
||||
guint64 *filepos);
|
||||
static gboolean gst_asf_demux_process_object (GstASFDemux *asf_demux);
|
||||
static void gst_asf_demux_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
|
@ -100,7 +99,9 @@ static gboolean gst_asf_demux_process_chunk (GstASFDemux *asf_demux,
|
|||
asf_packet_info *packet_info,
|
||||
asf_segment_info *segment_info);
|
||||
static const GstEventMask* gst_asf_demux_get_src_event_mask (GstPad *pad);
|
||||
static gboolean gst_asf_demux_handle_sink_event (GstASFDemux *asf_demux);
|
||||
static gboolean gst_asf_demux_handle_sink_event (GstASFDemux *asf_demux,
|
||||
GstEvent *event,
|
||||
guint32 remaining);
|
||||
static gboolean gst_asf_demux_handle_src_event (GstPad *pad,
|
||||
GstEvent *event);
|
||||
static const GstFormat* gst_asf_demux_get_src_formats (GstPad *pad);
|
||||
|
@ -223,22 +224,14 @@ static void
|
|||
gst_asf_demux_loop (GstElement *element)
|
||||
{
|
||||
GstASFDemux *asf_demux;
|
||||
guint64 filepos = 0;
|
||||
|
||||
g_return_if_fail (element != NULL);
|
||||
g_return_if_fail (GST_IS_ASF_DEMUX (element));
|
||||
|
||||
asf_demux = GST_ASF_DEMUX (element);
|
||||
|
||||
asf_demux->restart = FALSE;
|
||||
|
||||
/* this is basically an infinite loop */
|
||||
while (gst_asf_demux_process_object (asf_demux, &filepos)) { }
|
||||
GST_DEBUG ("Ending loop");
|
||||
if (!asf_demux->restart) {
|
||||
/* if we exit the loop we are EOS */
|
||||
gst_pad_event_default (asf_demux->sinkpad, gst_event_new (GST_EVENT_EOS));
|
||||
}
|
||||
gst_asf_demux_process_object (asf_demux);
|
||||
}
|
||||
|
||||
static guint32 gst_asf_demux_read_var_length (GstASFDemux *asf_demux, guint8 type, guint32 *rsize)
|
||||
|
@ -288,6 +281,9 @@ static guint32 gst_asf_demux_read_var_length (GstASFDemux *asf_demux, guint8 typ
|
|||
static void gst_asf_demux_read_object_header_rest (GstASFDemux *asf_demux, guint8 **buf, guint32 size) {
|
||||
guint32 got_bytes;
|
||||
GstByteStream *bs = asf_demux->bs;
|
||||
gboolean ret;
|
||||
GstEvent *event;
|
||||
guint32 remaining;
|
||||
|
||||
do {
|
||||
got_bytes = gst_bytestream_peek_bytes (bs, buf, size);
|
||||
|
@ -295,11 +291,13 @@ static void gst_asf_demux_read_object_header_rest (GstASFDemux *asf_demux, guint
|
|||
gst_bytestream_flush (bs, size);
|
||||
return;
|
||||
}
|
||||
} while (gst_asf_demux_handle_sink_event (asf_demux));
|
||||
gst_bytestream_get_status (bs, &remaining, &event);
|
||||
ret = gst_asf_demux_handle_sink_event (asf_demux, event, remaining);
|
||||
} while (ret);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_asf_demux_process_file (GstASFDemux *asf_demux, guint64 *filepos, guint64 *obj_size)
|
||||
gst_asf_demux_process_file (GstASFDemux *asf_demux, guint64 *obj_size)
|
||||
{
|
||||
asf_obj_file *object;
|
||||
guint8 *ptr;
|
||||
|
@ -319,7 +317,7 @@ gst_asf_demux_process_file (GstASFDemux *asf_demux, guint64 *filepos, guint64 *o
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_asf_demux_process_bitrate_props_object (GstASFDemux *asf_demux, guint64 *filepos, guint64 *obj_size)
|
||||
gst_asf_demux_process_bitrate_props_object (GstASFDemux *asf_demux, guint64 *obj_size)
|
||||
{
|
||||
guint32 got_bytes;
|
||||
GstBuffer *buf;
|
||||
|
@ -345,7 +343,7 @@ gst_asf_demux_process_bitrate_props_object (GstASFDemux *asf_demux, guint64 *fil
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_asf_demux_process_comment (GstASFDemux *asf_demux, guint64 *filepos, guint64 *obj_size)
|
||||
gst_asf_demux_process_comment (GstASFDemux *asf_demux, guint64 *obj_size)
|
||||
{
|
||||
asf_obj_comment *object;
|
||||
guint16 title_length;
|
||||
|
@ -380,7 +378,7 @@ gst_asf_demux_process_comment (GstASFDemux *asf_demux, guint64 *filepos, guint64
|
|||
|
||||
|
||||
static gboolean
|
||||
gst_asf_demux_process_header (GstASFDemux *asf_demux, guint64 *filepos, guint64 *obj_size)
|
||||
gst_asf_demux_process_header (GstASFDemux *asf_demux, guint64 *obj_size)
|
||||
{
|
||||
guint32 num_objects;
|
||||
asf_obj_header *object;
|
||||
|
@ -396,7 +394,7 @@ gst_asf_demux_process_header (GstASFDemux *asf_demux, guint64 *filepos, guint64
|
|||
|
||||
/* Loop through the header's objects, processing those */
|
||||
for (i = 0; i < num_objects; i++) {
|
||||
if (!gst_asf_demux_process_object (asf_demux, filepos)) {
|
||||
if (!gst_asf_demux_process_object (asf_demux)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -502,7 +500,7 @@ gst_asf_demux_process_segment (GstASFDemux *asf_demux,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_asf_demux_process_data (GstASFDemux *asf_demux, guint64 *filepos, guint64 *obj_size)
|
||||
gst_asf_demux_process_data (GstASFDemux *asf_demux, guint64 *obj_size)
|
||||
{
|
||||
asf_obj_data *object;
|
||||
asf_obj_data_packet *packet_properties_object;
|
||||
|
@ -611,7 +609,7 @@ gst_asf_demux_process_data (GstASFDemux *asf_demux, guint64 *filepos, guint64 *o
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_asf_demux_process_stream (GstASFDemux *asf_demux, guint64 *filepos, guint64 *obj_size)
|
||||
gst_asf_demux_process_stream (GstASFDemux *asf_demux, guint64 *obj_size)
|
||||
{
|
||||
asf_obj_stream *object;
|
||||
guint32 stream_id;
|
||||
|
@ -719,7 +717,7 @@ gst_asf_demux_process_stream (GstASFDemux *asf_demux, guint64 *filepos, guint64
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_asf_demux_skip_object (GstASFDemux *asf_demux, guint64 *filepos, guint64 *obj_size)
|
||||
gst_asf_demux_skip_object (GstASFDemux *asf_demux, guint64 *obj_size)
|
||||
{
|
||||
GstByteStream *bs = asf_demux->bs;
|
||||
|
||||
|
@ -735,63 +733,42 @@ gst_asf_demux_read_object_header (GstASFDemux *asf_demux, guint32 *obj_id, guint
|
|||
{
|
||||
guint32 got_bytes;
|
||||
ASFGuid *guid;
|
||||
guint64 *size;
|
||||
GstByteStream *bs = asf_demux->bs;
|
||||
guint8 *ptr;
|
||||
|
||||
|
||||
/* First get the GUID */
|
||||
got_bytes = gst_bytestream_peek_bytes (bs, &ptr, sizeof(ASFGuid));
|
||||
guid = (ASFGuid *)ptr;
|
||||
if (got_bytes < sizeof (ASFGuid)) {
|
||||
guint32 remaining;
|
||||
GstEvent *event;
|
||||
|
||||
gst_bytestream_get_status (bs, &remaining, &event);
|
||||
gst_event_unref (event);
|
||||
|
||||
if ((got_bytes = gst_bytestream_peek_bytes (bs, &ptr,
|
||||
sizeof(ASFGuid))) < sizeof(ASFGuid))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
guid = (ASFGuid *) ptr;
|
||||
*obj_id = gst_asf_demux_identify_guid (asf_demux, asf_object_guids, guid);
|
||||
|
||||
gst_bytestream_flush (bs, sizeof (ASFGuid));
|
||||
|
||||
if (*obj_id == ASF_OBJ_UNDEFINED) {
|
||||
GST_INFO ( "Object found with unknown GUID %08x %08x %08x %08x", guid->v1, guid->v2, guid->v3, guid->v4);
|
||||
gst_element_error (GST_ELEMENT (asf_demux), "Could not identify object");
|
||||
if ((got_bytes = gst_bytestream_peek_bytes (bs, &ptr,
|
||||
sizeof(guint64))) < sizeof(guint64))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now get the object size */
|
||||
got_bytes = gst_bytestream_peek_bytes (bs, &ptr, sizeof (guint64));
|
||||
size = (guint64 *)ptr;
|
||||
while (got_bytes < sizeof (guint64)) {
|
||||
guint32 remaining;
|
||||
GstEvent *event;
|
||||
|
||||
gst_bytestream_get_status (bs, &remaining, &event);
|
||||
gst_event_unref (event);
|
||||
|
||||
got_bytes = gst_bytestream_peek_bytes (bs, &ptr, sizeof (guint64));
|
||||
size = (guint64 *)ptr;
|
||||
}
|
||||
|
||||
*obj_size = GUINT64_FROM_LE (*size);
|
||||
*obj_size = GUINT64_FROM_LE(* (guint64 *) ptr);
|
||||
gst_bytestream_flush (bs, sizeof (guint64));
|
||||
|
||||
if (*obj_id == ASF_OBJ_UNDEFINED) {
|
||||
g_warning ("Could not identify object (0x%08x/0x%08x/0x%08x/0x%08x) with size=%llu",
|
||||
guid->v1, guid->v2, guid->v3, guid->v4, *obj_size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_asf_demux_process_object (GstASFDemux *asf_demux,
|
||||
guint64 *filepos) {
|
||||
gst_asf_demux_process_object (GstASFDemux *asf_demux) {
|
||||
|
||||
guint32 obj_id;
|
||||
guint64 obj_size;
|
||||
|
||||
if (!gst_asf_demux_read_object_header (asf_demux, &obj_id, &obj_size)) {
|
||||
g_print (" ***** Error reading object at filepos %" G_GUINT64_FORMAT "\n", *filepos);
|
||||
GST_DEBUG (" ***** Error reading object at filepos %" G_GUINT64_FORMAT " (EOS?)\n", /**filepos*/ gst_bytestream_tell (asf_demux->bs));
|
||||
gst_asf_demux_handle_sink_event (asf_demux, gst_event_new (GST_EVENT_EOS), 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -799,38 +776,39 @@ gst_asf_demux_process_object (GstASFDemux *asf_demux,
|
|||
|
||||
switch (obj_id) {
|
||||
case ASF_OBJ_STREAM:
|
||||
return gst_asf_demux_process_stream (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_process_stream (asf_demux, &obj_size);
|
||||
case ASF_OBJ_DATA:
|
||||
gst_asf_demux_process_data (asf_demux, filepos, &obj_size);
|
||||
gst_asf_demux_process_data (asf_demux, &obj_size);
|
||||
/* This is the last object */
|
||||
return FALSE;
|
||||
case ASF_OBJ_FILE:
|
||||
return gst_asf_demux_process_file (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_process_file (asf_demux, &obj_size);
|
||||
case ASF_OBJ_HEADER:
|
||||
return gst_asf_demux_process_header (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_process_header (asf_demux, &obj_size);
|
||||
case ASF_OBJ_CONCEAL_NONE:
|
||||
break;
|
||||
case ASF_OBJ_COMMENT:
|
||||
return gst_asf_demux_process_comment (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_process_comment (asf_demux, &obj_size);
|
||||
case ASF_OBJ_CODEC_COMMENT:
|
||||
return gst_asf_demux_skip_object (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_skip_object (asf_demux, &obj_size);
|
||||
case ASF_OBJ_INDEX:
|
||||
return gst_asf_demux_skip_object (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_skip_object (asf_demux, &obj_size);
|
||||
case ASF_OBJ_HEAD1:
|
||||
return gst_asf_demux_skip_object (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_skip_object (asf_demux, &obj_size);
|
||||
case ASF_OBJ_HEAD2:
|
||||
break;
|
||||
case ASF_OBJ_PADDING:
|
||||
return gst_asf_demux_skip_object (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_skip_object (asf_demux, &obj_size);
|
||||
case ASF_OBJ_EXT_CONTENT_DESC:
|
||||
return gst_asf_demux_skip_object (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_skip_object (asf_demux, &obj_size);
|
||||
case ASF_OBJ_BITRATE_PROPS:
|
||||
return gst_asf_demux_process_bitrate_props_object (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_process_bitrate_props_object (asf_demux, &obj_size);
|
||||
case ASF_OBJ_BITRATE_MUTEX:
|
||||
return gst_asf_demux_skip_object (asf_demux, filepos, &obj_size);
|
||||
return gst_asf_demux_skip_object (asf_demux, &obj_size);
|
||||
case ASF_OBJ_UNDEFINED:
|
||||
default:
|
||||
gst_element_error (GST_ELEMENT (asf_demux), "Unknown ASF object");
|
||||
return FALSE;
|
||||
/* unknown object read, just ignore it, we hate fatal errors */
|
||||
return gst_asf_demux_skip_object (asf_demux, &obj_size);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -989,21 +967,28 @@ gst_asf_demux_process_chunk (GstASFDemux *asf_demux,
|
|||
*/
|
||||
|
||||
static gboolean
|
||||
gst_asf_demux_handle_sink_event (GstASFDemux *asf_demux)
|
||||
gst_asf_demux_handle_sink_event (GstASFDemux *asf_demux,
|
||||
GstEvent *event,
|
||||
guint32 remaining)
|
||||
{
|
||||
guint32 remaining;
|
||||
GstEvent *event;
|
||||
GstEventType type;
|
||||
|
||||
gst_bytestream_get_status (asf_demux->bs, &remaining, &event);
|
||||
|
||||
type = event? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
|
||||
|
||||
switch (type) {
|
||||
case GST_EVENT_EOS:
|
||||
case GST_EVENT_EOS: {
|
||||
asf_stream_context *stream;
|
||||
GstEvent *event = gst_event_new (GST_EVENT_EOS);
|
||||
gint n;
|
||||
for (n = 0; n < asf_demux->num_streams; n++) {
|
||||
stream = &asf_demux->stream[n];
|
||||
gst_pad_push (stream->pad, GST_DATA (gst_event_ref (event)));
|
||||
}
|
||||
gst_event_unref (event);
|
||||
gst_bytestream_flush (asf_demux->bs, remaining);
|
||||
gst_pad_event_default (asf_demux->sinkpad, event);
|
||||
gst_element_set_eos (GST_ELEMENT (asf_demux));
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_FLUSH:
|
||||
g_warning ("flush event");
|
||||
break;
|
||||
|
@ -1146,7 +1131,6 @@ gst_asf_demux_change_state (GstElement *element)
|
|||
break;
|
||||
case GST_STATE_PAUSED_TO_READY:
|
||||
gst_bytestream_destroy (asf_demux->bs);
|
||||
asf_demux->restart = TRUE;
|
||||
for (i = 0 ; i < GST_ASF_DEMUX_NUM_VIDEO_PADS; i++) {
|
||||
asf_demux->video_PTS[i] = 0;
|
||||
}
|
||||
|
@ -1479,11 +1463,19 @@ gst_asf_demux_video_caps (guint32 codec_fcc,
|
|||
case GST_MAKE_FOURCC('D','I','V','3'):
|
||||
case GST_MAKE_FOURCC('D','I','V','4'):
|
||||
case GST_MAKE_FOURCC('D','I','V','5'):
|
||||
caps = GST_ASF_VID_CAPS_NEW ("asf_demux_video_src_div345",
|
||||
caps = GST_ASF_VID_CAPS_NEW ("asf_demux_video_src_div3",
|
||||
"video/x-divx",
|
||||
"divxversion", GST_PROPS_INT (3));
|
||||
break;
|
||||
|
||||
case GST_MAKE_FOURCC('D','I','V','X'):
|
||||
case GST_MAKE_FOURCC('d','i','v','x'):
|
||||
case GST_MAKE_FOURCC('D','X','5','0'):
|
||||
caps = GST_ASF_VID_CAPS_NEW ("asf_demux_video_src_div5",
|
||||
"video/x-divx",
|
||||
"divxversion", GST_PROPS_INT (5));
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("asfdemux: unkown video format " GST_FOURCC_FORMAT "(0x%08x)",
|
||||
GST_FOURCC_ARGS(codec_fcc), codec_fcc);
|
||||
|
@ -1575,6 +1567,8 @@ plugin_init (GModule *module, GstPlugin *plugin)
|
|||
GST_MAKE_FOURCC('M','P','G','4'),
|
||||
GST_MAKE_FOURCC('M','P','4','2'),
|
||||
GST_MAKE_FOURCC('M','P','4','3'),
|
||||
GST_MAKE_FOURCC('D','I','V','3'),
|
||||
GST_MAKE_FOURCC('D','X','5','0'),
|
||||
0 /* end */
|
||||
};
|
||||
gint aud_list[] = {
|
||||
|
|
Loading…
Reference in a new issue