static void
ges_timeline_pipeline_dispose (GObject * object)
{
  GESTimelinePipeline *self = GES_TIMELINE_PIPELINE (object);

  if (self->priv->playsink) {
    if (self->priv->mode & (TIMELINE_MODE_PREVIEW))
      gst_bin_remove (GST_BIN (object), self->priv->playsink);
    else
      gst_object_unref (self->priv->playsink);
    self->priv->playsink = NULL;
  }

  if (self->priv->encodebin) {
    if (self->priv->mode & (TIMELINE_MODE_RENDER | TIMELINE_MODE_SMART_RENDER))
      gst_bin_remove (GST_BIN (object), self->priv->encodebin);
    else
      gst_object_unref (self->priv->encodebin);
    self->priv->encodebin = NULL;
  }

  if (self->priv->profile) {
    gst_encoding_profile_unref (self->priv->profile);
    self->priv->profile = NULL;
  }

  G_OBJECT_CLASS (ges_timeline_pipeline_parent_class)->dispose (object);
}
Пример #2
0
static void
sj_extractor_set_property (GObject *object, guint property_id,
                                       const GValue *value, GParamSpec *pspec)
{
  GstEncodingProfile *profile;
  SjExtractorPrivate *priv = SJ_EXTRACTOR (object)->priv;
  switch (property_id) {
  case PROP_PROFILE:
    if (priv->profile)
      gst_encoding_profile_unref (priv->profile);
    profile = GST_ENCODING_PROFILE (g_value_get_pointer (value));
    priv->profile = GST_ENCODING_PROFILE(gst_encoding_profile_ref (profile));
    priv->rebuild_pipeline = TRUE;
    g_object_notify (object, "profile");
    break;
  case PROP_PARANOIA:
    priv->paranoia_mode = g_value_get_int (value);
    if (priv->cdsrc)
      g_object_set (G_OBJECT (priv->cdsrc),
                    "paranoia-mode", priv->paranoia_mode,
                    NULL);
    break;
  case PROP_DEVICE:
    /* We need to cache this as the source will be recreated */
    g_free (priv->device_path);
    priv->device_path = g_value_dup_string (value);
    if (priv->cdsrc != NULL)
      g_object_set (G_OBJECT (priv->cdsrc),
                    "device", priv->device_path,
                    NULL);
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  }
}
Пример #3
0
static void
print_profile (GUPnPDLNAProfile *profile, gpointer unused)
{
        GstEncodingProfile *enc_profile;
        const GList *tmp;
        gchar *caps_str;

        enc_profile = gupnp_dlna_profile_get_encoding_profile (profile);
        tmp = gst_encoding_container_profile_get_profiles
                                        (GST_ENCODING_CONTAINER_PROFILE (enc_profile));

        g_print ("%s %-30s%-35s",
                 gupnp_dlna_profile_get_extended (profile) ? "*" : " ",
                 gupnp_dlna_profile_get_name (profile),
                 gupnp_dlna_profile_get_mime (profile));

        if (verbose) {
                caps_str = gst_caps_to_string
                        (gst_encoding_profile_get_format (enc_profile));
                g_print ("\n`- container: %s\n", caps_str);
                g_free (caps_str);

                while (tmp) {
                        print_caps (gst_encoding_profile_get_format
                                        (GST_ENCODING_PROFILE (tmp->data)));
                        tmp = tmp->next;
                }
        }

        g_print ("\n");
        gst_encoding_profile_unref (enc_profile);
}
/**
 * ges_timeline_pipeline_set_render_settings:
 * @pipeline: a #GESTimelinePipeline
 * @output_uri: the URI to which the timeline will be rendered
 * @profile: the #GstEncodingProfile to use to render the timeline.
 *
 * Specify where the pipeline shall be rendered and with what settings.
 *
 * A copy of @profile and @output_uri will be done internally, the caller can
 * safely free those values afterwards.
 *
 * This method must be called before setting the pipeline mode to
 * #TIMELINE_MODE_RENDER
 *
 * Returns: %TRUE if the settings were aknowledged properly, else %FALSE
 */
gboolean
ges_timeline_pipeline_set_render_settings (GESTimelinePipeline * pipeline,
    gchar * output_uri, GstEncodingProfile * profile)
{
  /* Clear previous URI sink if it existed */
  /* FIXME : We should figure out if it was added to the pipeline,
   * and if so, remove it. */
  if (pipeline->priv->urisink) {
    g_object_unref (pipeline->priv->urisink);
    pipeline->priv->urisink = NULL;
  }

  pipeline->priv->urisink =
      gst_element_make_from_uri (GST_URI_SINK, output_uri, "urisink");
  if (G_UNLIKELY (pipeline->priv->urisink == NULL)) {
    GST_ERROR_OBJECT (pipeline, "Couldn't not create sink for URI %s",
        output_uri);
    return FALSE;
  }

  if (pipeline->priv->profile)
    gst_encoding_profile_unref (pipeline->priv->profile);
  g_object_set (pipeline->priv->encodebin, "avoid-reencoding",
      !(!(pipeline->priv->mode & TIMELINE_MODE_SMART_RENDER)), NULL);
  g_object_set (pipeline->priv->encodebin, "profile", profile, NULL);
  pipeline->priv->profile =
      (GstEncodingProfile *) gst_encoding_profile_ref (profile);

  return TRUE;
}
void
on_formatComboBox_changed (GtkWidget * widget, gpointer data)
{
  GstEncodingProfile *profile = NULL;
  gint index = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));

  if (formats[index].create_profile) {
    profile = formats[index].create_profile ();
  }

  g_return_if_fail (profile != NULL);
  gst_element_set_state (camera, GST_STATE_NULL);
  g_object_set (camera, "video-profile", profile, NULL);
  gst_encoding_profile_unref (profile);

  if (GST_STATE_CHANGE_FAILURE == gst_element_set_state (camera,
          GST_STATE_PLAYING)) {
    GtkWidget *dialog =
        gtk_message_dialog_new (GTK_WINDOW (ui_main_window), GTK_DIALOG_MODAL,
        GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
        "Could not initialize camerabin with the "
        "selected format. Your system might not have the required plugins installed.\n"
        "Please select another format.");

    gtk_dialog_run (GTK_DIALOG (dialog));

    gtk_widget_destroy (dialog);
  }
}
bool QDeclarativeVideoEditor::render()
{
    //sanity check
    if (m_size < 1) {
        emit error(NO_MEDIA, "No media added to the timeline");
        return false;
    }

    qDebug() << "Render preparations started";

    QString output_uri = "file:///home/user/MyDocs/Movies/" + getDateTimeString() + ".mp4";

    GstEncodingProfile *profile = createEncodingProfile();
    if (!ges_timeline_pipeline_set_render_settings (m_pipeline, output_uri.toUtf8().data(), profile)) {
        emit error(RENDERING_FAILED, "Failed setting rendering options");
        gst_encoding_profile_unref(profile);
        return false;
    }
    gst_encoding_profile_unref (profile);

    if (!ges_timeline_pipeline_set_mode (m_pipeline, TIMELINE_MODE_RENDER)) {
        emit error(RENDERING_FAILED, "Failed to set rendering mode");
        gst_encoding_profile_unref(profile);
        return false;
    }

    qDebug() << "Rendering to " << output_uri;

    // reset duration and progress
    setDuration(GST_CLOCK_TIME_NONE);
    setProgress(0.0);
    qDebug() << "Starting progress polling";

    m_positionTimer.start(500);
    //g_timeout_add (500, updateProgress, this);

    m_rendering = true;
    if(!gst_element_set_state (GST_ELEMENT (m_pipeline), GST_STATE_PLAYING)) {
        gst_element_set_state (GST_ELEMENT (m_pipeline), GST_STATE_NULL);

        m_rendering = false;
        emit error(RENDERING_FAILED, "Failed to set pipeline to playing state");
        return false;
    }
    return true;
}
Пример #7
0
static void
kms_muxing_pipeline_configure (KmsMuxingPipeline * self)
{
  GstEncodingContainerProfile *cprof;
  const GList *profiles, *l;
  GstElement *appsrc;

  cprof =
      kms_recording_profile_create_profile (self->priv->profile, TRUE, TRUE);

  profiles = gst_encoding_container_profile_get_profiles (cprof);

  for (l = profiles; l != NULL; l = l->next) {
    GstEncodingProfile *prof = l->data;
    GstCaps *caps;

    if (GST_IS_ENCODING_AUDIO_PROFILE (prof)) {
      appsrc = self->priv->audiosrc;
    } else if (GST_IS_ENCODING_VIDEO_PROFILE (prof)) {
      appsrc = self->priv->videosrc;
    } else
      continue;

    caps = gst_encoding_profile_get_input_caps (prof);

    g_object_set (G_OBJECT (appsrc), "is-live", TRUE, "do-timestamp", FALSE,
        "min-latency", G_GUINT64_CONSTANT (0), "max-latency",
        G_GUINT64_CONSTANT (0), "format", GST_FORMAT_TIME, NULL);

    gst_caps_unref (caps);
  }

  g_object_set (G_OBJECT (self->priv->encodebin), "profile", cprof,
      "audio-jitter-tolerance", 100 * GST_MSECOND,
      "avoid-reencoding", TRUE, NULL);
  gst_encoding_profile_unref (cprof);

  if (self->priv->profile == KMS_RECORDING_PROFILE_MP4) {
    GstElement *mux =
        gst_bin_get_by_name (GST_BIN (self->priv->encodebin), "muxer");

    g_object_set (G_OBJECT (mux), "fragment-duration", 2000, "streamable", TRUE,
        NULL);

    g_object_unref (mux);
  } else if (self->priv->profile == KMS_RECORDING_PROFILE_WEBM) {
    GstElement *mux =
        gst_bin_get_by_name (GST_BIN (self->priv->encodebin), "muxer");

    g_object_set (G_OBJECT (mux), "streamable", TRUE, NULL);

    g_object_unref (mux);
  }
}
Пример #8
0
/**
 * ges_pipeline_set_render_settings:
 * @pipeline: a #GESPipeline
 * @output_uri: the URI to which the timeline will be rendered
 * @profile: the #GstEncodingProfile to use to render the timeline.
 *
 * Specify where the pipeline shall be rendered and with what settings.
 *
 * A copy of @profile and @output_uri will be done internally, the caller can
 * safely free those values afterwards.
 *
 * This method must be called before setting the pipeline mode to
 * #TIMELINE_MODE_RENDER
 *
 * Returns: %TRUE if the settings were aknowledged properly, else %FALSE
 */
gboolean
ges_pipeline_set_render_settings (GESPipeline * pipeline,
    const gchar * output_uri, GstEncodingProfile * profile)
{
  GError *err = NULL;
  GstEncodingProfile *set_profile;

  g_return_val_if_fail (GES_IS_PIPELINE (pipeline), FALSE);

  /* Clear previous URI sink if it existed */
  /* FIXME : We should figure out if it was added to the pipeline,
   * and if so, remove it. */
  if (pipeline->priv->urisink) {
    gst_object_unref (pipeline->priv->urisink);
    pipeline->priv->urisink = NULL;
  }

  pipeline->priv->urisink =
      gst_element_make_from_uri (GST_URI_SINK, output_uri, "urisink", &err);
  if (G_UNLIKELY (pipeline->priv->urisink == NULL)) {
    GST_ERROR_OBJECT (pipeline, "Couldn't not create sink for URI %s: '%s'",
        output_uri, ((err
                && err->message) ? err->message : "failed to create element"));
    g_clear_error (&err);
    return FALSE;
  }

  if (pipeline->priv->profile)
    gst_encoding_profile_unref (pipeline->priv->profile);
  g_object_set (pipeline->priv->encodebin, "avoid-reencoding",
      !(!(pipeline->priv->mode & TIMELINE_MODE_SMART_RENDER)), NULL);
  g_object_set (pipeline->priv->encodebin, "profile", profile, NULL);
  g_object_get (pipeline->priv->encodebin, "profile", &set_profile, NULL);

  if (set_profile == NULL) {
    GST_ERROR_OBJECT (pipeline, "Profile %" GST_PTR_FORMAT " could no be set",
        profile);

    return FALSE;
  }

  /* We got a referencer when getting back the profile */
  pipeline->priv->profile = profile;

  return TRUE;
}
Пример #9
0
static void
sj_extractor_dispose (GObject *object)
{
  SjExtractorPrivate *priv = SJ_EXTRACTOR (object)->priv;

  if (priv->profile) {
    gst_encoding_profile_unref (priv->profile);
    priv->profile = NULL;
  }

  if (priv->pipeline) {
    gst_element_set_state (priv->pipeline, GST_STATE_NULL);
    g_object_unref (priv->pipeline);
    priv->pipeline = NULL;
  }

  G_OBJECT_CLASS (sj_extractor_parent_class)->dispose (object);
}
Пример #10
0
static GstCaps *
kms_recorder_endpoint_get_caps_from_profile (KmsRecorderEndpoint * self,
    KmsElementPadType type)
{
  GstEncodingContainerProfile *cprof;
  const GList *profiles, *l;
  GstCaps *caps = NULL;

  switch (type) {
    case KMS_ELEMENT_PAD_TYPE_VIDEO:
      cprof =
          kms_recording_profile_create_profile (self->priv->profile, FALSE,
          TRUE);
      break;
    case KMS_ELEMENT_PAD_TYPE_AUDIO:
      cprof =
          kms_recording_profile_create_profile (self->priv->profile, TRUE,
          FALSE);
      break;
    default:
      return NULL;
  }

  profiles = gst_encoding_container_profile_get_profiles (cprof);

  for (l = profiles; l != NULL; l = l->next) {
    GstEncodingProfile *prof = l->data;

    if ((GST_IS_ENCODING_AUDIO_PROFILE (prof) &&
            type == KMS_ELEMENT_PAD_TYPE_AUDIO) ||
        (GST_IS_ENCODING_VIDEO_PROFILE (prof) &&
            type == KMS_ELEMENT_PAD_TYPE_VIDEO)) {
      caps = gst_encoding_profile_get_input_caps (prof);
      break;
    }
  }

  gst_encoding_profile_unref (cprof);
  return caps;
}
Пример #11
0
static void
ges_pipeline_dispose (GObject * object)
{
  GESPipeline *self = GES_PIPELINE (object);

  if (self->priv->playsink) {
    if (self->priv->mode & (GES_PIPELINE_MODE_PREVIEW))
      gst_bin_remove (GST_BIN (object), self->priv->playsink);
    else
      gst_object_unref (self->priv->playsink);
    self->priv->playsink = NULL;
  }

  if (self->priv->encodebin) {
    if (self->priv->mode & (GES_PIPELINE_MODE_RENDER |
            GES_PIPELINE_MODE_SMART_RENDER))
      gst_bin_remove (GST_BIN (object), self->priv->encodebin);
    else
      gst_object_unref (self->priv->encodebin);
    self->priv->encodebin = NULL;
  }

  if (self->priv->profile) {
    gst_encoding_profile_unref (self->priv->profile);
    self->priv->profile = NULL;
  }

  if (self->priv->timeline) {
    g_signal_handlers_disconnect_by_func (self->priv->timeline,
        _timeline_track_added_cb, self);
    g_signal_handlers_disconnect_by_func (self->priv->timeline,
        _timeline_track_removed_cb, self);
  }

  G_OBJECT_CLASS (ges_pipeline_parent_class)->dispose (object);
}
Пример #12
0
static void pattern_label_update (void)
{
  char *file_pattern, *path_pattern;
  char *file_value, *path_value, *example, *format;
  char *media_type;
  GstEncodingProfile *profile;

  /* Disable -Wdiscarded-quantifiers to prevent warnings as we're
     initalizing gchar* from const gchar*. This is safe as the strings
     are never changed. */
SJ_BEGIN_IGNORE_DISCARDED_QUANTIFIERS
  static const AlbumDetails sample_album = {
    .title = "Help!", /* title */
    .artist = "The Beatles", /* artist */
    .artist_sortname = "Beatles, The", /* artist_sortname */
    .genre = NULL, /* genre */
    .number = 0, /* number of tracks*/
    .disc_number = 1, /* disc number */
    .tracks = NULL, /* track list */
    .release_date = NULL, /* release date */
    .album_id = NULL, /* album ID */
    .artist_id = NULL /* artist ID */
  };
  static const TrackDetails sample_track = {
    .album = (AlbumDetails*)&sample_album,  /*album */
    .number = 7, /* track number */
    .title = "Ticket To Ride", /* title */
    .artist = "The Beatles", /* artist */
    .artist_sortname = "Beatles, The", /* artist_sortname */
    .composer = "John Lennon and Paul McCartney", /* composer */
    .composer_sortname = "Lennon, John", /* composer_sortname */
    .duration = 0, /* duration */
    .track_id = NULL, /* track ID */
    .artist_id = NULL, /* artist ID */
  };
SJ_END_IGNORE_DISCARDED_QUANTIFIERS

  g_object_get (sj_extractor, "profile", &profile, NULL);
  /* It's possible the profile isn't set, in which case do nothing */
  if (!profile) {
    return;
  }
  media_type = rb_gst_encoding_profile_get_media_type (profile);
  gst_encoding_profile_unref (profile);

  /* TODO: sucky. Replace with get-gconf-key-with-default mojo */
  file_pattern = g_settings_get_string (sj_settings, SJ_SETTINGS_FILE_PATTERN);
  if (file_pattern == NULL) {
    file_pattern = g_strdup (sj_get_default_file_pattern ());
  }
  path_pattern = g_settings_get_string (sj_settings, SJ_SETTINGS_PATH_PATTERN);
  if (path_pattern == NULL) {
    path_pattern = g_strdup (sj_get_default_path_pattern ());
  }

  file_value = filepath_parse_pattern (file_pattern, &sample_track);
  path_value = filepath_parse_pattern (path_pattern, &sample_track);

  example = g_build_filename (G_DIR_SEPARATOR_S, path_value, file_value, NULL);
  g_free (file_value);
  g_free (file_pattern);
  g_free (path_value);
  g_free (path_pattern);

  format = g_strconcat ("<small><i><b>",
                        _("Example Path: "),
                        "</b>",
                        example,
                        ".",
                        rb_gst_media_type_to_extension (media_type),
                        "</i></small>", NULL);
  g_free (example);
  g_free (media_type);

  gtk_label_set_markup (GTK_LABEL (path_example_label), format);
  g_free (format);
}

static void settings_changed_cb (GSettings *settings, const gchar *key, gpointer combo)
{
  char *value;

  value = g_settings_get_string (settings, key);
  if (!gtk_combo_box_set_active_id (combo, value))
    gtk_combo_box_set_active_id (combo, NULL);

  g_free (value);
  pattern_label_update ();
}

/**
 * Default device changed (either GSettings key or the widget)
 */
static void device_changed_cb (GSettings *settings, const gchar *key, gpointer user_data)
{
  BraseroDrive *drive;
  BraseroMediumMonitor *monitor;
  char *value;

  g_return_if_fail (strcmp (key, SJ_SETTINGS_DEVICE) == 0);

  value = g_settings_get_string (settings, key);
  if ((value != NULL) && (*value != '\0')) {
    monitor = brasero_medium_monitor_get_default ();
    drive = brasero_medium_monitor_get_drive (monitor, value);
    brasero_drive_selection_set_active (BRASERO_DRIVE_SELECTION (cd_option), drive);
    g_object_unref (drive);
    g_object_unref (monitor);
  } else {
    /* FIXME: see the FIXME in sj-main.c around one of the
     * device_changed_cb calls for a way to fix this
     */
    g_warn_if_reached();
  }
  g_free (value);
}
Пример #13
0
static void
test_individual_target (GstEncodingTarget * target)
{
  GstEncodingProfile *prof;
  GstCaps *tmpcaps, *tmpcaps2;
  GstEncodingProfile *sprof1, *sprof2;

  GST_DEBUG ("Checking the target properties");
  /* Check the target  */
  fail_unless_equals_string (gst_encoding_target_get_name (target),
      "myponytarget");
  fail_unless_equals_string (gst_encoding_target_get_category (target),
      "herding");
  fail_unless_equals_string (gst_encoding_target_get_description (target),
      "Plenty of pony glitter profiles");

  GST_DEBUG ("Checking the number of profiles the target contains");
  fail_unless_equals_int (g_list_length ((GList *)
          gst_encoding_target_get_profiles (target)), 1);


  GST_DEBUG ("Checking the container profile");
  /* Check the profile */
  prof = (GstEncodingProfile *) gst_encoding_target_get_profiles (target)->data;
  tmpcaps = gst_caps_from_string ("animal/x-pony");
  CHECK_PROFILE (prof, "pony", "I don't want a description !", tmpcaps, NULL, 0,
      0);
  gst_caps_unref (tmpcaps);

  GST_DEBUG ("Checking the container profile has 2 stream profiles");
  /* Check the stream profiles */
  fail_unless_equals_int (g_list_length ((GList *)
          gst_encoding_container_profile_get_profiles (
              (GstEncodingContainerProfile *) prof)), 2);

  GST_DEBUG ("Checking the container profile has the audio/x-pony-song stream");
  tmpcaps = gst_caps_from_string ("audio/x-pony-song,pretty=True");
  tmpcaps2 = gst_caps_from_string ("audio/x-raw-int,channels=1,rate=44100");
  sprof1 =
      (GstEncodingProfile *) gst_encoding_audio_profile_new (tmpcaps, NULL,
      tmpcaps2, 1);
  fail_unless (gst_encoding_container_profile_contains_profile (
          (GstEncodingContainerProfile *) prof, sprof1));
  gst_encoding_profile_unref (sprof1);
  gst_caps_unref (tmpcaps);
  gst_caps_unref (tmpcaps2);

  GST_DEBUG ("Checking the container profile has the video//x-glitter stream");
  tmpcaps = gst_caps_from_string ("video/x-glitter,sparkling=True");
  tmpcaps2 =
      gst_caps_from_string
      ("video/x-raw-yuv,width=640,height=480,framerate=15/1");
  sprof2 = (GstEncodingProfile *)
      gst_encoding_video_profile_new (tmpcaps, "seriously glittery", tmpcaps2,
      0);
  gst_encoding_video_profile_set_variableframerate ((GstEncodingVideoProfile *)
      sprof2, TRUE);
  fail_unless (gst_encoding_container_profile_contains_profile (
          (GstEncodingContainerProfile *) prof, sprof2));
  gst_encoding_profile_unref (sprof2);
  gst_caps_unref (tmpcaps);
  gst_caps_unref (tmpcaps2);
}
static void
set_profile (GstElement * ebin, GstEncodingProfile * prof)
{
  g_object_set (ebin, "profile", prof, NULL);
  gst_encoding_profile_unref (prof);
}
Пример #15
0
int
main (int argc, char **argv)
{
    GError *err = NULL;
    gchar *outputuri = NULL;
    gchar *format = NULL;
    gchar *aformat = NULL;
    gchar *vformat = NULL;
    gboolean allmissing = FALSE;
    gboolean listcodecs = FALSE;
    GOptionEntry options[] = {
        {   "silent", 's', 0, G_OPTION_ARG_NONE, &silent,
            "Don't output the information structure", NULL
        },
        {   "outputuri", 'o', 0, G_OPTION_ARG_STRING, &outputuri,
            "URI to encode to", "URI (<protocol>://<location>)"
        },
        {   "format", 'f', 0, G_OPTION_ARG_STRING, &format,
            "Container format", "<GstCaps>"
        },
        {   "vformat", 'v', 0, G_OPTION_ARG_STRING, &vformat,
            "Video format", "<GstCaps>"
        },
        {   "aformat", 'a', 0, G_OPTION_ARG_STRING, &aformat,
            "Audio format", "<GstCaps>"
        },
        {   "allmissing", 'm', 0, G_OPTION_ARG_NONE, &allmissing,
            "encode to all matching format/codec that aren't specified", NULL
        },
        {   "list-codecs", 'l', 0, G_OPTION_ARG_NONE, &listcodecs,
            "list all available codecs and container formats", NULL
        },
        {NULL}
    };
    GOptionContext *ctx;
    GstEncodingProfile *prof;
    gchar *inputuri;

    ctx = g_option_context_new ("- encode URIs with GstProfile and encodebin");
    g_option_context_add_main_entries (ctx, options, NULL);
    g_option_context_add_group (ctx, gst_init_get_option_group ());

    if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
        g_print ("Error initializing: %s\n", err->message);
        exit (1);
    }

    if (listcodecs) {
        list_codecs ();
        g_option_context_free (ctx);
        exit (0);
    }

    if (outputuri == NULL || argc != 2) {
        g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL));
        g_option_context_free (ctx);
        exit (-1);
    }

    g_option_context_free (ctx);

    /* Fixup outputuri to be a URI */
    inputuri = ensure_uri (argv[1]);
    outputuri = ensure_uri (outputuri);

    if (allmissing) {
        GList *muxers;
        GstCaps *formats = NULL;
        GstCaps *vformats = NULL;
        GstCaps *aformats = NULL;
        guint f, v, a, flen, vlen, alen;

        if (!format)
            formats = gst_caps_list_container_formats (GST_RANK_NONE);
        else
            formats = gst_caps_from_string (format);

        if (!vformat)
            vformats = gst_caps_list_video_encoding_formats (GST_RANK_NONE);
        else
            vformats = gst_caps_from_string (vformat);

        if (!aformat)
            aformats = gst_caps_list_audio_encoding_formats (GST_RANK_NONE);
        else
            aformats = gst_caps_from_string (aformat);
        muxers =
            gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER,
                    GST_RANK_NONE);

        flen = gst_caps_get_size (formats);

        for (f = 0; f < flen; f++) {
            GstCaps *container =
                gst_caps_new_full (gst_caps_steal_structure (formats, 0), NULL);
            GstCaps *compatv =
                gst_caps_list_compatible_codecs (container, vformats, muxers);
            GstCaps *compata =
                gst_caps_list_compatible_codecs (container, aformats, muxers);

            vlen = gst_caps_get_size (compatv);
            alen = gst_caps_get_size (compata);


            for (v = 0; v < vlen; v++) {
                GstCaps *vcodec =
                    gst_caps_new_full (gst_structure_copy (gst_caps_get_structure
                                       (compatv, v)), NULL);
                for (a = 0; a < alen; a++) {
                    GstCaps *acodec =
                        gst_caps_new_full (gst_structure_copy (gst_caps_get_structure
                                           (compata, a)), NULL);

                    prof =
                        create_profile ((GstCaps *) container, (GstCaps *) vcodec,
                                        (GstCaps *) acodec);
                    if (G_UNLIKELY (prof == NULL)) {
                        g_print ("Wrong arguments\n");
                        break;
                    }
                    outputuri =
                        ensure_uri (generate_filename (container, vcodec, acodec));
                    transcode_file (inputuri, outputuri, prof);
                    gst_encoding_profile_unref (prof);

                    gst_caps_unref (acodec);
                }
                gst_caps_unref (vcodec);
            }
            gst_caps_unref (container);
        }

    } else {

        /* Create the profile */
        prof = create_profile_from_string (format, vformat, aformat);
        if (G_UNLIKELY (prof == NULL)) {
            g_print ("Encoding arguments are not valid !\n");
            return 1;
        }

        /* Transcode file */
        transcode_file (inputuri, outputuri, prof);

        /* cleanup */
        gst_encoding_profile_unref (prof);

    }
    return 0;
}
Пример #16
0
int
main (int argc, gchar ** argv)
{
  GError *err = NULL;
  gchar *outputuri = NULL;
  gchar *container = (gchar *) "application/ogg";
  gchar *audio = (gchar *) "audio/x-vorbis";
  gchar *video = (gchar *) "video/x-theora";
  gchar *video_restriction = (gchar *) "ANY";
  gchar *audio_preset = NULL;
  gchar *video_preset = NULL;
  gchar *exclude_args = NULL;
  static gboolean render = FALSE;
  static gboolean smartrender = FALSE;
  static gboolean list_transitions = FALSE;
  static gboolean list_patterns = FALSE;
  static gdouble thumbinterval = 0;
  static gboolean verbose = FALSE;
  gchar *save_path = NULL;
  gchar *load_path = NULL;
  gchar *project_path = NULL;
  GOptionEntry options[] = {
    {"thumbnail", 'm', 0.0, G_OPTION_ARG_DOUBLE, &thumbinterval,
        "Take thumbnails every n seconds (saved in current directory)", "N"},
    {"render", 'r', 0, G_OPTION_ARG_NONE, &render,
        "Render to outputuri", NULL},
    {"smartrender", 's', 0, G_OPTION_ARG_NONE, &smartrender,
        "Render to outputuri, and avoid decoding/reencoding", NULL},
    {"outputuri", 'o', 0, G_OPTION_ARG_STRING, &outputuri,
        "URI to encode to", "URI (<protocol>://<location>)"},
    {"format", 'f', 0, G_OPTION_ARG_STRING, &container,
        "Container format", "<GstCaps>"},
    {"vformat", 'v', 0, G_OPTION_ARG_STRING, &video,
        "Video format", "<GstCaps>"},
    {"aformat", 'a', 0, G_OPTION_ARG_STRING, &audio,
        "Audio format", "<GstCaps>"},
    {"vrestriction", 'x', 0, G_OPTION_ARG_STRING, &video_restriction,
        "Video restriction", "<GstCaps>"},
    {"apreset", 0, 0, G_OPTION_ARG_STRING, &audio_preset,
        "Encoding audio profile preset", "<GstPresetName>"},
    {"vpreset", 0, 0, G_OPTION_ARG_STRING, &video_preset,
        "Encoding video profile preset", "<GstPresetName>"},
    {"repeat", 'l', 0, G_OPTION_ARG_INT, &repeat,
        "Number of time to repeat timeline", NULL},
    {"list-transitions", 't', 0, G_OPTION_ARG_NONE, &list_transitions,
        "List valid transition types and exit", NULL},
    {"list-patterns", 'p', 0, G_OPTION_ARG_NONE, &list_patterns,
        "List patterns and exit", NULL},
    {"save", 'z', 0, G_OPTION_ARG_STRING, &save_path,
        "Save project to file before rendering", "<path>"},
    {"load", 'q', 0, G_OPTION_ARG_STRING, &load_path,
        "Load project from file before rendering", "<path>"},
    {"verbose", 0, 0, G_OPTION_ARG_NONE, &verbose,
        "Output status information and property notifications", NULL},
    {"exclude", 'X', 0, G_OPTION_ARG_NONE, &exclude_args,
        "Do not output status information of TYPE", "TYPE1,TYPE2,..."},
    {"load-xptv", 'y', 0, G_OPTION_ARG_STRING, &project_path,
        "Load xptv project from file for previewing", "<path>"},
    {NULL}
  };
  GOptionContext *ctx;
  GMainLoop *mainloop;
  GstBus *bus;

  ctx = g_option_context_new ("- plays or renders a timeline.");
  g_option_context_set_summary (ctx,
      "ges-launch renders a timeline, which can be specified on the commandline,\n"
      "or loaded from a file using the -q option.\n\n"
      "A timeline is a list of files, patterns, and transitions to be rendered\n"
      "one after the other. Files and Patterns provide video and audio as the\n"
      "primary input, and transitions animate between the end of one file/pattern\n"
      "and the beginning of a new one. Hence, transitions can only be listed\n"
      "in between patterns or files.\n\n"
      "A file is a triplet of filename, inpoint (in seconds) and\n"
      "duration (in seconds). If the duration is 0, the full file length is used.\n\n"
      "Patterns and transitions are triplets that begin with either \"+pattern\"\n"
      "or \"+transition\", followed by a <type> and duration (in seconds, must be\n"
      "greater than 0)\n\n"
      "Durations in all cases can be fractions of a second.\n\n"
      "Example:\n"
      "ges-launch file1.avi 0 45 +transition crossfade 3.5 file2.avi 0 0");
  g_option_context_add_main_entries (ctx, options, NULL);
  g_option_context_add_group (ctx, gst_init_get_option_group ());

  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
    g_printerr ("Error initializing: %s\n", err->message);
    g_option_context_free (ctx);
    exit (1);
  }

  /* Initialize the GStreamer Editing Services */
  if (!ges_init ()) {
    g_printerr ("Error initializing GES\n");
    exit (1);
  }

  if (list_transitions) {
    print_transition_list ();
    exit (0);
  }

  if (list_patterns) {
    print_pattern_list ();
    exit (0);
  }

  if (project_path) {
    load_project (project_path);
    exit (0);
  }
  if (((!load_path && (argc < 4))) || (outputuri && (!render && !smartrender))) {
    g_printf ("%s", g_option_context_get_help (ctx, TRUE, NULL));
    g_option_context_free (ctx);
    exit (1);
  }

  g_option_context_free (ctx);

  /* normalize */
  if (strcmp (audio, "none") == 0)
    audio = NULL;
  if (strcmp (video, "none") == 0)
    video = NULL;

  /* Create the pipeline */
  pipeline = create_pipeline (load_path, save_path, argc - 1, argv + 1,
      audio, video);
  if (!pipeline)
    exit (1);

  /* Setup profile/encoding if needed */
  if (render || smartrender) {
    GstEncodingProfile *prof;

    prof = make_encoding_profile (audio, video, video_restriction, audio_preset,
        video_preset, container);

    if (!prof ||
        !ges_timeline_pipeline_set_render_settings (pipeline, outputuri, prof)
        || !ges_timeline_pipeline_set_mode (pipeline,
            smartrender ? TIMELINE_MODE_SMART_RENDER : TIMELINE_MODE_RENDER))
      exit (1);

    g_free (outputuri);
    gst_encoding_profile_unref (prof);
  } else {
    ges_timeline_pipeline_set_mode (pipeline, TIMELINE_MODE_PREVIEW);
  }

  if (verbose) {
    gchar **exclude_list =
        exclude_args ? g_strsplit (exclude_args, ",", 0) : NULL;
    g_signal_connect (pipeline, "deep-notify",
        G_CALLBACK (gst_object_default_deep_notify), exclude_list);
  }

  /* Play the pipeline */
  mainloop = g_main_loop_new (NULL, FALSE);

  if (thumbinterval != 0.0) {
    g_printf ("thumbnailing every %f seconds\n", thumbinterval);
    g_timeout_add (1000 * thumbinterval, thumbnail_cb, pipeline);
  }

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_signal_watch (bus);
  g_signal_connect (bus, "message", G_CALLBACK (bus_message_cb), mainloop);

  if (gst_element_set_state (GST_ELEMENT (pipeline),
          GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
    g_error ("Failed to start the encoding\n");
    return 1;
  }
  g_main_loop_run (mainloop);

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);

  gst_object_unref (pipeline);

  return (int) seenerrors;
}
Пример #17
0
/**
 * ges_pipeline_set_render_settings:
 * @pipeline: a #GESPipeline
 * @output_uri: the URI to which the timeline will be rendered
 * @profile: the #GstEncodingProfile to use to render the timeline.
 *
 * Specify where the pipeline shall be rendered and with what settings.
 *
 * A copy of @profile and @output_uri will be done internally, the caller can
 * safely free those values afterwards.
 *
 * This method must be called before setting the pipeline mode to
 * #GES_PIPELINE_MODE_RENDER
 *
 * Returns: %TRUE if the settings were aknowledged properly, else %FALSE
 */
gboolean
ges_pipeline_set_render_settings (GESPipeline * pipeline,
    const gchar * output_uri, GstEncodingProfile * profile)
{
  GError *err = NULL;
  GstEncodingProfile *set_profile;

  g_return_val_if_fail (GES_IS_PIPELINE (pipeline), FALSE);

  /*  FIXME Properly handle multi track, for now GESPipeline
   *  only hanles single track per type, so we should just set the
   *  presence to 1.
   */
  if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) {
    const GList *tmpprofiles =
        gst_encoding_container_profile_get_profiles
        (GST_ENCODING_CONTAINER_PROFILE (profile));
    GList *tmptrack, *tracks =
        ges_timeline_get_tracks (pipeline->priv->timeline);

    for (; tmpprofiles; tmpprofiles = tmpprofiles->next) {
      for (tmptrack = tracks; tmptrack; tmptrack = tmptrack->next) {
        if ((GST_IS_ENCODING_AUDIO_PROFILE (tmpprofiles->data) &&
                GES_IS_AUDIO_TRACK (tmptrack->data)) ||
            (GST_IS_ENCODING_VIDEO_PROFILE (tmpprofiles->data) &&
                GES_IS_VIDEO_TRACK (tmptrack->data))) {
          GST_DEBUG_OBJECT (pipeline, "Setting presence to 1!");
          gst_encoding_profile_set_presence (tmpprofiles->data, 1);
          gst_encoding_profile_set_allow_dynamic_output (tmpprofiles->data,
              FALSE);
        }
      }
    }

    g_list_free_full (tracks, gst_object_unref);
  }

  /* Clear previous URI sink if it existed */
  /* FIXME : We should figure out if it was added to the pipeline,
   * and if so, remove it. */
  if (pipeline->priv->urisink) {
    gst_object_unref (pipeline->priv->urisink);
    pipeline->priv->urisink = NULL;
  }

  pipeline->priv->urisink =
      gst_element_make_from_uri (GST_URI_SINK, output_uri, "urisink", &err);
  if (G_UNLIKELY (pipeline->priv->urisink == NULL)) {
    GST_ERROR_OBJECT (pipeline, "Couldn't not create sink for URI %s: '%s'",
        output_uri, ((err
                && err->message) ? err->message : "failed to create element"));
    g_clear_error (&err);
    return FALSE;
  }

  if (pipeline->priv->profile)
    gst_encoding_profile_unref (pipeline->priv->profile);
  g_object_set (pipeline->priv->encodebin, "avoid-reencoding",
      !(!(pipeline->priv->mode & GES_PIPELINE_MODE_SMART_RENDER)), NULL);
  g_object_set (pipeline->priv->encodebin, "profile", profile, NULL);
  g_object_get (pipeline->priv->encodebin, "profile", &set_profile, NULL);

  if (set_profile == NULL) {
    GST_ERROR_OBJECT (pipeline, "Profile %" GST_PTR_FORMAT " could no be set",
        profile);

    return FALSE;
  }

  /* We got a referencer when getting back the profile */
  pipeline->priv->profile = profile;

  return TRUE;
}