Пример #1
0
static VALUE
async_start_initialize(VALUE self, VALUE src, VALUE new_base_time)
{
    G_INITIALIZE(self, gst_message_new_async_start(RVAL2GST_OBJ(src),
                                                   RVAL2CBOOL(new_base_time)));
    return Qnil;
}
GstStateChangeReturn
gst_sandboxed_decodebin_change_state (GstElement *element,
                                      GstStateChange state_change)
{
    GError *error = NULL;
    GstSandboxedDecodebinPrivate *priv;
    GstSandboxedDecodebin *self = GST_SANDBOXED_DECODEBIN (element);
    GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

    priv = GST_SANDBOXED_DECODEBIN_GET_PRIVATE (self);

    switch (state_change) {
    case GST_STATE_CHANGE_NULL_TO_READY:
        /* TODO: set up file monitoring */
        /* spawn subprocess */
        priv->subprocess_stdin = start_decoder (priv->shm_audio_socket_path,
                                                priv->shm_video_socket_path,
                                                &error);
        if (priv->subprocess_stdin == -1) {
            GST_WARNING_OBJECT (element,
                                "Could not spawn subprocess: %s", error->message);
            ret = GST_STATE_CHANGE_FAILURE;
        }

        /* set the right fd to fdsink */
        g_object_set (priv->fdsink, "fd", priv->subprocess_stdin, NULL);
        GST_DEBUG_OBJECT (element, "Waiting for shm sockets to be available\n");
        while (!self->priv->subprocess_ready) {
            /* does that count as acceptable code? The alternatives are another
             * thread to monitor file creation or sleep() */
            g_main_context_iteration (NULL, TRUE);
        }
        GST_DEBUG_OBJECT (element, "Done waiting\n");

        break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
        GST_DEBUG_OBJECT (element, "Going to PAUSED");
        break;
#if 0
    case GST_STATE_CHANGE_READY_TO_PAUSED:
        /* TODO: check subprocess is ready with the help of file monitoring, if
         * not, do the change asynchronously */
    {
        GstMessage *message;
        ret = GST_STATE_CHANGE_ASYNC;

        message = gst_message_new_async_start (GST_OBJECT_CAST (element), FALSE);
        parent_class->handle_message (GST_BIN (element), message);

        /* Yeah, this is a hack */
        g_timeout_add (2000, do_async_done, self);
    }

    break;
#endif
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
        GST_DEBUG_OBJECT (element, "Going to PLAYING");
        break;
    default:
        break;
    }
    if (ret != GST_STATE_CHANGE_FAILURE) {
        GstStateChangeReturn bret;
        bret = GST_ELEMENT_CLASS (parent_class)->change_state (element, state_change);
        if (bret == GST_STATE_CHANGE_FAILURE) {
            GST_WARNING_OBJECT (element, "parent change_state failed!");
            ret = bret;
        }
    }

    if (ret != GST_STATE_CHANGE_FAILURE) {
        GstStateChangeReturn fdret;
        gint fd;
        switch (state_change) {
        case GST_STATE_CHANGE_READY_TO_PAUSED:
            GST_DEBUG_OBJECT (element, "Trying to set fdsink to PLAYING");
            fdret = gst_element_set_state (priv->fdsink, GST_STATE_PLAYING);
            GST_DEBUG_OBJECT (element, "Returned: %s",
                              gst_element_state_change_return_get_name (fdret));
            break;
        case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
            g_object_get (priv->audiosrc,
                          "shm-area-name", &priv->audio_shm_area_name, NULL);
            g_object_get (priv->videosrc,
                          "shm-area-name", &priv->video_shm_area_name, NULL);
            GST_DEBUG_OBJECT (element, "Name of audio/video shm areas: "
                              "\"%s\" and \"%s\"\n",
                              priv->audio_shm_area_name,
                              priv->video_shm_area_name);
            break;
        case GST_STATE_CHANGE_READY_TO_NULL:
            /* Closing the fd sounds like a polite thing to do now*/
            g_object_get (priv->fdsink, "fd", &fd, NULL);
            close (fd);

            /* Unlinking the stuff the decoder could not unlink because it doesn't
             * have the necessary privileges */
            GST_DEBUG_OBJECT (element, "Trying to unlink %s and %s",
                              priv->shm_video_socket_path,
                              priv->shm_audio_socket_path);
            if (-1 == g_unlink (priv->shm_video_socket_path))
                GST_WARNING_OBJECT (element, "Could not unlink %s: %m", priv->shm_video_socket_path);
            if (-1 == g_unlink (priv->shm_audio_socket_path))
                GST_WARNING_OBJECT (element, "Could not unlink %s: %m", priv->shm_audio_socket_path);

            GST_DEBUG_OBJECT (element,
                              "Trying to unlink audio/video shm areas: \"%s\" and \"%s\"\n",
                              priv->audio_shm_area_name,
                              priv->video_shm_area_name);
            if (-1 == shm_unlink (priv->audio_shm_area_name))
                GST_WARNING_OBJECT (element, "Could not unlink shm area %s: %m",
                                    priv->audio_shm_area_name);
            if (-1 == shm_unlink (priv->video_shm_area_name))
                GST_WARNING_OBJECT (element, "Could not unlink shm area %s: %m",
                                    priv->video_shm_area_name);
            /* FIXME: where do we free all these strings? */
            break;
        default:
            break;
        }
    }

    return ret;
}