#include "widget.h"
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include <QToolButton>
#include <QStyle>
void Widget::handle_message (CustomData *data, GstMessage *msg)
{
GError *err;
gchar *debug_info;
switch (GST_MESSAGE_TYPE (msg))
{
case GST_MESSAGE_ERROR:
gst_message_parse_error (msg, &err, &debug_info);
qCritical() << "Error received from element " << QString(GST_OBJECT_NAME (msg->src)) << ":" << QString(err->message);
qCritical() << "Debugging information:" << QString(debug_info);
g_clear_error (&err);
g_free (debug_info);
if(queryTimer->isActive())
{
queryTimer->stop();
}
break;
case GST_MESSAGE_EOS:
qInfo ("End-Of-Stream reached.\n");
if(queryTimer->isActive())
{
queryTimer->stop();
}
break;
case GST_MESSAGE_DURATION:
data->duration = GST_CLOCK_TIME_NONE;
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);
qInfo() << "GST_MESSAGE_STATE_CHANGED is called!!!";
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->playbin2))
{
g_print ("Pipeline state changed from %s to %s:\n",gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));
/* Remember whether we are in the PLAYING state or not */
data->playing = (data->playbin2->current_state == GST_STATE_PLAYING);
if (data->playing)
{
/* We just moved to PLAYING. Check if seeking is possible */
qInfo() << "data->playing is called!!";
GstQuery *query;
gint64 start, end;
query = gst_query_new_seeking (GST_FORMAT_TIME);
if (gst_element_query (data->playbin2, query))
{
gst_query_parse_seeking (query, NULL, &data->seek_enabled, &start, &end);
if (data->seek_enabled) {
g_print ("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n",
GST_TIME_ARGS (start), GST_TIME_ARGS (end));
}
else
{
g_print ("Seeking is DISABLED for this stream.\n");
}
}
else
{
g_printerr ("Seeking query failed.");
}
gst_query_unref (query);
}
}
} break;
default:
/* We should not reach here */
g_printerr ("Unexpected message received.\n");
break;
}
gst_message_unref (msg);
}
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
data = new CustomData;
muteFlag = true;
/* Initialize our data structure */
memset (data, 0, sizeof (CustomData));
data->duration = GST_CLOCK_TIME_NONE;
/* Create the elements */
data->playbin2 = gst_element_factory_make ("playbin", "playbin2");
if (!data->playbin2)
{
qWarning("Not all elements could be created.\n");
return ;
}
/* Set the URI to play */
g_object_set(data->playbin2, "uri", uri.toUtf8().data(), NULL);
/* Create the GUI */
createUi(data);
/* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
bus = gst_element_get_bus (data->playbin2);
queryTimer = new QTimer;
connect(queryTimer,SIGNAL(timeout()),this,SLOT(slotTimerout()));
}
void Widget::slotTimerout()
{
GstMessage *msg;
msg = gst_bus_timed_pop_filtered (data->bus, GST_CLOCK_TIME_NONE,
GstMessageType(GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_DURATION));
/* Parse message */
if (msg != NULL)
{
qInfo() << "msg != NULL";
handle_message (data, msg);
}
refresh_ui(data);
expose_cb(displayWnd,NULL,data);
analyze_streams(data);
}
Widget::~Widget()
{
}
void Widget::closeEvent(QCloseEvent *)
{
if(queryTimer->isActive())
{
queryTimer->stop();
}
delete_event_cb(NULL,NULL,data);
/* Free resources */
gst_element_set_state (data->playbin2, GST_STATE_NULL);
gst_object_unref (data->playbin2);
if(data != NULL)
{
delete data;
data = NULL;
}
}
/* This function is called when the GUI toolkit creates the physical window that will hold the video.
* At this point we can retrieve its handler (which has a different meaning depending on the windowing system)
* and pass it to GStreamer through the XOverlay interface. */
void Widget::realize_cb(QWidget *widget, CustomData *data)
{
guintptr window_handle;
window_handle = (guintptr)(widget->winId());
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(data->playbin2),window_handle);
}
/*This funcion is called when the PLAY button is clicked!*/
void Widget::playButtonClicked(QPushButton *button, CustomData *data)
{
Q_UNUSED(button);
GstStateChangeReturn ret;
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);
QMessageBox::information(this,tr("提示"),tr("文件无法渲染!"),1);
data->playbin2 = gst_element_factory_make ("playbin", "playbin2");
realize_cb(displayWnd,data);
if (!data->playbin2)
{
qWarning("Not all elements could be created.\n");
return ;
}
return;
}
else
{
if(!queryTimer->isActive())
{
queryTimer->start(100*3);
}
}
g_object_set(G_OBJECT(data->playbin2), "volume", 50*1.0/100, NULL);
g_object_set(G_OBJECT(data->playbin2), "mute", FALSE, NULL);
}
/* This function is called when the PAUSE button is clicked */
void Widget::plauseButtonClicked(QPushButton *button, CustomData *data)
{
Q_UNUSED(button);
if(uri == "")
{
return;
}
GstStateChangeReturn ret;
ret = gst_element_set_state(data->playbin2,GST_STATE_PAUSED);
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_printerr ("Unable to set the pipeline to the plauseing state.\n");
gst_object_unref (data->playbin2);
QMessageBox::information(this,tr("提示"),tr("暂停操作失败!"),1);
data->playbin2 = gst_element_factory_make ("playbin", "playbin2");
realize_cb(displayWnd,data);
if (!data->playbin2)
{
qWarning("Not all elements could be created.\n");
return ;
}
return;
}
}
/* This function is called when the STOP button is clicked */
void Widget::stopButtonClicked(QPushButton *button, CustomData *data)
{
Q_UNUSED(button);
if(uri == "")
{
return;
}
GstStateChangeReturn ret;
if(data != NULL && data->playbin2 != NULL)
{
ret = gst_element_set_state (data->playbin2, GST_STATE_READY); ;
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_printerr ("Unable to set the pipeline to the stopping state.\n");
gst_object_unref (data->playbin2);
return;
}
else
{
startBtn->setText("播放");
}
}
}
/* This function is called when the main window is closed */
void Widget::delete_event_cb(QWidget *widget, QEvent *event, CustomData *data)
{
Q_UNUSED(widget);
Q_UNUSED(event);
if(data != NULL)
{
stopButtonClicked(NULL,data);
}
}
/* This function is called everytime the video window needs to be redrawn (due to damage/exposure,
* rescaling, etc). GStreamer takes care of this in the PAUSED and PLAYING states, otherwise,
* we simply draw a black rectangle to avoid garbage showing up. */
bool Widget::expose_cb(QWidget *widget, QEvent *eve
- 1
- 2
- 3
前往页