1.1 --- a/gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c Wed Mar 21 14:51:07 2007 +0000
1.2 +++ b/gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c Thu Mar 22 18:13:13 2007 +0000
1.3 @@ -257,6 +257,8 @@
1.4 gboolean active);
1.5 static gboolean gst_nuv_demux_sink_activate (GstPad * sinkpad);
1.6 static gboolean gst_nuv_demux_sink_event (GstPad *pad, GstEvent *event);
1.7 +static gboolean gst_nuv_demux_srcpad_event (GstPad * pad, GstEvent * event);
1.8 +
1.9 static GstFlowReturn gst_nuv_demux_read_bytes (GstNuvDemux * nuv, guint64 size,
1.10 gboolean move, GstBuffer ** buffer);
1.11 static void gst_nuv_demux_reset (GstNuvDemux * nuv);
1.12 @@ -634,6 +636,8 @@
1.13 gst_pad_set_active (pad, TRUE);
1.14 gst_pad_use_fixed_caps (pad);
1.15 gst_element_add_pad (GST_ELEMENT (nuv), pad);
1.16 + gst_pad_set_event_function (pad,
1.17 + GST_DEBUG_FUNCPTR (gst_nuv_demux_srcpad_event));
1.18
1.19 return pad;
1.20 }
1.21 @@ -674,14 +678,79 @@
1.22 gst_element_no_more_pads (GST_ELEMENT (nuv));
1.23 }
1.24
1.25 +static gboolean
1.26 +gst_nuv_demux_validate_header (nuv_frame_header *h)
1.27 +{
1.28 + gboolean valid = FALSE;
1.29 + //g_debug ("Type %d = Compression %d", h->i_type, h->i_compression);
1.30 + //g_usleep (1 * G_USEC_PER_SEC );
1.31 + switch (h->i_type) {
1.32 +/*
1.33 + case 'V':
1.34 + if (h->i_compression == 0 ||
1.35 + h->i_compression == 1 ||
1.36 + h->i_compression == 2 ||
1.37 + h->i_compression == 'N' ||
1.38 + h->i_compression == 'L') {
1.39 + valid = TRUE;
1.40 + }
1.41 + break;
1.42 + case 'A':
1.43 + if (h->i_compression == 0 ||
1.44 + h->i_compression == 1 ||
1.45 + h->i_compression == 2 ||
1.46 + h->i_compression == 3 ||
1.47 + h->i_compression == 'F' ||
1.48 + h->i_compression == 'S' ||
1.49 + h->i_compression == 'N' ||
1.50 + h->i_compression == 'L') {
1.51 + valid = TRUE;
1.52 + }
1.53 + break;
1.54 + case 'S':
1.55 + if (h->i_compression == 'B' ||
1.56 + h->i_compression == 'A' ||
1.57 + h->i_compression == 'V' ||
1.58 + h->i_compression == 'S') {
1.59 + valid = TRUE;
1.60 + }
1.61 + break;
1.62 +*/
1.63 + case 'A':
1.64 + case 'V':
1.65 + case 'S':
1.66 + case 'R':
1.67 + case 'D':
1.68 + valid = TRUE;
1.69 + break;
1.70 + default:
1.71 + valid = FALSE;
1.72 + }
1.73 +
1.74 + return valid;
1.75 +}
1.76 +
1.77 static GstFlowReturn
1.78 gst_nuv_demux_read_head_frame (GstNuvDemux * nuv)
1.79 {
1.80 GstFlowReturn ret = GST_FLOW_OK;
1.81 + gboolean valid = FALSE;
1.82
1.83 - ret = gst_nuv_demux_frame_header_load (nuv, &nuv->priv->fh);
1.84 - if (ret != GST_FLOW_OK)
1.85 - return ret;
1.86 + do {
1.87 + ret = gst_nuv_demux_frame_header_load (nuv, &nuv->priv->fh);
1.88 + if (ret != GST_FLOW_OK) {
1.89 + g_debug ("FAIL TO READ HEADER");
1.90 + return ret;
1.91 + }
1.92 +
1.93 + if (gst_nuv_demux_validate_header (&nuv->priv->fh) == TRUE)
1.94 + valid = TRUE;
1.95 + else
1.96 + g_debug ("Invalid frame header");
1.97 +
1.98 + } while (valid == FALSE);
1.99 +
1.100 +// } while (gst_nuv_demux_validate_header (nuv->priv->fh));
1.101
1.102 nuv->priv->state = GST_NUV_DEMUX_MOVI;
1.103 return ret;
1.104 @@ -721,18 +790,18 @@
1.105 goto done;
1.106
1.107 if (h.i_length > 0) {
1.108 - ret = gst_nuv_demux_read_bytes (nuv, h.i_length, TRUE, &buf);
1.109 - if ((ret != GST_FLOW_OK) || (buf == NULL)) {
1.110 - goto done;
1.111 - }
1.112 + ret = gst_nuv_demux_read_bytes (nuv, h.i_length, TRUE, &buf);
1.113 + if ((ret != GST_FLOW_OK) || (buf == NULL)) {
1.114 + goto done;
1.115 + }
1.116
1.117 - if ((h.i_timecode < 0)) {
1.118 - h.i_timecode = 0;
1.119 - //goto done;
1.120 - }
1.121 + if ((h.i_timecode < 0)) {
1.122 + h.i_timecode = 0;
1.123 + //goto done;
1.124 + }
1.125
1.126 - timestamp = h.i_timecode * GST_MSECOND;
1.127 - GST_BUFFER_TIMESTAMP (buf) = timestamp;
1.128 + timestamp = h.i_timecode * GST_MSECOND;
1.129 + GST_BUFFER_TIMESTAMP (buf) = timestamp;
1.130 }
1.131 else {
1.132 goto done;
1.133 @@ -824,10 +893,11 @@
1.134
1.135 /* verify anothers flow if is necessary stop task */
1.136 if (gst_nuv_combine_flow (nuv) != FALSE) {
1.137 - ret = GST_FLOW_OK;
1.138 - }
1.139 + ret = GST_FLOW_OK;
1.140 + } else {
1.141 + GST_WARNING_OBJECT (nuv, "error: on push");
1.142 + }
1.143
1.144 - //GST_WARNING_OBJECT (nuv, "error: %d pushing on srcpad %s", ret, gst_pad_get_name (pad));
1.145 }
1.146 }
1.147
1.148 @@ -942,6 +1012,7 @@
1.149 return res;
1.150 }
1.151
1.152 +
1.153 static GstFlowReturn
1.154 gst_nuv_demux_play (GstPad * pad)
1.155 {
1.156 @@ -998,7 +1069,7 @@
1.157 }
1.158 break;
1.159
1.160 - case GST_NUV_DEMUX_MOVI:
1.161 + case GST_NUV_DEMUX_MOVI:
1.162 res = gst_nuv_demux_stream_data (nuv);
1.163 if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
1.164 goto pause;
1.165 @@ -1142,6 +1213,88 @@
1.166 return TRUE;
1.167 }
1.168
1.169 +static gboolean
1.170 +gst_nuv_demux_do_seek (GstNuvDemux *nuv, GstEvent * event)
1.171 +{
1.172 + gdouble rate;
1.173 + GstFormat format;
1.174 + GstSeekFlags flags;
1.175 + GstSeekType cur_type;
1.176 + gint64 cur;
1.177 + GstSeekType stop_type;
1.178 + gint64 stop;
1.179 + gboolean flush;
1.180 +
1.181 + g_debug ("DEMUX SEEK");
1.182 + gst_event_parse_seek (event, &rate, &format, &flags,
1.183 + &cur_type, &cur, &stop_type, &stop);
1.184 +
1.185 + if (format == GST_FORMAT_BYTES &&
1.186 + nuv->priv->state > GST_NUV_DEMUX_EXTEND_HEADER_DATA &&
1.187 + gst_pad_is_linked (nuv->priv->sinkpad)) {
1.188 +
1.189 + flush = flags & GST_SEEK_FLAG_FLUSH;
1.190 + if (flush) {
1.191 + gst_pad_push_event (nuv->priv->sinkpad, gst_event_new_flush_start ());
1.192 +
1.193 + if (nuv->priv->src_video_pad != NULL) {
1.194 + gst_pad_push_event (nuv->priv->src_video_pad, gst_event_new_flush_start ());
1.195 + }
1.196 +
1.197 + if (nuv->priv->src_audio_pad != NULL) {
1.198 + gst_pad_push_event (nuv->priv->src_audio_pad, gst_event_new_flush_start ());
1.199 + }
1.200 + }
1.201 + else {
1.202 + gst_pad_pause_task (nuv->priv->sinkpad);
1.203 + }
1.204 +
1.205 + GST_PAD_STREAM_LOCK (nuv->priv->sinkpad);
1.206 +
1.207 + g_debug ("offset %ld, cur %ld", nuv->priv->offset, cur);
1.208 +
1.209 + nuv->priv->state = GST_NUV_DEMUX_FRAME_HEADER;
1.210 +
1.211 + if (flush) {
1.212 + gst_pad_push_event (nuv->priv->sinkpad, gst_event_new_flush_stop ());
1.213 +
1.214 + if (nuv->priv->src_video_pad != NULL) {
1.215 + gst_pad_push_event (nuv->priv->src_video_pad, gst_event_new_flush_stop ());
1.216 + }
1.217 +
1.218 + if (nuv->priv->src_audio_pad != NULL) {
1.219 + gst_pad_push_event (nuv->priv->src_audio_pad, gst_event_new_flush_stop ());
1.220 + }
1.221 + }
1.222 +
1.223 + g_debug ("STARTING TASK AGAIN");
1.224 + gst_pad_start_task (nuv->priv->sinkpad, (GstTaskFunction) gst_nuv_demux_loop,
1.225 + nuv->priv->sinkpad);
1.226 +
1.227 + GST_PAD_STREAM_UNLOCK (nuv->priv->sinkpad);
1.228 + return TRUE;
1.229 + }
1.230 + return FALSE;
1.231 +}
1.232 +
1.233 +static gboolean
1.234 +gst_nuv_demux_srcpad_event (GstPad * pad, GstEvent * event)
1.235 +{
1.236 + gboolean res = FALSE;
1.237 + GstNuvDemux *nuv;
1.238 +
1.239 + nuv = GST_NUV_DEMUX (gst_pad_get_parent (pad));
1.240 +
1.241 + switch (GST_EVENT_TYPE (event)) {
1.242 + case GST_EVENT_SEEK:
1.243 + res = gst_nuv_demux_do_seek (nuv, event);
1.244 + break;
1.245 + default:
1.246 + res = FALSE;
1.247 + break;
1.248 + }
1.249 + return res;
1.250 +}
1.251
1.252 static gboolean
1.253 gst_nuv_demux_sink_event (GstPad *pad, GstEvent *event)
1.254 @@ -1165,6 +1318,7 @@
1.255 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, &stop_type, &stop);
1.256 GST_DEBUG_OBJECT (nuv, "got seek, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, cur, stop);
1.257 g_debug ("got seek, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, cur, stop);
1.258 + res = gst_pad_event_default (pad, event);
1.259 break;
1.260 }
1.261 case GST_EVENT_NEWSEGMENT:
1.262 @@ -1174,32 +1328,13 @@
1.263 GstFormat format;
1.264 gboolean update;
1.265
1.266 - GST_DEBUG_OBJECT (nuv, "got a new segment event");
1.267 gst_event_parse_new_segment (event, &update, &rate, &format, &start, &stop, &time);
1.268 -
1.269 GST_DEBUG_OBJECT (nuv, "got newsegment, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, start, stop);
1.270 g_debug ("got newsegment, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, start, stop);
1.271 - nuv->priv->duration_bytes = stop - start;
1.272 - gst_event_unref (event);
1.273 - res = TRUE;
1.274 + //nuv->priv->duration_bytes = stop - start;
1.275 + res = gst_pad_event_default (pad, event);
1.276 break;
1.277 }
1.278 - case GST_EVENT_QOS:
1.279 - {
1.280 -/*
1.281 - gdouble proportion;
1.282 - GstClockTimeDiff diff;
1.283 - GstClockTime timestamp;
1.284 -
1.285 - gst_event_parse_qos (event, &proportion, &diff, ×tamp);
1.286 - if (diff > 0)
1.287 - nuv->time_qos = timecode + diff;
1.288 - else
1.289 - nuv->time_qos = -1;
1.290 -*/
1.291 - break;
1.292 - }
1.293 -
1.294 case GST_EVENT_EOS:
1.295 default:
1.296 res = gst_pad_event_default (pad, event);
1.297 @@ -1299,8 +1434,9 @@
1.298 }
1.299
1.300 switch (transition) {
1.301 - case GST_STATE_CHANGE_READY_TO_NULL:
1.302 - g_debug ("READY_TO_NULL");
1.303 + case GST_STATE_CHANGE_PAUSED_TO_READY:
1.304 + //case GST_STATE_CHANGE_READY_TO_NULL:
1.305 + g_debug ("PAUSED_TO_READY");
1.306 gst_nuv_demux_reset (GST_NUV_DEMUX (element));
1.307 gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (element));
1.308 break;