Beispiel #1
0
static void populate_profile_combo (GtkComboBox *combo)
{
  GstEncodingTarget *target;
  const GList *p;
  GtkTreeModel *model;

  model = GTK_TREE_MODEL (gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_STRING));

  target = rb_gst_get_default_encoding_target ();
  for (p = gst_encoding_target_get_profiles (target); p != NULL; p = p->next) {
    GstEncodingProfile *profile = GST_ENCODING_PROFILE (p->data);
    char *media_type;

    media_type = rb_gst_encoding_profile_get_media_type (profile);
    if (media_type == NULL) {
      continue;
    }
    gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
                                       NULL, NULL, -1,
                                       0, media_type,
                                       1, gst_encoding_profile_get_description (profile),
                                       -1);
    g_free (media_type);
  }

  gtk_combo_box_set_model (GTK_COMBO_BOX (combo), model);
  g_object_unref (model);
}
/**
 * rb_transfer_target_get_format_descriptions:
 * @target: an #RBTransferTarget
 *
 * Returns a #GList of allocated media format descriptions for
 * the formats supported by the target.  The list and the strings
 * it holds must be freed by the caller.
 *
 * Return value: (element-type utf8) (transfer full): list of descriptions.
 */
GList *
rb_transfer_target_get_format_descriptions (RBTransferTarget *target)
{
	GstEncodingTarget *enctarget;
	const GList *l;
	GList *desc = NULL;
	g_object_get (target, "encoding-target", &enctarget, NULL);
	if (enctarget != NULL) {
		for (l = gst_encoding_target_get_profiles (enctarget); l != NULL; l = l->next) {
			GstEncodingProfile *profile = l->data;
			desc = g_list_append (desc, g_strdup (gst_encoding_profile_get_description (profile)));
		}
		gst_encoding_target_unref (enctarget);
	}
	return desc;
}
Beispiel #3
0
GstEncodingProfile *get_encoding_profile(const char *media_type)
{
	const GList *l;
	GstEncodingTarget *target;
	target = get_default_encoding_target();

	for(l = gst_encoding_target_get_profiles(target); l != NULL; l = l->next) {
		GstEncodingProfile *profile = l->data;
		if (media_type_matches_profile(profile, media_type)) {
			gst_encoding_profile_ref(profile);
			return profile;
		}
	}

	return NULL;
}
/**
 * rb_track_transfer_batch_check_profiles:
 * @batch: a #RBTrackTransferBatch
 * @missing_plugin_profiles: (out) (element-type GstPbutils.EncodingProfile): holds a #GList of #GstEncodingProfiles on return
 * @error_count: holds the number of entries that cannot be transferred on return
 *
 * Checks that all entries in the batch can be transferred in a format
 * supported by the destination.  If no encoding profile is available for
 * some entries, but installing additional plugins could make a profile
 * available, a list of profiles that require additional plugins is returned.
 *
 * Return value: %TRUE if some entries can be transferred without additional plugins
 */
gboolean
rb_track_transfer_batch_check_profiles (RBTrackTransferBatch *batch, GList **missing_plugin_profiles, int *error_count)
{
	RBEncoder *encoder = rb_encoder_new ();
	gboolean ret = FALSE;
	const GList *l;

	rb_debug ("checking profiles");

	/* first, figure out which profiles that we care about would require additional plugins to use */
	g_list_free (batch->priv->missing_plugin_profiles);
	batch->priv->missing_plugin_profiles = NULL;

	for (l = gst_encoding_target_get_profiles (batch->priv->target); l != NULL; l = l->next) {
		GstEncodingProfile *profile = GST_ENCODING_PROFILE (l->data);
		char *profile_media_type;
		profile_media_type = rb_gst_encoding_profile_get_media_type (profile);
		if (profile_media_type != NULL &&
		    (rb_gst_media_type_is_lossless (profile_media_type) == FALSE) &&
		    rb_encoder_get_missing_plugins (encoder, profile, NULL, NULL)) {
			batch->priv->missing_plugin_profiles = g_list_append (batch->priv->missing_plugin_profiles, profile);
		}
		g_free (profile_media_type);
	}
	g_object_unref (encoder);

	rb_debug ("have %d profiles with missing plugins", g_list_length (batch->priv->missing_plugin_profiles));

	for (l = batch->priv->entries; l != NULL; l = l->next) {
		RhythmDBEntry *entry = (RhythmDBEntry *)l->data;
		GstEncodingProfile *profile;

		profile = NULL;
		if (select_profile_for_entry (batch, entry, &profile, FALSE) == TRUE) {
			if (profile != NULL) {
				rb_debug ("found profile %s for %s",
					  gst_encoding_profile_get_name (profile),
					  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
			} else {
				rb_debug ("copying entry %s", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
			}
			ret = TRUE;
			continue;
		}

		(*error_count)++;
		if (select_profile_for_entry (batch, entry, &profile, TRUE) == FALSE) {
			rb_debug ("unable to transfer %s (media type %s)",
				  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION),
				  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MEDIA_TYPE));
		} else {
			rb_debug ("require additional plugins to transfer %s (media type %s)",
				  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION),
				  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MEDIA_TYPE));
			if (*missing_plugin_profiles == NULL) {
				*missing_plugin_profiles = g_list_copy (batch->priv->missing_plugin_profiles);
			}
		}
	}
	return ret;
}
static gboolean
select_profile_for_entry (RBTrackTransferBatch *batch, RhythmDBEntry *entry, GstEncodingProfile **rprofile, gboolean allow_missing)
{
	const char *source_media_type = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MEDIA_TYPE);
	const GList *p;
	int best = 0;

	for (p = gst_encoding_target_get_profiles (batch->priv->target); p != NULL; p = p->next) {
		GstEncodingProfile *profile = GST_ENCODING_PROFILE (p->data);
		char *profile_media_type;
		const char *preferred_media_type;
		gboolean transcode_lossless;
		gboolean is_preferred;
		gboolean is_lossless;
		gboolean is_source;
		gboolean is_missing;
		int rank;

		profile_media_type = rb_gst_encoding_profile_get_media_type (profile);
		if (batch->priv->settings) {
			preferred_media_type = g_settings_get_string (batch->priv->settings, "media-type");
			if (rb_gst_media_type_is_lossless (preferred_media_type)) {
				transcode_lossless = FALSE;
			} else {
				transcode_lossless = g_settings_get_boolean (batch->priv->settings, "transcode-lossless");
			}

			is_preferred = (rb_gst_media_type_matches_profile (profile, preferred_media_type));
		} else {
			preferred_media_type = NULL;
			transcode_lossless = FALSE;
			is_preferred = FALSE;
		}

		is_missing = (g_list_find (batch->priv->missing_plugin_profiles, profile) != NULL);
		if (g_str_has_prefix (source_media_type, "audio/x-raw") == FALSE) {
			is_source = rb_gst_media_type_matches_profile (profile, source_media_type);
		} else {
			/* always transcode raw audio */
			is_source = FALSE;
		}

		if (profile_media_type != NULL) {
			is_lossless = (rb_gst_media_type_is_lossless (profile_media_type));
		} else {
			is_lossless = (rb_gst_media_type_is_lossless (source_media_type));
		}

		if (is_missing && allow_missing == FALSE && is_source == FALSE) {
			/* this only applies if transcoding would be required */
			rb_debug ("can't use encoding %s due to missing plugins", profile_media_type);
			rank = 0;
		} else if (transcode_lossless && is_lossless) {
			/* this overrides is_source so all lossless files get transcoded */
			rb_debug ("don't want lossless encoding %s", profile_media_type);
			rank = 0;
		} else if (is_source) {
			/* this overrides is_preferred so we don't transcode unneccessarily */
			rb_debug ("can use source encoding %s", profile_media_type);
			rank = 100;
			profile = NULL;
		} else if (is_preferred) {
			/* otherwise, always use the preferred encoding if available */
			rb_debug ("can use preferred encoding %s", profile_media_type);
			rank = 50;
		} else if (is_lossless == FALSE) {
			/* if we can't use the preferred encoding, we prefer lossy encodings over lossless, for space reasons */
			rb_debug ("can use lossy encoding %s", profile_media_type);
			rank = 25;
		} else {
			rb_debug ("can use lossless encoding %s", profile_media_type);
			rank = 10;
		}

		g_free (profile_media_type);
		if (rank > best) {
			*rprofile = profile;
			best = rank;
		}
	}

	return (best > 0);
}
static void
missing_encoder_response_cb (GtkDialog *dialog, gint response, RBTrackTransferQueue *queue)
{
	GClosure *retry;
	GstEncodingTarget *target;
	GPtrArray *details;
	GList *profiles;
	const GList *l;
	RBEncoder *encoder;

	switch (response) {
	case GTK_RESPONSE_YES:
		/* 'continue' -> start the batch */
		rb_debug ("starting batch regardless of missing plugins");
		actually_start_batch (queue);
		break;

	case GTK_RESPONSE_CANCEL:
	case GTK_RESPONSE_DELETE_EVENT:
		/* 'cancel' -> cancel the batch and start the next one */
		rb_debug ("cancelling batch");
		_rb_track_transfer_batch_cancel (queue->priv->current);
		g_object_unref (queue->priv->current);
		queue->priv->current = NULL;

		start_next_batch (queue);
		break;

	case GTK_RESPONSE_ACCEPT:
		/* 'install plugins' -> try to install encoder/muxer */

		/* get profiles that need plugins installed */
		profiles = NULL;
		encoder = rb_encoder_new ();
		g_object_get (queue->priv->current, "encoding-target", &target, NULL);
		for (l = gst_encoding_target_get_profiles (target); l != NULL; l = l->next) {
			GstEncodingProfile *profile = GST_ENCODING_PROFILE (l->data);
			char *profile_media_type;
			profile_media_type = rb_gst_encoding_profile_get_media_type (profile);
			if (profile_media_type != NULL &&
			    (rb_gst_media_type_is_lossless (profile_media_type) == FALSE) &&
			    rb_encoder_get_missing_plugins (encoder, profile, NULL, NULL)) {
				profiles = g_list_append (profiles, profile);
			}
			g_free (profile_media_type);
		}
		g_object_unref (encoder);
		g_object_unref (target);

		if (profiles == NULL) {
			rb_debug ("apparently we don't need any plugins any more");
			actually_start_batch (queue);
			break;
		}

		rb_debug ("attempting plugin installation");
		details = get_missing_plugin_strings (profiles, FALSE);
		retry = g_cclosure_new ((GCallback) missing_plugins_retry_cb,
					g_object_ref (queue),
					(GClosureNotify) g_object_unref);
		g_closure_set_marshal (retry, g_cclosure_marshal_VOID__BOOLEAN);
		if (rb_missing_plugins_install ((const char **)details->pdata, FALSE, retry)) {
			rb_debug ("attempting to install missing plugins for transcoding");
		} else {
			rb_debug ("proceeding without the missing plugins for transcoding");
			actually_start_batch (queue);
		}

		g_closure_sink (retry);
		g_ptr_array_free (details, TRUE);
		g_list_free (profiles);
		break;

	default:
		g_assert_not_reached ();
	}

	gtk_widget_destroy (GTK_WIDGET (dialog));
}
Beispiel #7
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 gboolean
select_profile_for_entry (RBTrackTransferBatch *batch, RhythmDBEntry *entry, GstEncodingProfile **rprofile, gboolean allow_missing)
{
	/* probably want a way to pass in some policy about lossless encoding
	 * here.  possibilities:
	 * - convert everything to lossy
	 * - if transcoding is required, use lossy
	 * - keep lossless encoded files lossless
	 * - if transcoding is required, use lossless
	 * - convert everything to lossless
	 *
	 * of course this only applies to targets that include lossless profiles..
	 */

	const char *media_type = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MEDIA_TYPE);
	GstEncodingProfile *lossless = NULL;
	gboolean found_lossy = FALSE;
	const GList *p;

	for (p = gst_encoding_target_get_profiles (batch->priv->target); p != NULL; p = p->next) {
		GstEncodingProfile *profile = GST_ENCODING_PROFILE (p->data);
		char *profile_media_type;
		gboolean is_missing;
		gboolean skip;

		if (g_str_has_prefix (media_type, "audio/x-raw") == FALSE &&
		    rb_gst_media_type_matches_profile (profile, media_type)) {
			/* source file is already in a supported encoding, so just copy it */
			*rprofile = NULL;
			return TRUE;
		}

		skip = FALSE;
		is_missing = (g_list_find (batch->priv->missing_plugin_profiles, profile) != NULL);

		profile_media_type = rb_gst_encoding_profile_get_media_type (profile);
		if (profile_media_type == NULL) {
			if (g_str_has_prefix (media_type, "audio/x-raw")) {
				skip = TRUE;
			}
		} else if (rb_gst_media_type_is_lossless (profile_media_type)) {
			skip = TRUE;
			if (allow_missing == FALSE && is_missing) {
				/* ignore entirely */
			} else if (lossless == NULL) {
				/* remember the first lossless profile that works */
				lossless = profile;
			}
		} else {
			found_lossy = TRUE;
			if (allow_missing == FALSE && is_missing) {
				skip = TRUE;
			}
		}

		if (skip == FALSE && *rprofile == NULL) {
			*rprofile = profile;
		}
		g_free (profile_media_type);
	}

	/* if we only found a lossless encoding, use it */
	if (*rprofile == NULL && found_lossy == FALSE && lossless != NULL) {
		*rprofile = lossless;
	}

	return (*rprofile != NULL);
}