equal
deleted
inserted
replaced
73 #endif |
73 #endif |
74 |
74 |
75 #include "gsttagdemux.h" |
75 #include "gsttagdemux.h" |
76 |
76 |
77 #include <gst/base/gsttypefindhelper.h> |
77 #include <gst/base/gsttypefindhelper.h> |
|
78 #ifndef __SYMBIAN32__ |
78 #include <gst/gst-i18n-plugin.h> |
79 #include <gst/gst-i18n-plugin.h> |
|
80 #else |
|
81 #include "gst/gst-i18n-plugin.h" |
|
82 #endif |
79 #include <string.h> |
83 #include <string.h> |
80 |
84 |
81 typedef enum |
85 typedef enum |
82 { |
86 { |
83 GST_TAG_DEMUX_READ_START_TAG, |
87 GST_TAG_DEMUX_READ_START_TAG, |
109 gboolean send_tag_event; |
113 gboolean send_tag_event; |
110 |
114 |
111 GstSegment segment; |
115 GstSegment segment; |
112 gboolean need_newseg; |
116 gboolean need_newseg; |
113 gboolean newseg_update; |
117 gboolean newseg_update; |
114 |
|
115 GList *pending_events; |
|
116 }; |
118 }; |
117 |
119 |
118 /* Require at least 8kB of data before we attempt typefind. |
120 /* Require at least 8kB of data before we attempt typefind. |
119 * Seems a decent value based on test files |
121 * Seems a decent value based on test files |
120 * 40kB is massive overkill for the maximum, I think, but it |
122 * 40kB is massive overkill for the maximum, I think, but it |
162 static void gst_tag_demux_base_init (gpointer g_class); |
164 static void gst_tag_demux_base_init (gpointer g_class); |
163 static void gst_tag_demux_class_init (gpointer g_class, gpointer d); |
165 static void gst_tag_demux_class_init (gpointer g_class, gpointer d); |
164 static void gst_tag_demux_init (GstTagDemux * obj, GstTagDemuxClass * klass); |
166 static void gst_tag_demux_init (GstTagDemux * obj, GstTagDemuxClass * klass); |
165 |
167 |
166 static gpointer parent_class; /* NULL */ |
168 static gpointer parent_class; /* NULL */ |
167 #ifdef __SYMBIAN32__ |
|
168 EXPORT_C |
|
169 #endif |
|
170 |
|
171 |
|
172 GType |
|
173 gst_tag_demux_result_get_type (void) |
|
174 { |
|
175 static GType etype = 0; |
|
176 if (etype == 0) { |
|
177 static const GEnumValue values[] = { |
|
178 {GST_TAG_DEMUX_RESULT_BROKEN_TAG, "GST_TAG_DEMUX_RESULT_BROKEN_TAG", |
|
179 "broken-tag"}, |
|
180 {GST_TAG_DEMUX_RESULT_AGAIN, "GST_TAG_DEMUX_RESULT_AGAIN", "again"}, |
|
181 {GST_TAG_DEMUX_RESULT_OK, "GST_TAG_DEMUX_RESULT_OK", "ok"}, |
|
182 {0, NULL, NULL} |
|
183 }; |
|
184 etype = g_enum_register_static ("GstTagDemuxResult", values); |
|
185 } |
|
186 return etype; |
|
187 } |
|
188 |
169 |
189 /* Cannot use boilerplate macros here because we want the abstract flag */ |
170 /* Cannot use boilerplate macros here because we want the abstract flag */ |
190 #ifdef __SYMBIAN32__ |
171 #ifdef __SYMBIAN32__ |
191 EXPORT_C |
172 EXPORT_C |
192 #endif |
173 #endif |
275 } |
256 } |
276 |
257 |
277 gst_segment_init (&tagdemux->priv->segment, GST_FORMAT_UNDEFINED); |
258 gst_segment_init (&tagdemux->priv->segment, GST_FORMAT_UNDEFINED); |
278 tagdemux->priv->need_newseg = TRUE; |
259 tagdemux->priv->need_newseg = TRUE; |
279 tagdemux->priv->newseg_update = FALSE; |
260 tagdemux->priv->newseg_update = FALSE; |
280 |
|
281 g_list_foreach (tagdemux->priv->pending_events, |
|
282 (GFunc) gst_mini_object_unref, NULL); |
|
283 g_list_free (tagdemux->priv->pending_events); |
|
284 tagdemux->priv->pending_events = NULL; |
|
285 } |
261 } |
286 |
262 |
287 static void |
263 static void |
288 gst_tag_demux_init (GstTagDemux * demux, GstTagDemuxClass * gclass) |
264 gst_tag_demux_init (GstTagDemux * demux, GstTagDemuxClass * gclass) |
289 { |
265 { |
444 } else { |
420 } else { |
445 out_offset -= tagdemux->priv->strip_start; |
421 out_offset -= tagdemux->priv->strip_start; |
446 } |
422 } |
447 need_sub = TRUE; |
423 need_sub = TRUE; |
448 } |
424 } |
|
425 |
|
426 g_assert (out_size > 0); |
449 |
427 |
450 if (need_sub == TRUE) { |
428 if (need_sub == TRUE) { |
451 if (out_size != GST_BUFFER_SIZE (buf) || !gst_buffer_is_writable (buf)) { |
429 if (out_size != GST_BUFFER_SIZE (buf) || !gst_buffer_is_writable (buf)) { |
452 GstBuffer *sub; |
430 GstBuffer *sub; |
453 |
431 |
676 demux->priv->collect = NULL; |
654 demux->priv->collect = NULL; |
677 if (!gst_tag_demux_trim_buffer (demux, &outbuf)) |
655 if (!gst_tag_demux_trim_buffer (demux, &outbuf)) |
678 return GST_FLOW_UNEXPECTED; |
656 return GST_FLOW_UNEXPECTED; |
679 } |
657 } |
680 if (outbuf) { |
658 if (outbuf) { |
681 GList *events; |
|
682 |
|
683 if (G_UNLIKELY (demux->priv->srcpad == NULL)) { |
659 if (G_UNLIKELY (demux->priv->srcpad == NULL)) { |
684 gst_buffer_unref (outbuf); |
660 gst_buffer_unref (outbuf); |
685 return GST_FLOW_ERROR; |
661 return GST_FLOW_ERROR; |
686 } |
662 } |
687 |
663 |
692 "event as it should"); |
668 "event as it should"); |
693 } |
669 } |
694 demux->priv->need_newseg = FALSE; |
670 demux->priv->need_newseg = FALSE; |
695 } |
671 } |
696 |
672 |
697 /* send any pending events we cached */ |
673 /* Send pending tag event */ |
698 GST_OBJECT_LOCK (demux); |
|
699 events = demux->priv->pending_events; |
|
700 demux->priv->pending_events = NULL; |
|
701 GST_OBJECT_UNLOCK (demux); |
|
702 |
|
703 while (events != NULL) { |
|
704 GST_DEBUG_OBJECT (demux->priv->srcpad, "sending cached %s event: %" |
|
705 GST_PTR_FORMAT, GST_EVENT_TYPE_NAME (events->data), events->data); |
|
706 gst_pad_push_event (demux->priv->srcpad, GST_EVENT (events->data)); |
|
707 events = g_list_delete_link (events, events); |
|
708 } |
|
709 |
|
710 /* Send our own pending tag event */ |
|
711 if (demux->priv->send_tag_event) { |
674 if (demux->priv->send_tag_event) { |
712 gst_tag_demux_send_tag_event (demux); |
675 gst_tag_demux_send_tag_event (demux); |
713 demux->priv->send_tag_event = FALSE; |
676 demux->priv->send_tag_event = FALSE; |
714 } |
677 } |
715 |
678 |
763 gst_event_unref (event); |
726 gst_event_unref (event); |
764 ret = TRUE; |
727 ret = TRUE; |
765 break; |
728 break; |
766 } |
729 } |
767 default: |
730 default: |
768 if (demux->priv->need_newseg) { |
731 ret = gst_pad_event_default (pad, event); |
769 /* Cache all events if we have a pending segment, so they don't get |
|
770 * lost (esp. tag events) */ |
|
771 GST_INFO_OBJECT (demux, "caching event: %" GST_PTR_FORMAT, event); |
|
772 GST_OBJECT_LOCK (demux); |
|
773 demux->priv->pending_events = |
|
774 g_list_append (demux->priv->pending_events, event); |
|
775 GST_OBJECT_UNLOCK (demux); |
|
776 ret = TRUE; |
|
777 } else { |
|
778 ret = gst_pad_event_default (pad, event); |
|
779 } |
|
780 break; |
732 break; |
781 } |
733 } |
782 |
734 |
783 gst_object_unref (demux); |
735 gst_object_unref (demux); |
784 return ret; |
736 return ret; |
875 res = gst_pad_push_event (tagdemux->priv->sinkpad, upstream); |
827 res = gst_pad_push_event (tagdemux->priv->sinkpad, upstream); |
876 } |
828 } |
877 break; |
829 break; |
878 } |
830 } |
879 default: |
831 default: |
880 res = gst_pad_push_event (tagdemux->priv->sinkpad, event); |
832 /* FIXME: shouldn't we pass unknown and unhandled events upstream? */ |
881 event = NULL; |
|
882 break; |
833 break; |
883 } |
834 } |
884 |
835 |
885 gst_object_unref (tagdemux); |
836 gst_object_unref (tagdemux); |
886 if (event) |
837 gst_event_unref (event); |
887 gst_event_unref (event); |
|
888 return res; |
838 return res; |
889 } |
839 } |
890 |
840 |
891 /* Read and interpret any end tag when activating in pull_range. |
841 /* Read and interpret any end tag when activating in pull_range. |
892 * Returns FALSE if pad activation should fail. */ |
842 * Returns FALSE if pad activation should fail. */ |
1207 |
1157 |
1208 if (demux->priv->parsed_tags != NULL) { |
1158 if (demux->priv->parsed_tags != NULL) { |
1209 demux->priv->send_tag_event = TRUE; |
1159 demux->priv->send_tag_event = TRUE; |
1210 } |
1160 } |
1211 |
1161 |
1212 if (demux->priv->upstream_size <= |
|
1213 demux->priv->strip_start + demux->priv->strip_end) { |
|
1214 /* There was no data (probably due to a truncated file) */ |
|
1215 GST_DEBUG_OBJECT (demux, "No data in file"); |
|
1216 return FALSE; |
|
1217 } |
|
1218 |
|
1219 /* 3 - Do typefinding on data */ |
1162 /* 3 - Do typefinding on data */ |
1220 caps = gst_type_find_helper_get_range (GST_OBJECT (demux), |
1163 caps = gst_type_find_helper_get_range (GST_OBJECT (demux), |
1221 (GstTypeFindHelperGetRangeFunction) gst_tag_demux_read_range, |
1164 (GstTypeFindHelperGetRangeFunction) gst_tag_demux_read_range, |
1222 demux->priv->upstream_size |
1165 demux->priv->upstream_size |
1223 - (demux->priv->strip_start + demux->priv->strip_end), &probability); |
1166 - (demux->priv->strip_start + demux->priv->strip_end), &probability); |
1324 |
1267 |
1325 read_beyond_end: |
1268 read_beyond_end: |
1326 { |
1269 { |
1327 GST_DEBUG_OBJECT (demux, "attempted read beyond end of file"); |
1270 GST_DEBUG_OBJECT (demux, "attempted read beyond end of file"); |
1328 if (*buffer != NULL) { |
1271 if (*buffer != NULL) { |
1329 gst_buffer_unref (*buffer); |
1272 gst_buffer_unref (buffer); |
1330 *buffer = NULL; |
1273 *buffer = NULL; |
1331 } |
1274 } |
1332 return GST_FLOW_UNEXPECTED; |
1275 return GST_FLOW_UNEXPECTED; |
1333 } |
1276 } |
1334 } |
1277 } |