gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c
branchtrunk
changeset 427 be6bb250b01a
parent 422 fc0a5721cd04
child 430 4476d11d6b9a
     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 15:19:38 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, &timestamp);
   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;