gnomemm r1446 - in gstreamermm/trunk: . examples/media_player_gtkmm examples/ogg_player examples/ogg_player_gtkmm
- From: jaalburqu svn gnome org
- To: svn-commits-list gnome org
- Subject: gnomemm r1446 - in gstreamermm/trunk: . examples/media_player_gtkmm examples/ogg_player examples/ogg_player_gtkmm
- Date: Tue, 8 Apr 2008 05:57:17 +0100 (BST)
Author: jaalburqu
Date: Tue Apr 8 05:57:17 2008
New Revision: 1446
URL: http://svn.gnome.org/viewvc/gnomemm?rev=1446&view=rev
Log:
2008-04-08 Josà Alburquerque <jaalburqu svn gnome org>
* examples/media_player_gtkmm/PlayerWindow.cc:
* examples/media_player_gtkmm/PlayerWindow.h:
* examples/media_player_gtkmm/main.cc: Modified media player example
to use its own video sink with the playbin pipeline; Modified widget
packing so that videoArea takes most space and rest less; Added code
to react to initial data (buffer) received in the video sink pad to
deal with size of videoArea.
Modified:
gstreamermm/trunk/ChangeLog
gstreamermm/trunk/examples/media_player_gtkmm/PlayerWindow.cc
gstreamermm/trunk/examples/media_player_gtkmm/PlayerWindow.h
gstreamermm/trunk/examples/media_player_gtkmm/main.cc
gstreamermm/trunk/examples/ogg_player/ (props changed)
gstreamermm/trunk/examples/ogg_player_gtkmm/ (props changed)
Modified: gstreamermm/trunk/examples/media_player_gtkmm/PlayerWindow.cc
==============================================================================
--- gstreamermm/trunk/examples/media_player_gtkmm/PlayerWindow.cc (original)
+++ gstreamermm/trunk/examples/media_player_gtkmm/PlayerWindow.cc Tue Apr 8 05:57:17 2008
@@ -23,7 +23,9 @@
#include <gtkmm/filechooserdialog.h>
#include <gdk/gdkx.h>
#include <gstreamermm/bus.h>
+#include <gstreamermm/caps.h>
#include <gstreamermm/clock.h>
+#include <gstreamermm/buffer.h>
#include <gstreamermm/event.h>
#include <gstreamermm/message.h>
#include <gstreamermm/query.h>
@@ -34,8 +36,8 @@
#include <iomanip>
#include "PlayerWindow.h"
-PlayerWindow::PlayerWindow(Glib::RefPtr<Gst::Element> playbin,
- Glib::RefPtr<Gst::Pipeline> mainPipeline) :
+PlayerWindow::PlayerWindow(const Glib::RefPtr<Gst::Pipeline>& playbin,
+ const Glib::RefPtr<Gst::Element>& videoSink) :
vBox(false, 5),
progressLabel("000:00:00.000000000 / 000:00:00.000000000"),
playButton(Gtk::Stock::MEDIA_PLAY),
@@ -48,10 +50,10 @@
set_title("gstreamermm Media Player Example");
add(vBox);
- vBox.pack_start(videoArea);
- vBox.pack_start(progressLabel);
- vBox.pack_start(progressScale);
- vBox.pack_start(buttonBox);
+ vBox.pack_start(videoArea, Gtk::PACK_EXPAND_WIDGET);
+ vBox.pack_start(progressLabel, Gtk::PACK_SHRINK);
+ vBox.pack_start(progressScale, Gtk::PACK_SHRINK);
+ vBox.pack_start(buttonBox, Gtk::PACK_SHRINK);
progressLabel.set_alignment(Gtk::ALIGN_CENTER);
@@ -81,7 +83,7 @@
&PlayerWindow::on_open));
// get the bus from the pipeline
- Glib::RefPtr<Gst::Bus> bus = mainPipeline->get_bus();
+ Glib::RefPtr<Gst::Bus> bus = playbin->get_bus();
// Add a sync handler to receive synchronous messages from pipeline's
// bus (this is done so that videoArea can be set up for drawing at an
@@ -101,7 +103,7 @@
forwardButton.set_sensitive(false);
this->playbin = playbin;
- this->mainPipeline = mainPipeline;
+ this->videoSink = videoSink;
show_all_children();
pauseButton.hide();
@@ -127,14 +129,14 @@
if (xoverlay)
{
- gulong xWindowId = GDK_WINDOW_XID(Glib::unwrap(videoArea.get_window()));
+ gulong xWindowId = GDK_WINDOW_XID(videoArea.get_window()->gobj());
xoverlay->set_xwindow_id(xWindowId);
}
return Gst::BUS_DROP;
}
-// This function is used to receive asynchronous messages from mainPipeline's bus
+// This function is used to receive asynchronous messages from playbin's bus
bool PlayerWindow::on_bus_message(const Glib::RefPtr<Gst::Bus>& /* bus_not_used */,
const Glib::RefPtr<Gst::Message>& message)
{
@@ -201,6 +203,30 @@
return true;
}
+bool PlayerWindow::on_video_pad_got_buffer(const Glib::RefPtr<Gst::Pad>& pad,
+ const Glib::RefPtr<Gst::MiniObject>& data)
+{
+ Glib::RefPtr<Gst::Buffer> buffer = Glib::RefPtr<Gst::Buffer>::cast_dynamic(data);
+
+ if (buffer) {
+ Glib::Value<int> widthValue;
+ Glib::Value<int> heightValue;
+
+ Glib::RefPtr<Gst::Caps> caps = buffer->get_caps();
+ caps->get_structure(0)->get_field("width", widthValue);
+ caps->get_structure(0)->get_field("height", heightValue);
+
+ videoArea.set_size_request(widthValue.get(), heightValue.get());
+ resize(1, 1); // Resize to minimum when first playing by making size
+ check_resize(); // smallest then resizing according to video new size
+ }
+
+ pad->remove_buffer_probe(pad_probe_id);
+ pad_probe_id = 0; // Clear probe id to indicate that it has been removed
+
+ return true; // Keep buffer in pipeline (do not throw away)
+}
+
void PlayerWindow::on_play(void)
{
progressScale.set_sensitive(true);
@@ -220,7 +246,7 @@
&PlayerWindow::update_stream_progress), 200);
// set Gstmm pipeline to play mode
- mainPipeline->set_state(Gst::STATE_PLAYING);
+ playbin->set_state(Gst::STATE_PLAYING);
}
void PlayerWindow::on_pause(void)
@@ -235,7 +261,7 @@
progressConnection.disconnect();
// set Gstmm pipeline to pause mode
- mainPipeline->set_state(Gst::STATE_PAUSED);
+ playbin->set_state(Gst::STATE_PAUSED);
}
void PlayerWindow::on_stop(void)
@@ -255,16 +281,27 @@
progressConnection.disconnect();
// set Gstmm pipeline to inactive mode
- mainPipeline->set_state(Gst::STATE_NULL);
+ playbin->set_state(Gst::STATE_NULL);
+
+ // reset display
display_label_progress(0, duration);
progressScale.set_value(0);
+
+ // Remove video sink pad buffer probe if after playing, probe id is
+ // not zero (means probe was not removed because media had no video and
+ // video_pad_got_buffer method never got a chance to remove probe)
+ if (pad_probe_id != 0)
+ {
+ videoSink->get_pad("sink")->remove_buffer_probe(pad_probe_id);
+ pad_probe_id = 0;
+ }
}
bool PlayerWindow::on_scale_value_changed(Gtk::ScrollType /* type_not_used */, double value)
{
gint64 newPos = gint64(value * duration);
- if (mainPipeline->seek(Gst::FORMAT_TIME, Gst::SEEK_FLAG_FLUSH, newPos))
+ if (playbin->seek(Gst::FORMAT_TIME, Gst::SEEK_FLAG_FLUSH, newPos))
{
display_label_progress(newPos, duration);
return true;
@@ -283,13 +320,13 @@
gint64 pos;
Gst::Format fmt = Gst::FORMAT_TIME;
- if (mainPipeline->query_position(fmt, pos))
+ if (playbin->query_position(fmt, pos))
{
gint64 newPos = (pos > skipAmount) ? (pos - skipAmount) : 0;
- if (mainPipeline->seek(Gst::FORMAT_TIME, Gst::SEEK_FLAG_FLUSH, newPos)) {
- display_label_progress(newPos, duration);
+ if (playbin->seek(Gst::FORMAT_TIME, Gst::SEEK_FLAG_FLUSH, newPos)) {
progressScale.set_value(double(newPos) / duration);
+ display_label_progress(newPos, duration);
}
else
std::cerr << "Could not seek!" << std::endl;
@@ -305,7 +342,7 @@
Glib::RefPtr<Gst::Query> query = Gst::QueryPosition::create(fmt);
- if (mainPipeline->query(query))
+ if (playbin->query(query))
{
Glib::RefPtr<Gst::QueryPosition> posQuery =
Glib::RefPtr<Gst::QueryPosition>::cast_dynamic(query);
@@ -322,7 +359,7 @@
Glib::RefPtr<Gst::EventSeek> seekEvent =
Glib::RefPtr<Gst::EventSeek>::cast_dynamic(event);
- if (mainPipeline->send_event(seekEvent))
+ if (playbin->send_event(seekEvent))
{
progressScale.set_value(double(newPos) / duration);
display_label_progress(newPos, duration);
@@ -349,8 +386,22 @@
if (response == Gtk::RESPONSE_OK) {
workingDir = chooser.get_current_folder();
- // Set filename property on the file source. Also add a message handler:
- playbin->set_property("uri", chooser.get_uri());
+ // Set uri property on the playbin.
+ Glib::RefPtr<Gst::Element>::cast_dynamic(playbin)->
+ set_property("uri", chooser.get_uri());
+
+ // Resize videoArea and window to minimum when opening a file
+ videoArea.set_size_request(0, 0);
+ resize(1, 1);
+
+ // Add buffer probe to video sink pad when file is opened which will
+ // be removed after first buffer is received in on_video_pad_got_buffer
+ // method (if there's video). When first buffer arrives, video
+ // size can be extracted. If there's no video, probe will be
+ // removed when media stops in on_stop method
+ pad_probe_id = videoSink->get_pad("sink")->add_buffer_probe(
+ sigc::mem_fun(*this, &PlayerWindow::on_video_pad_got_buffer));
+
set_title(Glib::filename_display_basename(chooser.get_filename()));
playButton.set_sensitive(true);
@@ -363,8 +414,8 @@
Gst::Format fmt = Gst::FORMAT_TIME;
gint64 pos = 0;
- if (mainPipeline->query_position(fmt, pos)
- && mainPipeline->query_duration(fmt, duration)) {
+ if (playbin->query_position(fmt, pos)
+ && playbin->query_duration(fmt, duration)) {
progressScale.set_value(double(pos) / duration);
display_label_progress(pos, duration);
}
@@ -394,5 +445,5 @@
PlayerWindow::~PlayerWindow()
{
- mainPipeline->get_bus()->remove_watch(watch_id);
+ playbin->get_bus()->remove_watch(watch_id);
}
Modified: gstreamermm/trunk/examples/media_player_gtkmm/PlayerWindow.h
==============================================================================
--- gstreamermm/trunk/examples/media_player_gtkmm/PlayerWindow.h (original)
+++ gstreamermm/trunk/examples/media_player_gtkmm/PlayerWindow.h Tue Apr 8 05:57:17 2008
@@ -35,8 +35,9 @@
class PlayerWindow : public Gtk::Window
{
public:
- PlayerWindow(Glib::RefPtr<Gst::Element> playbin,
- Glib::RefPtr<Gst::Pipeline> mainPipeline);
+ PlayerWindow(const Glib::RefPtr<Gst::Pipeline>& playbin,
+ const Glib::RefPtr<Gst::Element>& videoSink);
+
~PlayerWindow();
protected:
Gtk::VBox vBox;
@@ -58,6 +59,9 @@
virtual bool on_bus_message(const Glib::RefPtr<Gst::Bus>& bus,
const Glib::RefPtr<Gst::Message>& message);
+ virtual bool on_video_pad_got_buffer(const Glib::RefPtr<Gst::Pad>& pad,
+ const Glib::RefPtr<Gst::MiniObject>& buffer);
+
virtual void on_play(void);
virtual void on_pause(void);
virtual void on_stop(void);
@@ -69,11 +73,12 @@
bool update_stream_progress(void);
void display_label_progress(gint64 pos, gint64 len);
private:
- Glib::RefPtr<Gst::Element> playbin;
- Glib::RefPtr<Gst::Pipeline> mainPipeline;
+ Glib::RefPtr<Gst::Pipeline> playbin;
+ Glib::RefPtr<Gst::Element> videoSink;
sigc::connection progressConnection;
- unsigned int watch_id;
+ guint watch_id;
gint64 duration;
+ gulong pad_probe_id;
};
#endif /* _PLAYERWINDOW_H */
Modified: gstreamermm/trunk/examples/media_player_gtkmm/main.cc
==============================================================================
--- gstreamermm/trunk/examples/media_player_gtkmm/main.cc (original)
+++ gstreamermm/trunk/examples/media_player_gtkmm/main.cc Tue Apr 8 05:57:17 2008
@@ -34,38 +34,31 @@
Gtk::Main kit(argc, argv);
Gst::init(argc, argv);
- // Create the pipeline
- Glib::RefPtr<Gst::Pipeline> pipeline = Gst::Pipeline::create("media-player");
-
// Create the elements
// Autoplays any media type. Implements GstBase::XOverlay so accepts
// a window id in which to draw video
- Glib::RefPtr<Gst::Element> playbin = Gst::ElementFactory::create("playbin", "media-playbin");
+ Glib::RefPtr<Gst::Element> playbin = Gst::ElementFactory::create("playbin", "media-player");
+ Glib::RefPtr<Gst::Pipeline> playbinPipeline = Glib::RefPtr<Gst::Pipeline>::cast_dynamic(playbin);
- if (!pipeline || !playbin)
- {
- std::cerr << "One element could not be created" << std::endl;
- return -1;
- }
+ // Video sink where video (if any) will be drawn
+ Glib::RefPtr<Gst::Element> videoSink = Gst::ElementFactory::create("ximagesink", "video-sink");
- // Put elements in a pipeline:
- try
+ if (!playbinPipeline || !videoSink)
{
- pipeline->add(playbin);
- }
- catch(const Glib::Error& ex)
- {
- std::cerr << "Error while adding elements to the pipeline: " << ex.what() << std::endl;
+ std::cerr << "One of the elements for media player could not be created." << std::endl;
return -1;
}
- PlayerWindow mainWindow(playbin, pipeline);
+ // set the playbin's video-sink property so that videoSink is used for video display
+ playbinPipeline->set_property("video-sink", videoSink);
+
+ PlayerWindow mainWindow(playbinPipeline, videoSink);
kit.run(mainWindow);
// Clean up nicely:
- pipeline->set_state(Gst::STATE_NULL);
+ playbinPipeline->set_state(Gst::STATE_NULL);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]