Beispiel #1
0
static GstFlowReturn
gst_mms_create (GstPushSrc * psrc, GstBuffer ** buf)
{
  GstMMS *mmssrc;
  guint8 *data;
  guint blocksize;
  gint result;
  mms_off_t offset;

  *buf = NULL;

  mmssrc = GST_MMS (psrc);

  offset = mmsx_get_current_pos (mmssrc->connection);

  /* Check if a seek perhaps has wrecked our connection */
  if (offset == -1) {
    GST_DEBUG_OBJECT (mmssrc,
        "connection broken (probably an error during mmsx_seek_time during a convert query) returning FLOW_ERROR");
    return GST_FLOW_ERROR;
  }

  /* Choose blocksize best for optimum performance */
  if (offset == 0)
    blocksize = mmsx_get_asf_header_len (mmssrc->connection);
  else
    blocksize = mmsx_get_asf_packet_len (mmssrc->connection);

  *buf = gst_buffer_new_and_alloc (blocksize);

  data = GST_BUFFER_DATA (*buf);
  GST_BUFFER_SIZE (*buf) = 0;
  GST_LOG_OBJECT (mmssrc, "reading %d bytes", blocksize);
  result = mmsx_read (NULL, mmssrc->connection, (char *) data, blocksize);

  /* EOS? */
  if (result == 0)
    goto eos;

  GST_BUFFER_OFFSET (*buf) = offset;
  GST_BUFFER_SIZE (*buf) = result;

  GST_LOG_OBJECT (mmssrc, "Returning buffer with offset %" G_GINT64_FORMAT
      " and size %u", GST_BUFFER_OFFSET (*buf), GST_BUFFER_SIZE (*buf));

  gst_buffer_set_caps (*buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (mmssrc)));

  return GST_FLOW_OK;

eos:
  {
    GST_DEBUG_OBJECT (mmssrc, "EOS");
    gst_buffer_unref (*buf);
    *buf = NULL;
    return GST_FLOW_UNEXPECTED;
  }
}
Beispiel #2
0
static GstFlowReturn
gst_mms_create (GstPushSrc * psrc, GstBuffer ** buf)
{
  GstMMS *mmssrc = GST_MMS (psrc);
  guint8 *data;
  guint blocksize;
  gint result;
  mms_off_t offset;

  *buf = NULL;

  offset = mmsx_get_current_pos (mmssrc->connection);

  /* Check if a seek perhaps has wrecked our connection */
  if (offset == -1) {
    GST_ERROR_OBJECT (mmssrc,
        "connection broken (probably an error during mmsx_seek_time during a convert query) returning FLOW_ERROR");
    return GST_FLOW_ERROR;
  }

  /* Choose blocksize best for optimum performance */
  if (offset == 0)
    blocksize = mmsx_get_asf_header_len (mmssrc->connection);
  else
    blocksize = mmsx_get_asf_packet_len (mmssrc->connection);

  data = g_try_malloc (blocksize);
  if (!data) {
    GST_ERROR_OBJECT (mmssrc, "Failed to allocate %u bytes", blocksize);
    return GST_FLOW_ERROR;
  }

  GST_LOG_OBJECT (mmssrc, "reading %d bytes", blocksize);
  result = mmsx_read (NULL, mmssrc->connection, (char *) data, blocksize);
  /* EOS? */
  if (result == 0)
    goto eos;

  *buf = gst_buffer_new_wrapped (data, result);
  GST_BUFFER_OFFSET (*buf) = offset;

  GST_LOG_OBJECT (mmssrc, "Returning buffer with offset %" G_GINT64_FORMAT
      " and size %u", offset, result);

  return GST_FLOW_OK;

eos:
  {
    GST_DEBUG_OBJECT (mmssrc, "EOS");
    g_free (data);
    *buf = NULL;
    return GST_FLOW_EOS;
  }
}
Beispiel #3
0
/* FIXME operating in TIME rather than BYTES could remove this altogether
 * and be more convenient elsewhere */
static gboolean
gst_mms_query (GstBaseSrc * src, GstQuery * query)
{
  GstMMS *mmssrc = GST_MMS (src);
  gboolean res = TRUE;
  GstFormat format;
  gint64 value;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
      gst_query_parse_position (query, &format, &value);
      if (format != GST_FORMAT_BYTES) {
        res = FALSE;
        break;
      }
      value = (gint64) mmsx_get_current_pos (mmssrc->connection);
      gst_query_set_position (query, format, value);
      break;
    case GST_QUERY_DURATION:
      if (!mmsx_get_seekable (mmssrc->connection)) {
        res = FALSE;
        break;
      }
      gst_query_parse_duration (query, &format, &value);
      switch (format) {
        case GST_FORMAT_BYTES:
          value = (gint64) mmsx_get_length (mmssrc->connection);
          gst_query_set_duration (query, format, value);
          break;
        case GST_FORMAT_TIME:
          value = mmsx_get_time_length (mmssrc->connection) * GST_SECOND;
          gst_query_set_duration (query, format, value);
          break;
        default:
          res = FALSE;
      }
      break;
    default:
      /* chain to parent */
      res =
          GST_BASE_SRC_CLASS (parent_class)->query (GST_BASE_SRC (src), query);
      break;
  }

  return res;
}
Beispiel #4
0
static gboolean
gst_mms_stop (GstBaseSrc * bsrc)
{
  GstMMS *mms = GST_MMS (bsrc);

  if (mms->connection != NULL) {
    /* Check if the connection is still pristine, that is if no more then
       just the mmslib cached asf header has been read. If it is still pristine
       preserve it as we often are re-started with the same URL and connecting
       is expensive */
    if (mmsx_get_current_pos (mms->connection) >
        mmsx_get_asf_header_len (mms->connection)) {
      mmsx_close (mms->connection);
      mms->connection = NULL;
      g_free (mms->current_connection_uri_name);
      mms->current_connection_uri_name = NULL;
    }
  }
  return TRUE;
}
Beispiel #5
0
static gboolean
gst_mms_do_seek (GstBaseSrc * src, GstSegment * segment)
{
  mms_off_t start;
  GstMMS *mmssrc = GST_MMS (src);

  if (segment->format == GST_FORMAT_TIME) {
    if (!mmsx_time_seek (NULL, mmssrc->connection,
            (double) segment->start / GST_SECOND)) {
      GST_LOG_OBJECT (mmssrc, "mmsx_time_seek() failed");
      return FALSE;
    }
    start = mmsx_get_current_pos (mmssrc->connection);
    GST_INFO_OBJECT (mmssrc, "sought to %" GST_TIME_FORMAT ", offset after "
        "seek: %" G_GINT64_FORMAT, GST_TIME_ARGS (segment->start), start);
  } else if (segment->format == GST_FORMAT_BYTES) {
    start = mmsx_seek (NULL, mmssrc->connection, segment->start, SEEK_SET);
    /* mmsx_seek will close and reopen the connection when seeking with the
       mmsh protocol, if the reopening fails this is indicated with -1 */
    if (start == -1) {
      GST_DEBUG_OBJECT (mmssrc, "connection broken during seek");
      return FALSE;
    }
    GST_INFO_OBJECT (mmssrc, "sought to: %" G_GINT64_FORMAT " bytes, "
        "result: %" G_GINT64_FORMAT, segment->start, start);
  } else {
    GST_DEBUG_OBJECT (mmssrc, "unsupported seek segment format: %s",
        GST_STR_NULL (gst_format_get_name (segment->format)));
    return FALSE;
  }
  gst_segment_init (segment, GST_FORMAT_BYTES);
  gst_segment_set_seek (segment, segment->rate, GST_FORMAT_BYTES,
      segment->flags, GST_SEEK_TYPE_SET, start, GST_SEEK_TYPE_NONE,
      segment->stop, NULL);
  return TRUE;
}