mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-14 13:21:28 +00:00
launcher: Re activate smart rendering support
Trying to get the best encoding profile for smart rendering when the user didn't specify anything. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/198>
This commit is contained in:
parent
6f7d4ac525
commit
3a6530a127
1 changed files with 135 additions and 10 deletions
|
@ -105,10 +105,111 @@ _set_restriction_caps (GESTimeline * timeline, GESLauncherParsedOptions * opts)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_check_has_audio_video (GESLauncher * self, gint * n_audio, gint * n_video)
|
||||||
|
{
|
||||||
|
GList *tmp, *tracks = ges_timeline_get_tracks (self->priv->timeline);
|
||||||
|
|
||||||
|
*n_video = *n_audio = 0;
|
||||||
|
for (tmp = tracks; tmp; tmp = tmp->next) {
|
||||||
|
if (GES_TRACK (tmp->data)->type == GES_TRACK_TYPE_VIDEO)
|
||||||
|
*n_video = *n_video + 1;
|
||||||
|
else if (GES_TRACK (tmp->data)->type == GES_TRACK_TYPE_AUDIO)
|
||||||
|
*n_audio = *n_audio + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define N_INSTANCES "__n_instances"
|
||||||
|
static gint
|
||||||
|
sort_encoding_profiles (gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
const gint acount =
|
||||||
|
GPOINTER_TO_INT (g_object_get_data ((GObject *) a, N_INSTANCES));
|
||||||
|
const gint bcount =
|
||||||
|
GPOINTER_TO_INT (g_object_get_data ((GObject *) b, N_INSTANCES));
|
||||||
|
|
||||||
|
if (acount < bcount)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (acount == bcount)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstEncodingProfile *
|
||||||
|
get_smart_profile (GESLauncher * self)
|
||||||
|
{
|
||||||
|
gint n_audio, n_video;
|
||||||
|
GList *tmp, *assets, *possible_profiles = NULL;
|
||||||
|
GstEncodingProfile *res = NULL;
|
||||||
|
GESProject *proj =
|
||||||
|
GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE (self->
|
||||||
|
priv->timeline)));
|
||||||
|
|
||||||
|
_check_has_audio_video (self, &n_audio, &n_video);
|
||||||
|
assets = ges_project_list_assets (proj, GES_TYPE_URI_CLIP);
|
||||||
|
for (tmp = assets; tmp; tmp = tmp->next) {
|
||||||
|
GESAsset *asset = tmp->data;
|
||||||
|
GList *audio_streams, *video_streams;
|
||||||
|
GstDiscovererInfo *info;
|
||||||
|
|
||||||
|
if (!GES_IS_URI_CLIP_ASSET (asset))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
info = ges_uri_clip_asset_get_info (GES_URI_CLIP_ASSET (asset));
|
||||||
|
audio_streams = gst_discoverer_info_get_audio_streams (info);
|
||||||
|
video_streams = gst_discoverer_info_get_video_streams (info);
|
||||||
|
if (g_list_length (audio_streams) >= n_audio
|
||||||
|
&& g_list_length (video_streams) >= n_video) {
|
||||||
|
GstEncodingProfile *prof = gst_encoding_profile_from_discoverer (info);
|
||||||
|
GList *prevprof;
|
||||||
|
|
||||||
|
prevprof =
|
||||||
|
g_list_find_custom (possible_profiles, prof,
|
||||||
|
(GCompareFunc) gst_encoding_profile_is_equal);
|
||||||
|
if (prevprof) {
|
||||||
|
g_object_unref (prof);
|
||||||
|
prof = prevprof->data;
|
||||||
|
} else {
|
||||||
|
possible_profiles = g_list_prepend (possible_profiles, prof);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_set_data ((GObject *) prof, N_INSTANCES,
|
||||||
|
GINT_TO_POINTER (GPOINTER_TO_INT (g_object_get_data ((GObject *) prof,
|
||||||
|
N_INSTANCES)) + 1));
|
||||||
|
}
|
||||||
|
gst_discoverer_stream_info_list_free (audio_streams);
|
||||||
|
gst_discoverer_stream_info_list_free (video_streams);
|
||||||
|
}
|
||||||
|
g_list_free_full (assets, gst_object_unref);
|
||||||
|
|
||||||
|
if (possible_profiles) {
|
||||||
|
possible_profiles = g_list_sort (possible_profiles, sort_encoding_profiles);
|
||||||
|
res = gst_object_ref (possible_profiles->data);
|
||||||
|
g_list_free_full (possible_profiles, gst_object_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
disable_bframe_for_smart_rendering_cb (GstBin * bin, GstBin * sub_bin,
|
||||||
|
GstElement * child)
|
||||||
|
{
|
||||||
|
GstElementFactory *factory = gst_element_get_factory (child);
|
||||||
|
|
||||||
|
if (factory && !g_strcmp0 (GST_OBJECT_NAME (factory), "x264enc")) {
|
||||||
|
g_object_set (child, "b-adapt", FALSE, "b-pyramid", FALSE, "bframes", 0,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_set_rendering_details (GESLauncher * self)
|
_set_rendering_details (GESLauncher * self)
|
||||||
{
|
{
|
||||||
GESLauncherParsedOptions *opts = &self->priv->parsed_options;
|
GESLauncherParsedOptions *opts = &self->priv->parsed_options;
|
||||||
|
gboolean smart_profile = FALSE;
|
||||||
GESPipelineFlags cmode = ges_pipeline_get_mode (self->priv->pipeline);
|
GESPipelineFlags cmode = ges_pipeline_get_mode (self->priv->pipeline);
|
||||||
|
|
||||||
if (cmode & GES_PIPELINE_MODE_RENDER
|
if (cmode & GES_PIPELINE_MODE_RENDER
|
||||||
|
@ -138,8 +239,14 @@ _set_rendering_details (GESLauncher * self)
|
||||||
|
|
||||||
if (!prof) {
|
if (!prof) {
|
||||||
if (opts->format == NULL) {
|
if (opts->format == NULL) {
|
||||||
opts->format = get_file_extension (opts->outputuri);
|
if (opts->smartrender)
|
||||||
prof = parse_encoding_profile (opts->format);
|
prof = get_smart_profile (self);
|
||||||
|
if (prof)
|
||||||
|
smart_profile = TRUE;
|
||||||
|
else {
|
||||||
|
opts->format = get_file_extension (opts->outputuri);
|
||||||
|
prof = parse_encoding_profile (opts->format);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
prof = parse_encoding_profile (opts->format);
|
prof = parse_encoding_profile (opts->format);
|
||||||
if (!prof)
|
if (!prof)
|
||||||
|
@ -161,11 +268,17 @@ _set_rendering_details (GESLauncher * self)
|
||||||
}
|
}
|
||||||
|
|
||||||
g_print ("Output: %s\n", opts->outputuri);
|
g_print ("Output: %s\n", opts->outputuri);
|
||||||
g_print ("Encoding to:\n");
|
g_print ("Encoding to:%s\n", smart_profile ?
|
||||||
|
" (Selected from input files format for efficient smart rendering)" :
|
||||||
|
"");
|
||||||
describe_encoding_profile (prof);
|
describe_encoding_profile (prof);
|
||||||
}
|
}
|
||||||
|
|
||||||
opts->outputuri = ensure_uri (opts->outputuri);
|
opts->outputuri = ensure_uri (opts->outputuri);
|
||||||
|
if (opts->smartrender) {
|
||||||
|
g_signal_connect (self->priv->pipeline, "deep-element-added",
|
||||||
|
G_CALLBACK (disable_bframe_for_smart_rendering_cb), NULL);
|
||||||
|
}
|
||||||
if (!prof
|
if (!prof
|
||||||
|| !ges_pipeline_set_render_settings (self->priv->pipeline,
|
|| !ges_pipeline_set_render_settings (self->priv->pipeline,
|
||||||
opts->outputuri, prof)
|
opts->outputuri, prof)
|
||||||
|
@ -182,6 +295,19 @@ _set_rendering_details (GESLauncher * self)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_track_set_mixing (GESTrack * track, GESLauncherParsedOptions * opts)
|
||||||
|
{
|
||||||
|
static gboolean printed_mixing_disabled = FALSE;
|
||||||
|
|
||||||
|
if (opts->disable_mixing || opts->smartrender)
|
||||||
|
ges_track_set_mixing (track, FALSE);
|
||||||
|
if (!opts->disable_mixing && opts->smartrender && !printed_mixing_disabled) {
|
||||||
|
g_print ("**Mixing is disabled for smart rendering to work**\n");
|
||||||
|
printed_mixing_disabled = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_timeline_set_user_options (GESLauncher * self, GESTimeline * timeline,
|
_timeline_set_user_options (GESLauncher * self, GESTimeline * timeline,
|
||||||
const gchar * load_path)
|
const gchar * load_path)
|
||||||
|
@ -199,9 +325,7 @@ retry:
|
||||||
else if (GES_TRACK (tmp->data)->type == GES_TRACK_TYPE_AUDIO)
|
else if (GES_TRACK (tmp->data)->type == GES_TRACK_TYPE_AUDIO)
|
||||||
has_audio = TRUE;
|
has_audio = TRUE;
|
||||||
|
|
||||||
if (opts->disable_mixing)
|
_track_set_mixing (tmp->data, opts);
|
||||||
ges_track_set_mixing (tmp->data, FALSE);
|
|
||||||
|
|
||||||
if (!(GES_TRACK (tmp->data)->type & opts->track_types)) {
|
if (!(GES_TRACK (tmp->data)->type & opts->track_types)) {
|
||||||
ges_timeline_remove_track (timeline, tmp->data);
|
ges_timeline_remove_track (timeline, tmp->data);
|
||||||
goto retry;
|
goto retry;
|
||||||
|
@ -215,8 +339,7 @@ retry:
|
||||||
if (!_set_track_restriction_caps (trackv, opts->video_track_caps))
|
if (!_set_track_restriction_caps (trackv, opts->video_track_caps))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (opts->disable_mixing)
|
_track_set_mixing (trackv, opts);
|
||||||
ges_track_set_mixing (trackv, FALSE);
|
|
||||||
|
|
||||||
if (!(ges_timeline_add_track (timeline, trackv)))
|
if (!(ges_timeline_add_track (timeline, trackv)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -228,8 +351,7 @@ retry:
|
||||||
if (!_set_track_restriction_caps (tracka, opts->audio_track_caps))
|
if (!_set_track_restriction_caps (tracka, opts->audio_track_caps))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (opts->disable_mixing)
|
_track_set_mixing (tracka, opts);
|
||||||
ges_track_set_mixing (tracka, FALSE);
|
|
||||||
|
|
||||||
if (!(ges_timeline_add_track (timeline, tracka)))
|
if (!(ges_timeline_add_track (timeline, tracka)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -720,6 +842,9 @@ ges_launcher_get_rendering_option_group (GESLauncherParsedOptions * opts)
|
||||||
"See ges-launch-1.0 help profile for more information. "
|
"See ges-launch-1.0 help profile for more information. "
|
||||||
"This will have no effect if no outputuri has been specified.",
|
"This will have no effect if no outputuri has been specified.",
|
||||||
"<profile-name>"},
|
"<profile-name>"},
|
||||||
|
{"smart-rendering", 0, 0, G_OPTION_ARG_NONE, &opts->smartrender,
|
||||||
|
"Avoid reencoding when rendering. This option implies --disable-mixing.",
|
||||||
|
NULL},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue