gst_plugins_base/gst-libs/gst/tag/gsttagdemux.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
    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 }