Пример #1
0
/* open the file, do stuff necessary to go to PAUSED state */
static gboolean
gst_gnome_vfs_src_start (GstBaseSrc * basesrc)
{
  GnomeVFSResult res;
  GstGnomeVFSSrc *src;

  src = GST_GNOME_VFS_SRC (basesrc);

  gst_gnome_vfs_src_push_callbacks (src);

  if (src->uri != NULL) {
    GnomeVFSOpenMode mode = GNOME_VFS_OPEN_READ;

    /* this can block... */
    res = gnome_vfs_open_uri (&src->handle, src->uri, mode);
    if (res != GNOME_VFS_OK)
      goto open_failed;
    src->own_handle = TRUE;
  } else if (!src->handle) {
    goto no_filename;
  } else {
    src->own_handle = FALSE;
  }

  if (gnome_vfs_seek (src->handle, GNOME_VFS_SEEK_CURRENT, 0) == GNOME_VFS_OK) {
    src->seekable = TRUE;
  } else {
    src->seekable = FALSE;
  }

  return TRUE;

  /* ERRORS */
open_failed:
  {
    gchar *filename = gnome_vfs_uri_to_string (src->uri,
        GNOME_VFS_URI_HIDE_PASSWORD);

    gst_gnome_vfs_src_pop_callbacks (src);

    if (res == GNOME_VFS_ERROR_NOT_FOUND ||
        res == GNOME_VFS_ERROR_HOST_NOT_FOUND ||
        res == GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE) {
      GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
          ("Could not open vfs file \"%s\" for reading: %s (%d)",
              filename, gnome_vfs_result_to_string (res), res));
    } else {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Could not open vfs file \"%s\" for reading: %s (%d)",
              filename, gnome_vfs_result_to_string (res), res));
    }
    g_free (filename);
    return FALSE;
  }
no_filename:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No filename given"));
    return FALSE;
  }
}
Пример #2
0
static gboolean
gst_gnome_vfs_sink_handle_event (GstBaseSink * basesink, GstEvent * event)
{
    GstGnomeVFSSink *sink;
    gboolean ret = TRUE;

    sink = GST_GNOME_VFS_SINK (basesink);

    GST_DEBUG_OBJECT (sink, "processing %s event", GST_EVENT_TYPE_NAME (event));

    switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT: {
        GnomeVFSResult res;
        GstFormat format;
        gint64 offset;

        gst_event_parse_new_segment (event, NULL, NULL, &format, &offset,
                                     NULL, NULL);

        if (format != GST_FORMAT_BYTES) {
            GST_WARNING_OBJECT (sink, "ignored NEWSEGMENT event in %s format",
                                gst_format_get_name (format));
            break;
        }

        GST_LOG_OBJECT (sink, "seeking to offset %" G_GINT64_FORMAT, offset);
        res = gnome_vfs_seek (sink->handle, GNOME_VFS_SEEK_START, offset);

        if (res != GNOME_VFS_OK) {
            GST_ERROR_OBJECT (sink, "Failed to seek to offset %"
                              G_GINT64_FORMAT ": %s", offset, gnome_vfs_result_to_string (res));
            ret = FALSE;
        } else {
            sink->current_pos = offset;
        }

        break;
    }

    case GST_EVENT_FLUSH_START:
    case GST_EVENT_EOS: {
        /* No need to flush with GnomeVfs */
        break;
    }
    default:
        break;
    }

    return ret;
}
Пример #3
0
/*
 * Read a new buffer from src->reqoffset, takes care of events
 * and seeking and such.
 */
static GstFlowReturn
gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
    GstBuffer ** buffer)
{
  GnomeVFSResult res;
  GstBuffer *buf;
  GnomeVFSFileSize readbytes;
  guint8 *data;
  guint todo;
  GstGnomeVFSSrc *src;

  src = GST_GNOME_VFS_SRC (basesrc);

  GST_DEBUG ("now at %" G_GINT64_FORMAT ", reading from %" G_GUINT64_FORMAT
      ", size %u", src->curoffset, offset, size);

  /* seek if required */
  if (G_UNLIKELY (src->curoffset != offset)) {
    GST_DEBUG ("need to seek");
    if (src->seekable) {
      GST_DEBUG ("seeking to %" G_GUINT64_FORMAT, offset);
      res = gnome_vfs_seek (src->handle, GNOME_VFS_SEEK_START, offset);
      if (res != GNOME_VFS_OK)
        goto seek_failed;
      src->curoffset = offset;
    } else {
      goto cannot_seek;
    }
  }

  buf = gst_buffer_try_new_and_alloc (size);
  if (G_UNLIKELY (buf == NULL)) {
    GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
    return GST_FLOW_ERROR;
  }

  data = GST_BUFFER_DATA (buf);

  todo = size;
  while (todo > 0) {
    /* this can return less that we ask for */
    res = gnome_vfs_read (src->handle, data, todo, &readbytes);

    if (G_UNLIKELY (res == GNOME_VFS_ERROR_EOF || (res == GNOME_VFS_OK
                && readbytes == 0)))
      goto eos;

    if (G_UNLIKELY (res != GNOME_VFS_OK))
      goto read_failed;

    if (readbytes < todo) {
      data = &data[readbytes];
      todo -= readbytes;
    } else {
      todo = 0;
    }
    GST_LOG ("  got size %" G_GUINT64_FORMAT, readbytes);
  }
  GST_BUFFER_OFFSET (buf) = src->curoffset;
  src->curoffset += size;

  /* we're done, return the buffer */
  *buffer = buf;

  return GST_FLOW_OK;

seek_failed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SEEK, (NULL),
        ("Failed to seek to requested position %" G_GINT64_FORMAT ": %s",
            offset, gnome_vfs_result_to_string (res)));
    return GST_FLOW_ERROR;
  }
cannot_seek:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SEEK, (NULL),
        ("Requested seek from %" G_GINT64_FORMAT " to %" G_GINT64_FORMAT
            " on non-seekable stream", src->curoffset, offset));
    return GST_FLOW_ERROR;
  }
read_failed:
  {
    gst_buffer_unref (buf);
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("Failed to read data: %s", gnome_vfs_result_to_string (res)));
    return GST_FLOW_ERROR;
  }
eos:
  {
    gst_buffer_unref (buf);
    GST_DEBUG_OBJECT (src, "Reading data gave EOS");
    return GST_FLOW_UNEXPECTED;
  }
}