mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 21:16:24 +00:00
Added playback tutorial 2, fixed connection speed in playback tutorial 1
This commit is contained in:
parent
1e20154e2b
commit
a8e8e02ef2
5 changed files with 319 additions and 1 deletions
|
@ -54,7 +54,7 @@ int main(int argc, char *argv[]) {
|
|||
g_object_set (data.playbin2, "flags", flags, NULL);
|
||||
|
||||
/* Set connection speed. This will affect some internal decisions of playbin2 */
|
||||
g_object_set (data.playbin2, "connection-speed", 56000, NULL);
|
||||
g_object_set (data.playbin2, "connection-speed", 56, NULL);
|
||||
|
||||
/* Add a bus watch, so we get notified when a message arrives */
|
||||
bus = gst_element_get_bus (data.playbin2);
|
||||
|
|
220
gst-sdk/tutorials/playback-tutorial-2.c
Normal file
220
gst-sdk/tutorials/playback-tutorial-2.c
Normal file
|
@ -0,0 +1,220 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
/* Structure to contain all our information, so we can pass it around */
|
||||
typedef struct _CustomData {
|
||||
GstElement *playbin2; /* Our one and only element */
|
||||
|
||||
gint n_video; /* Number of embedded video streams */
|
||||
gint n_audio; /* Number of embedded audio streams */
|
||||
gint n_text; /* Number of embedded subtitle streams */
|
||||
|
||||
gint current_video; /* Currently playing video stream */
|
||||
gint current_audio; /* Currently playing audio stream */
|
||||
gint current_text; /* Currently playing subtitle stream */
|
||||
|
||||
GMainLoop *main_loop; /* GLib's Main Loop */
|
||||
} CustomData;
|
||||
|
||||
/* playbin2 flags */
|
||||
typedef enum {
|
||||
GST_PLAY_FLAG_VIDEO = (1 << 0), /* We want video output */
|
||||
GST_PLAY_FLAG_AUDIO = (1 << 1), /* We want audio output */
|
||||
GST_PLAY_FLAG_TEXT = (1 << 2) /* We want subtitle output */
|
||||
} GstPlayFlags;
|
||||
|
||||
/* Forward definition for the message and keyboard processing functions */
|
||||
static gboolean handle_message (GstBus *bus, GstMessage *msg, CustomData *data);
|
||||
static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
CustomData data;
|
||||
GstBus *bus;
|
||||
GstStateChangeReturn ret;
|
||||
gint flags;
|
||||
GIOChannel *io_stdin;
|
||||
|
||||
/* Initialize GStreamer */
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
/* Create the elements */
|
||||
data.playbin2 = gst_element_factory_make ("playbin2", "playbin2");
|
||||
|
||||
if (!data.playbin2) {
|
||||
g_printerr ("Not all elements could be created.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the URI to play */
|
||||
g_object_set (data.playbin2, "uri", "http://docs.gstreamer.com/media/sintel_trailer-480p.ogv", NULL);
|
||||
|
||||
/* Set the subtitle URI to play and some font description */
|
||||
g_object_set (data.playbin2, "suburi", "http://docs.gstreamer.com/media/sintel_trailer_gr.srt", NULL);
|
||||
g_object_set (data.playbin2, "subtitle-font-desc", "Sans, 18", NULL);
|
||||
|
||||
/* Set flags to show Audio, Video and Subtitles */
|
||||
g_object_get (data.playbin2, "flags", &flags, NULL);
|
||||
flags |= GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_TEXT;
|
||||
g_object_set (data.playbin2, "flags", flags, NULL);
|
||||
|
||||
/* Add a bus watch, so we get notified when a message arrives */
|
||||
bus = gst_element_get_bus (data.playbin2);
|
||||
gst_bus_add_watch (bus, (GstBusFunc)handle_message, &data);
|
||||
|
||||
/* Add a keyboard watch so we get notified of keystrokes */
|
||||
#ifdef _WIN32
|
||||
io_stdin = g_io_channel_win32_new_fd (fileno (stdin));
|
||||
#else
|
||||
io_stdin = g_io_channel_unix_new (fileno (stdin));
|
||||
#endif
|
||||
g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc)handle_keyboard, &data);
|
||||
|
||||
/* Start playing */
|
||||
ret = gst_element_set_state (data.playbin2, GST_STATE_PLAYING);
|
||||
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||
g_printerr ("Unable to set the pipeline to the playing state.\n");
|
||||
gst_object_unref (data.playbin2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create a GLib Main Loop and set it to run */
|
||||
data.main_loop = g_main_loop_new (NULL, FALSE);
|
||||
g_main_loop_run (data.main_loop);
|
||||
|
||||
/* Free resources */
|
||||
g_main_loop_unref (data.main_loop);
|
||||
g_io_channel_unref (io_stdin);
|
||||
gst_object_unref (bus);
|
||||
gst_element_set_state (data.playbin2, GST_STATE_NULL);
|
||||
gst_object_unref (data.playbin2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Extract some metadata from the streams and print it on the screen */
|
||||
static void analyze_streams (CustomData *data) {
|
||||
gint i;
|
||||
GstTagList *tags;
|
||||
gchar *str;
|
||||
guint rate;
|
||||
|
||||
/* Read some properties */
|
||||
g_object_get (data->playbin2, "n-video", &data->n_video, NULL);
|
||||
g_object_get (data->playbin2, "n-audio", &data->n_audio, NULL);
|
||||
g_object_get (data->playbin2, "n-text", &data->n_text, NULL);
|
||||
|
||||
g_print ("%d video stream(s), %d audio stream(s), %d text stream(s)\n",
|
||||
data->n_video, data->n_audio, data->n_text);
|
||||
|
||||
g_print ("\n");
|
||||
for (i = 0; i < data->n_video; i++) {
|
||||
tags = NULL;
|
||||
/* Retrieve the stream's video tags */
|
||||
g_signal_emit_by_name (data->playbin2, "get-video-tags", i, &tags);
|
||||
if (tags) {
|
||||
g_print ("video stream %d:\n", i);
|
||||
gst_tag_list_get_string (tags, GST_TAG_VIDEO_CODEC, &str);
|
||||
g_print (" codec: %s\n", str ? str : "unknown");
|
||||
g_free (str);
|
||||
gst_tag_list_free (tags);
|
||||
}
|
||||
}
|
||||
|
||||
g_print ("\n");
|
||||
for (i = 0; i < data->n_audio; i++) {
|
||||
tags = NULL;
|
||||
/* Retrieve the stream's audio tags */
|
||||
g_signal_emit_by_name (data->playbin2, "get-audio-tags", i, &tags);
|
||||
if (tags) {
|
||||
g_print ("audio stream %d:\n", i);
|
||||
if (gst_tag_list_get_string (tags, GST_TAG_AUDIO_CODEC, &str)) {
|
||||
g_print (" codec: %s\n", str);
|
||||
g_free (str);
|
||||
}
|
||||
if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) {
|
||||
g_print (" language: %s\n", str);
|
||||
g_free (str);
|
||||
}
|
||||
if (gst_tag_list_get_uint (tags, GST_TAG_BITRATE, &rate)) {
|
||||
g_print (" bitrate: %d\n", rate);
|
||||
}
|
||||
gst_tag_list_free (tags);
|
||||
}
|
||||
}
|
||||
|
||||
g_print ("\n");
|
||||
for (i = 0; i < data->n_text; i++) {
|
||||
tags = NULL;
|
||||
/* Retrieve the stream's subtitle tags */
|
||||
g_print ("subtitle stream %d:\n", i);
|
||||
g_signal_emit_by_name (data->playbin2, "get-text-tags", i, &tags);
|
||||
if (tags) {
|
||||
if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) {
|
||||
g_print (" language: %s\n", str);
|
||||
g_free (str);
|
||||
}
|
||||
gst_tag_list_free (tags);
|
||||
} else {
|
||||
g_print (" no tags found\n");
|
||||
}
|
||||
}
|
||||
|
||||
g_object_get (data->playbin2, "current-video", &data->current_video, NULL);
|
||||
g_object_get (data->playbin2, "current-audio", &data->current_audio, NULL);
|
||||
g_object_get (data->playbin2, "current-text", &data->current_text, NULL);
|
||||
|
||||
g_print ("\n");
|
||||
g_print ("Currently playing video stream %d, audio stream %d and subtitle stream %d\n",
|
||||
data->current_video, data->current_audio, data->current_text);
|
||||
g_print ("Type any number and hit ENTER to select a different subtitle stream\n");
|
||||
}
|
||||
|
||||
/* Process messages from GStreamer */
|
||||
static gboolean handle_message (GstBus *bus, GstMessage *msg, CustomData *data) {
|
||||
GError *err;
|
||||
gchar *debug_info;
|
||||
|
||||
switch (GST_MESSAGE_TYPE (msg)) {
|
||||
case GST_MESSAGE_ERROR:
|
||||
gst_message_parse_error (msg, &err, &debug_info);
|
||||
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
|
||||
g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
|
||||
g_clear_error (&err);
|
||||
g_free (debug_info);
|
||||
g_main_loop_quit (data->main_loop);
|
||||
break;
|
||||
case GST_MESSAGE_EOS:
|
||||
g_print ("End-Of-Stream reached.\n");
|
||||
g_main_loop_quit (data->main_loop);
|
||||
break;
|
||||
case GST_MESSAGE_STATE_CHANGED: {
|
||||
GstState old_state, new_state, pending_state;
|
||||
gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
|
||||
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->playbin2)) {
|
||||
if (new_state == GST_STATE_PLAYING) {
|
||||
/* Once we are in the playing state, analyze the streams */
|
||||
analyze_streams (data);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
/* We want to keep receiving messages */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Process keyboard input */
|
||||
static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) {
|
||||
gchar *str = NULL;
|
||||
|
||||
if (g_io_channel_read_line (source, &str, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) {
|
||||
int index = atoi (str);
|
||||
if (index < 0 || index >= data->n_text) {
|
||||
g_printerr ("Index out of bounds\n");
|
||||
} else {
|
||||
/* If the input was a valid subtitle stream index, set the current subtitle stream */
|
||||
g_print ("Setting current subtitle stream to %d\n", index);
|
||||
g_object_set (data->playbin2, "current-text", index, NULL);
|
||||
}
|
||||
}
|
||||
g_free (str);
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4319F5D7-039A-44B5-B1A7-507DC627B24D}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>playbacktutorial2</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\libs\gstreamer-0.10.props" />
|
||||
<Import Project="..\..\libs\msvc\x86.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\libs\gstreamer-0.10.props" />
|
||||
<Import Project="..\..\libs\msvc\x86.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\..\gst-sdk\tutorials\playback-tutorial-2.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\..\gst-sdk\tutorials\playback-tutorial-2.c" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -13,6 +13,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic-tutorial-5", "basic-t
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-1", "playback-tutorial-1\playback-tutorial-1.vcxproj", "{474353B0-D353-4DB7-A9EE-E210D1ED954B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-2", "playback-tutorial-2\playback-tutorial-2.vcxproj", "{4319F5D7-039A-44B5-B1A7-507DC627B24D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -43,6 +45,10 @@ Global
|
|||
{474353B0-D353-4DB7-A9EE-E210D1ED954B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{474353B0-D353-4DB7-A9EE-E210D1ED954B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{474353B0-D353-4DB7-A9EE-E210D1ED954B}.Release|Win32.Build.0 = Release|Win32
|
||||
{4319F5D7-039A-44B5-B1A7-507DC627B24D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4319F5D7-039A-44B5-B1A7-507DC627B24D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4319F5D7-039A-44B5-B1A7-507DC627B24D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4319F5D7-039A-44B5-B1A7-507DC627B24D}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in a new issue