我已经为gstreamer创建了一个独立的类以流式传输视频。
这个类使用moveToThread()在单独的线程上运行。
我正在使用Qt5.5进行开发。
当我在主线程上发出startcommand时,Qthread启动,并且gstreamer使用g_main_loop_run
来流式传输视频。这完全正常。但是一些方式g_main_loop_run
阻塞了线程,当我从主线程发出停止视频的信号时,它不会执行gstreamer类中的槽。
请问有人能给我建议如何解决这个问题吗?我可以用其他命令替换g_main_loop_r
un或者另寻他法使用g_main_loop_quit( gloop )
。
void StreamingVideo::slotStartStream() // this slot called on start of thread from main thread
{
if( !isElementsLinked() )
{
qDebug() << " we are emitting in dummy server ";
//emit sigFailed( "elementsFailed" ); // WILL CONNECT IT WITH MAIN GUI ONXCE CODE IS FINISHED
return;
}
gst_bus_add_watch( bus, busCall, gloop );
gst_object_unref( bus );
//proper adding to pipe
gst_bin_add_many( GST_BIN( pipeline ), source, capsFilter, conv, videoRate, capsFilterRate,
clockDisplay, videoEnc, udpSink, NULL
);
//proper linking:
gst_element_link_many( source, capsFilter, conv, videoRate, capsFilterRate, clockDisplay, videoEnc, udpSink, NULL );
g_print("Linked all the Elements together\n");
gst_element_set_state( pipeline, GST_STATE_PLAYING );
// Iterate
g_print ("Running...\n");
emit sigStartStream(); // signal to main thread to issue success command . works fine
g_main_loop_run( gloop );
g_print ("Returned, stopping playback\n");
//gst_element_set_state (pipeline, GST_STATE_NULL);
if( g_main_loop_is_running( gloop ) )
{
qDebug() << " in g_main_loop_is_runnung emiting signal ";
emit sigStartStream();
}
if( !g_main_loop_is_running( gloop) )
{
qDebug() << "in not gmain running thread id";
qDebug() << QThread::currentThreadId();
}
}
void StreamingVideo::slotStopStream() // THIS SLOT IS NOT CALLED WHEN VIDEO RUNNING
{
qDebug() << " we are planning to stop streaming stramingVideo::slotStopStream ";
g_print ("Returned, stopping playback\n");
g_main_loop_quit( gloop );
gst_element_set_state (pipeline, GST_STATE_NULL);
// g_main_loop_quit( gloop );
releaseMemory();
emit sigStopStream(); // signal to main thread to issue message saying video has stopped.
}
// 在主线程的某个地方
threadStreaming = new QThread();
streamVideo = new StreamingVideo( "127.0.0.1"); // we will automate this ip address later on
streamVideo->moveToThread( threadStreaming );
connect( threadStreaming, SIGNAL( started() ), streamVideo, SLOT( slotStartStream() ) );
connect( streamVideo, SIGNAL( sigStopStream() ), threadStreaming, SLOT( quit() ) );
connect( streamVideo, SIGNAL( sigStopStream() ), streamVideo, SLOT(deleteLater() ) );
connect( threadStreaming, SIGNAL( finished() ), threadStreaming, SLOT(deleteLater() ) );
connect( streamVideo, SIGNAL( sigStartStream() ), this, SLOT( slotTrueStreamRun() ) );
connect( streamVideo, SIGNAL( sigStopStream() ), this, SLOT( slotFalseStreamRun() ) );
connect( this, SIGNAL( sigMopsCamStopCmd() ), streamVideo, SLOT(slotStopStream() ) );
threadStreaming->start();