vrplayer: work on client timing
This commit is contained in:
parent
f5e9bc3308
commit
ad0532b1bf
@ -647,8 +647,9 @@ process_message_channel_data(struct stream *s)
|
|||||||
{
|
{
|
||||||
rv = drdynvc_data_in(s, chan_id, chan_flags, length, total_length);
|
rv = drdynvc_data_in(s, chan_id, chan_flags, length, total_length);
|
||||||
}
|
}
|
||||||
else if (chan_id == ((struct xrdp_api_data *)
|
else if ((g_api_con_trans != 0) &&
|
||||||
(g_api_con_trans->callback_data))->chan_id)
|
(chan_id == ((struct xrdp_api_data *)
|
||||||
|
(g_api_con_trans->callback_data))->chan_id))
|
||||||
{
|
{
|
||||||
LOG(10, ("process_message_channel_data length %d total_length %d "
|
LOG(10, ("process_message_channel_data length %d total_length %d "
|
||||||
"chan_flags 0x%8.8x", length, total_length, chan_flags));
|
"chan_flags 0x%8.8x", length, total_length, chan_flags));
|
||||||
|
@ -3,26 +3,25 @@
|
|||||||
|
|
||||||
#include "demuxmedia.h"
|
#include "demuxmedia.h"
|
||||||
|
|
||||||
DemuxMedia::DemuxMedia(QObject *parent, QQueue<MediaPacket *> *audioQueue,
|
DemuxMedia::DemuxMedia(QObject *parent, QQueue<MediaPacket *> *videoQueue,
|
||||||
QQueue<MediaPacket *> *videoQueue, void *channel, int stream_id) :
|
void *channel, int stream_id) : QObject(parent)
|
||||||
QObject(parent)
|
|
||||||
{
|
{
|
||||||
this->audioQueue = audioQueue;
|
|
||||||
this->videoQueue = videoQueue;
|
|
||||||
this->channel = channel;
|
this->channel = channel;
|
||||||
this->stream_id = stream_id;
|
this->stream_id = stream_id;
|
||||||
this->threadsStarted = false;
|
|
||||||
this->vcrFlag = 0;
|
this->vcrFlag = 0;
|
||||||
|
this->elapsedTime = 0;
|
||||||
|
this->la_seekPos = -1;
|
||||||
|
this->isStopped = 0;
|
||||||
|
this->pausedTime = 0;
|
||||||
|
this->videoQueue = videoQueue;
|
||||||
|
|
||||||
playAudio = new PlayAudio(NULL, audioQueue, &sendMutex, channel, 101);
|
playVideo = new PlayVideo(NULL, videoQueue, &sendMutex, channel, 101, 24);
|
||||||
playAudioThread = new QThread(this);
|
|
||||||
connect(playAudioThread, SIGNAL(started()), playAudio, SLOT(play()));
|
|
||||||
playAudio->moveToThread(playAudioThread);
|
|
||||||
|
|
||||||
playVideo = new PlayVideo(NULL, videoQueue, &sendMutex, channel, 101);
|
|
||||||
playVideoThread = new QThread(this);
|
playVideoThread = new QThread(this);
|
||||||
connect(playVideoThread, SIGNAL(started()), playVideo, SLOT(play()));
|
connect(playVideoThread, SIGNAL(started()), playVideo, SLOT(play()));
|
||||||
playVideo->moveToThread(playVideoThread);
|
playVideo->moveToThread(playVideoThread);
|
||||||
|
|
||||||
|
playVideoThread->start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemuxMedia::setVcrOp(int op)
|
void DemuxMedia::setVcrOp(int op)
|
||||||
@ -30,12 +29,6 @@ void DemuxMedia::setVcrOp(int op)
|
|||||||
vcrMutex.lock();
|
vcrMutex.lock();
|
||||||
vcrFlag = op;
|
vcrFlag = op;
|
||||||
vcrMutex.unlock();
|
vcrMutex.unlock();
|
||||||
|
|
||||||
if (playVideo)
|
|
||||||
playVideo->setVcrOp(op);
|
|
||||||
|
|
||||||
if (playAudio)
|
|
||||||
playAudio->setVcrOp(op);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemuxMedia::startDemuxing()
|
void DemuxMedia::startDemuxing()
|
||||||
@ -44,9 +37,6 @@ void DemuxMedia::startDemuxing()
|
|||||||
int is_video_frame;
|
int is_video_frame;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if ((audioQueue == NULL) || (videoQueue == NULL))
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
vcrMutex.lock();
|
vcrMutex.lock();
|
||||||
@ -55,18 +45,40 @@ void DemuxMedia::startDemuxing()
|
|||||||
case VCR_PLAY:
|
case VCR_PLAY:
|
||||||
vcrFlag = 0;
|
vcrFlag = 0;
|
||||||
vcrMutex.unlock();
|
vcrMutex.unlock();
|
||||||
|
if (pausedTime)
|
||||||
|
{
|
||||||
|
elapsedTime = av_gettime() - pausedTime;
|
||||||
|
pausedTime = 0;
|
||||||
|
}
|
||||||
|
isStopped = false;
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VCR_PAUSE:
|
case VCR_PAUSE:
|
||||||
vcrMutex.unlock();
|
vcrMutex.unlock();
|
||||||
|
if (!pausedTime)
|
||||||
|
{
|
||||||
|
/* save amount of video played so far */
|
||||||
|
pausedTime = av_gettime() - elapsedTime;
|
||||||
|
}
|
||||||
usleep(1000 * 100);
|
usleep(1000 * 100);
|
||||||
|
isStopped = false;
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VCR_STOP:
|
case VCR_STOP:
|
||||||
vcrMutex.unlock();
|
vcrMutex.unlock();
|
||||||
usleep(1000 * 100);
|
|
||||||
|
if (isStopped)
|
||||||
|
{
|
||||||
|
usleep(1000 * 100);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
elapsedTime = 0;
|
||||||
|
pausedTime = 0;
|
||||||
|
la_seekPos = -1;
|
||||||
|
xrdpvr_seek_media(0, 0);
|
||||||
|
isStopped = true;
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -75,14 +87,6 @@ void DemuxMedia::startDemuxing()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((audioQueue->count() >= 20) || (videoQueue->count() >= 20))
|
|
||||||
{
|
|
||||||
if (!threadsStarted)
|
|
||||||
startAudioVideoThreads();
|
|
||||||
|
|
||||||
usleep(1000 * 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaPkt = new MediaPacket;
|
mediaPkt = new MediaPacket;
|
||||||
rv = xrdpvr_get_frame(&mediaPkt->av_pkt,
|
rv = xrdpvr_get_frame(&mediaPkt->av_pkt,
|
||||||
&is_video_frame,
|
&is_video_frame,
|
||||||
@ -91,31 +95,61 @@ void DemuxMedia::startDemuxing()
|
|||||||
{
|
{
|
||||||
/* looks like we reached end of file */
|
/* looks like we reached end of file */
|
||||||
delete mediaPkt;
|
delete mediaPkt;
|
||||||
playVideo->onMediaRestarted();
|
|
||||||
usleep(1000 * 100);
|
usleep(1000 * 100);
|
||||||
xrdpvr_seek_media(0, 0);
|
xrdpvr_seek_media(0, 0);
|
||||||
|
this->elapsedTime = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_video_frame)
|
if (is_video_frame)
|
||||||
|
{
|
||||||
|
sendMutex.lock();
|
||||||
|
#if 1
|
||||||
videoQueue->enqueue(mediaPkt);
|
videoQueue->enqueue(mediaPkt);
|
||||||
|
#else
|
||||||
|
send_video_pkt(channel, stream_id, mediaPkt->av_pkt);
|
||||||
|
delete mediaPkt;
|
||||||
|
#endif
|
||||||
|
sendMutex.unlock();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
audioQueue->enqueue(mediaPkt);
|
{
|
||||||
|
int frame;
|
||||||
|
sendMutex.lock();
|
||||||
|
send_audio_pkt(channel, stream_id, mediaPkt->av_pkt);
|
||||||
|
sendMutex.unlock();
|
||||||
|
xrdpvr_read_ack(channel, &frame);
|
||||||
|
delete mediaPkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMediaPos();
|
||||||
|
if (elapsedTime == 0)
|
||||||
|
{
|
||||||
|
elapsedTime = av_gettime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* time elapsed in 1/100th sec units since play started */
|
||||||
|
emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
|
||||||
|
|
||||||
|
|
||||||
} /* end while (1) */
|
} /* end while (1) */
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayVideo * DemuxMedia::getPlayVideoInstance()
|
void DemuxMedia::onMediaSeek(int value)
|
||||||
{
|
{
|
||||||
return this->playVideo;
|
posMutex.lock();
|
||||||
|
la_seekPos = value;
|
||||||
|
posMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemuxMedia::startAudioVideoThreads()
|
void DemuxMedia::updateMediaPos()
|
||||||
{
|
{
|
||||||
if (threadsStarted)
|
posMutex.lock();
|
||||||
return;
|
if (la_seekPos >= 0)
|
||||||
|
{
|
||||||
playVideoThread->start();
|
xrdpvr_seek_media(la_seekPos, 0);
|
||||||
playAudioThread->start();
|
elapsedTime = av_gettime() - la_seekPos * 1000000;
|
||||||
threadsStarted = true;
|
la_seekPos = -1;
|
||||||
|
}
|
||||||
|
posMutex.unlock();
|
||||||
}
|
}
|
||||||
|
@ -37,33 +37,39 @@ class DemuxMedia : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DemuxMedia(QObject *parent = 0, QQueue<MediaPacket *> *audioQueue = 0,
|
explicit DemuxMedia(QObject *parent = 0, QQueue<MediaPacket *> *videoQueue = 0,
|
||||||
QQueue<MediaPacket *> *videoQueue = 0, void *channel = 0, int stream_id = 101);
|
void *channel = 0, int stream_id = 101);
|
||||||
|
|
||||||
void setVcrOp(int op);
|
void setVcrOp(int op);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void startDemuxing();
|
void startDemuxing();
|
||||||
PlayVideo *getPlayVideoInstance();
|
void onMediaSeek(int value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QQueue<MediaPacket *> *audioQueue;
|
QMutex vcrMutex;
|
||||||
|
int vcrFlag;
|
||||||
|
void *channel;
|
||||||
|
int stream_id;
|
||||||
|
QMutex sendMutex;
|
||||||
|
QMutex posMutex;
|
||||||
|
int64_t elapsedTime; /* elapsed time in usecs since play started */
|
||||||
|
int64_t pausedTime; /* time at which stream was paused */
|
||||||
|
int64_t la_seekPos; /* locked access; must hold posMutex */
|
||||||
|
bool isStopped;
|
||||||
|
|
||||||
QQueue<MediaPacket *> *videoQueue;
|
QQueue<MediaPacket *> *videoQueue;
|
||||||
QMutex vcrMutex;
|
|
||||||
int vcrFlag;
|
|
||||||
void *channel;
|
|
||||||
PlayVideo *playVideo;
|
PlayVideo *playVideo;
|
||||||
QThread *playVideoThread;
|
QThread *playVideoThread;
|
||||||
PlayAudio *playAudio;
|
|
||||||
QThread *playAudioThread;
|
|
||||||
int stream_id;
|
|
||||||
bool threadsStarted;
|
|
||||||
QMutex sendMutex;
|
|
||||||
|
|
||||||
void startAudioVideoThreads();
|
void updateMediaPos();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void onMediaRestarted();
|
void onMediaRestarted();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void onElapsedtime(int val); /* in hundredth of a sec */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEMUXMEDIA_H
|
#endif // DEMUXMEDIA_H
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
#include <QtGui/QApplication>
|
#include <QtGui/QApplication>
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
@ -66,8 +66,8 @@ MainWindow::~MainWindow()
|
|||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
|
|
||||||
if (moveResizeTimer)
|
//if (moveResizeTimer)
|
||||||
delete moveResizeTimer;
|
// delete moveResizeTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::closeEvent(QCloseEvent *event)
|
void MainWindow::closeEvent(QCloseEvent *event)
|
||||||
@ -86,50 +86,50 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
|||||||
|
|
||||||
void MainWindow::resizeEvent(QResizeEvent *)
|
void MainWindow::resizeEvent(QResizeEvent *)
|
||||||
{
|
{
|
||||||
if (vcrFlag != VCR_PLAY)
|
//if (vcrFlag != VCR_PLAY)
|
||||||
{
|
{
|
||||||
QRect rect;
|
QRect rect;
|
||||||
|
|
||||||
getVdoGeometry(&rect);
|
getVdoGeometry(&rect);
|
||||||
interface->sendGeometry(rect);
|
interface->sendGeometry(rect);
|
||||||
return;
|
//return;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface->setVcrOp(VCR_PAUSE);
|
//interface->setVcrOp(VCR_PAUSE);
|
||||||
vcrFlag = VCR_PAUSE;
|
//vcrFlag = VCR_PAUSE;
|
||||||
|
|
||||||
if (!moveResizeTimer)
|
//if (!moveResizeTimer)
|
||||||
{
|
//{
|
||||||
moveResizeTimer = new QTimer;
|
// moveResizeTimer = new QTimer;
|
||||||
connect(moveResizeTimer, SIGNAL(timeout()),
|
// connect(moveResizeTimer, SIGNAL(timeout()),
|
||||||
this, SLOT(onMoveCompleted()));
|
// this, SLOT(onMoveCompleted()));
|
||||||
}
|
//}
|
||||||
lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
|
//lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
|
||||||
moveResizeTimer->start(1000);
|
//moveResizeTimer->start(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::moveEvent(QMoveEvent *)
|
void MainWindow::moveEvent(QMoveEvent *)
|
||||||
{
|
{
|
||||||
if (vcrFlag != VCR_PLAY)
|
//if (vcrFlag != VCR_PLAY)
|
||||||
{
|
{
|
||||||
QRect rect;
|
QRect rect;
|
||||||
|
|
||||||
getVdoGeometry(&rect);
|
getVdoGeometry(&rect);
|
||||||
interface->sendGeometry(rect);
|
interface->sendGeometry(rect);
|
||||||
return;
|
//return;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface->setVcrOp(VCR_PAUSE);
|
//interface->setVcrOp(VCR_PAUSE);
|
||||||
vcrFlag = VCR_PAUSE;
|
//vcrFlag = VCR_PAUSE;
|
||||||
|
|
||||||
if (!moveResizeTimer)
|
//if (!moveResizeTimer)
|
||||||
{
|
//{
|
||||||
moveResizeTimer = new QTimer;
|
// moveResizeTimer = new QTimer;
|
||||||
connect(moveResizeTimer, SIGNAL(timeout()),
|
// connect(moveResizeTimer, SIGNAL(timeout()),
|
||||||
this, SLOT(onMoveCompleted()));
|
// this, SLOT(onMoveCompleted()));
|
||||||
}
|
//}
|
||||||
lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
|
//lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
|
||||||
moveResizeTimer->start(1000);
|
//moveResizeTimer->start(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onVolSliderValueChanged(int value)
|
void MainWindow::onVolSliderValueChanged(int value)
|
||||||
@ -253,10 +253,17 @@ void MainWindow::openMediaFile()
|
|||||||
|
|
||||||
if (filename.length() == 0)
|
if (filename.length() == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* no previous selection - open user's home folder TODO */
|
/* no previous selection - open user's home folder TODO */
|
||||||
// TODO filename = QFileDialog::getOpenFileName(this, "Select Media File", "/");
|
// TODO filename = QFileDialog::getOpenFileName(this, "Select Media File", "/");
|
||||||
|
//filename = QFileDialog::getOpenFileName(this, "Select Media File",
|
||||||
|
// QDir::currentPath());
|
||||||
|
|
||||||
filename = QFileDialog::getOpenFileName(this, "Select Media File",
|
filename = QFileDialog::getOpenFileName(this, "Select Media File",
|
||||||
QDir::currentPath());
|
QDir::currentPath(),
|
||||||
|
"Media *.mov *.mp4 *.mkv (*.mov *.mp4 *.mkv)");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -302,13 +309,19 @@ void MainWindow::clearDisplay()
|
|||||||
void MainWindow::on_actionOpen_Media_File_triggered()
|
void MainWindow::on_actionOpen_Media_File_triggered()
|
||||||
{
|
{
|
||||||
if (vcrFlag != 0)
|
if (vcrFlag != 0)
|
||||||
|
{
|
||||||
onBtnStopClicked(true);
|
onBtnStopClicked(true);
|
||||||
|
}
|
||||||
|
|
||||||
/* if media was specified on cmd line, use it just once */
|
/* if media was specified on cmd line, use it just once */
|
||||||
if (gotMediaOnCmdline)
|
if (gotMediaOnCmdline)
|
||||||
|
{
|
||||||
gotMediaOnCmdline = false;
|
gotMediaOnCmdline = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
openMediaFile();
|
openMediaFile();
|
||||||
|
}
|
||||||
|
|
||||||
if (filename.length() == 0)
|
if (filename.length() == 0)
|
||||||
{
|
{
|
||||||
@ -327,10 +340,10 @@ void MainWindow::on_actionOpen_Media_File_triggered()
|
|||||||
interface->initRemoteClient();
|
interface->initRemoteClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
playVideo = interface->getPlayVideoInstance();
|
demuxMedia = interface->getDemuxMediaInstance();
|
||||||
if (playVideo)
|
if (demuxMedia)
|
||||||
{
|
{
|
||||||
connect(playVideo, SIGNAL(onElapsedtime(int)),
|
connect(demuxMedia, SIGNAL(onElapsedtime(int)),
|
||||||
this, SLOT(onElapsedTime(int)));
|
this, SLOT(onElapsedTime(int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +368,7 @@ void MainWindow::onBtnPlayClicked(bool)
|
|||||||
{
|
{
|
||||||
if (vcrFlag == 0)
|
if (vcrFlag == 0)
|
||||||
{
|
{
|
||||||
/* first time play button has been clicked */
|
/* first time play button3 has been clicked */
|
||||||
on_actionOpen_Media_File_triggered();
|
on_actionOpen_Media_File_triggered();
|
||||||
btnPlay->setText("Pause");
|
btnPlay->setText("Pause");
|
||||||
vcrFlag = VCR_PLAY;
|
vcrFlag = VCR_PLAY;
|
||||||
@ -385,8 +398,8 @@ void MainWindow::onBtnPlayClicked(bool)
|
|||||||
|
|
||||||
void MainWindow::onBtnRewindClicked(bool)
|
void MainWindow::onBtnRewindClicked(bool)
|
||||||
{
|
{
|
||||||
if (playVideo)
|
//if (playVideo)
|
||||||
playVideo->onMediaSeek(0);
|
// playVideo->onMediaSeek(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onBtnStopClicked(bool)
|
void MainWindow::onBtnStopClicked(bool)
|
||||||
@ -401,6 +414,8 @@ void MainWindow::onBtnStopClicked(bool)
|
|||||||
|
|
||||||
/* clear screen by filling it with black */
|
/* clear screen by filling it with black */
|
||||||
clearDisplay();
|
clearDisplay();
|
||||||
|
|
||||||
|
btnPlay->setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onMediaDurationInSeconds(int duration)
|
void MainWindow::onMediaDurationInSeconds(int duration)
|
||||||
@ -479,8 +494,10 @@ void MainWindow::onSliderValueChanged(int value)
|
|||||||
if (acceptSliderMove)
|
if (acceptSliderMove)
|
||||||
{
|
{
|
||||||
acceptSliderMove = false;
|
acceptSliderMove = false;
|
||||||
if (playVideo)
|
if (demuxMedia != NULL)
|
||||||
playVideo->onMediaSeek(value / 100);
|
{
|
||||||
|
demuxMedia->onMediaSeek(value / 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,6 +520,7 @@ void MainWindow::onSliderActionTriggered(int action)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// not called
|
||||||
void MainWindow::onMoveCompleted()
|
void MainWindow::onMoveCompleted()
|
||||||
{
|
{
|
||||||
QRect rect;
|
QRect rect;
|
||||||
@ -512,7 +530,7 @@ void MainWindow::onMoveCompleted()
|
|||||||
|
|
||||||
interface->setVcrOp(VCR_PLAY);
|
interface->setVcrOp(VCR_PLAY);
|
||||||
vcrFlag = VCR_PLAY;
|
vcrFlag = VCR_PLAY;
|
||||||
moveResizeTimer->stop();
|
//moveResizeTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionAbout_triggered()
|
void MainWindow::on_actionAbout_triggered()
|
||||||
|
@ -111,7 +111,8 @@ private:
|
|||||||
|
|
||||||
/* private stuff */
|
/* private stuff */
|
||||||
OurInterface *interface;
|
OurInterface *interface;
|
||||||
PlayVideo *playVideo;
|
//PlayVideo *playVideo;
|
||||||
|
DemuxMedia *demuxMedia;
|
||||||
QString filename;
|
QString filename;
|
||||||
bool oneTimeInitSuccess;
|
bool oneTimeInitSuccess;
|
||||||
bool remoteClientInited;
|
bool remoteClientInited;
|
||||||
|
@ -60,11 +60,11 @@ void OurInterface::initRemoteClient()
|
|||||||
/* LK_TODO this needs to be undone in deinitRemoteClient() */
|
/* LK_TODO this needs to be undone in deinitRemoteClient() */
|
||||||
if (!demuxMedia)
|
if (!demuxMedia)
|
||||||
{
|
{
|
||||||
demuxMedia = new DemuxMedia(NULL, &audioQueue, &videoQueue, channel, stream_id);
|
demuxMedia = new DemuxMedia(NULL, &videoQueue, channel, stream_id);
|
||||||
demuxMediaThread = new QThread(this);
|
demuxMediaThread = new QThread(this);
|
||||||
connect(demuxMediaThread, SIGNAL(started()), demuxMedia, SLOT(startDemuxing()));
|
connect(demuxMediaThread, SIGNAL(started()), demuxMedia, SLOT(startDemuxing()));
|
||||||
demuxMedia->moveToThread(demuxMediaThread);
|
demuxMedia->moveToThread(demuxMediaThread);
|
||||||
playVideo = demuxMedia->getPlayVideoInstance();
|
//playVideo = demuxMedia->getPlayVideoInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,11 +216,17 @@ void OurInterface::playMedia()
|
|||||||
demuxMediaThread->start();
|
demuxMediaThread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayVideo * OurInterface::getPlayVideoInstance()
|
//PlayVideo * OurInterface::getPlayVideoInstance()
|
||||||
|
//{
|
||||||
|
// return this->playVideo;
|
||||||
|
//}
|
||||||
|
|
||||||
|
DemuxMedia * OurInterface::getDemuxMediaInstance()
|
||||||
{
|
{
|
||||||
return this->playVideo;
|
return this->demuxMedia;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OurInterface::setVcrOp(int op)
|
void OurInterface::setVcrOp(int op)
|
||||||
{
|
{
|
||||||
if (demuxMedia)
|
if (demuxMedia)
|
||||||
|
@ -40,7 +40,8 @@ public:
|
|||||||
int sendGeometry(QRect rect);
|
int sendGeometry(QRect rect);
|
||||||
void setFilename(QString filename);
|
void setFilename(QString filename);
|
||||||
void playMedia();
|
void playMedia();
|
||||||
PlayVideo *getPlayVideoInstance();
|
//PlayVideo *getPlayVideoInstance();
|
||||||
|
DemuxMedia *getDemuxMediaInstance();
|
||||||
void setVcrOp(int op);
|
void setVcrOp(int op);
|
||||||
int setVolume(int volume);
|
int setVolume(int volume);
|
||||||
|
|
||||||
@ -54,12 +55,12 @@ signals:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
/* private stuff */
|
/* private stuff */
|
||||||
QQueue<MediaPacket *> audioQueue;
|
|
||||||
QQueue<MediaPacket *> videoQueue;
|
QQueue<MediaPacket *> videoQueue;
|
||||||
|
|
||||||
DemuxMedia *demuxMedia;
|
DemuxMedia *demuxMedia;
|
||||||
QThread *demuxMediaThread;
|
QThread *demuxMediaThread;
|
||||||
PlayVideo *playVideo;
|
//PlayVideo *playVideo;
|
||||||
QString filename;
|
QString filename;
|
||||||
void *channel;
|
void *channel;
|
||||||
int stream_id;
|
int stream_id;
|
||||||
|
@ -58,11 +58,11 @@ label1:
|
|||||||
if (audioQueue->isEmpty())
|
if (audioQueue->isEmpty())
|
||||||
{
|
{
|
||||||
qDebug() << "PlayAudio::play: GOT EMPTY";
|
qDebug() << "PlayAudio::play: GOT EMPTY";
|
||||||
usleep(1000 * 100);
|
usleep(1000 * 10);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("")
|
printf("");
|
||||||
pkt = audioQueue->dequeue();
|
pkt = audioQueue->dequeue();
|
||||||
sendMutex->lock();
|
sendMutex->lock();
|
||||||
send_audio_pkt(channel, stream_id, pkt->av_pkt);
|
send_audio_pkt(channel, stream_id, pkt->av_pkt);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "playvideo.h"
|
#include "playvideo.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -8,182 +9,58 @@ PlayVideo::PlayVideo(QObject *parent,
|
|||||||
QQueue<MediaPacket *> *videoQueue,
|
QQueue<MediaPacket *> *videoQueue,
|
||||||
QMutex *sendMutex,
|
QMutex *sendMutex,
|
||||||
void *channel,
|
void *channel,
|
||||||
int stream_id) :
|
int stream_id, int fps) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
this->videoQueue = videoQueue;
|
this->videoQueue = videoQueue;
|
||||||
this->channel = channel;
|
this->channel = channel;
|
||||||
this->sendMutex = sendMutex;
|
this->sendMutex = sendMutex;
|
||||||
this->stream_id = stream_id;
|
this->stream_id = stream_id;
|
||||||
elapsedTime = 0;
|
this->fps = fps;
|
||||||
pausedTime = 0;
|
}
|
||||||
la_seekPos = -1;
|
|
||||||
vcrFlag = 0;
|
/**
|
||||||
isStopped = false;
|
******************************************************************************/
|
||||||
|
static int
|
||||||
|
get_mstime(void)
|
||||||
|
{
|
||||||
|
struct timeval tp;
|
||||||
|
|
||||||
|
gettimeofday(&tp, 0);
|
||||||
|
return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayVideo::play()
|
void PlayVideo::play()
|
||||||
{
|
{
|
||||||
MediaPacket *pkt;
|
MediaPacket *pkt;
|
||||||
int usl;
|
int now_time;
|
||||||
|
int sleep_time;
|
||||||
|
int last_display_time;
|
||||||
|
|
||||||
|
last_display_time = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
vcrMutex.lock();
|
sendMutex->lock();
|
||||||
switch (vcrFlag)
|
|
||||||
{
|
|
||||||
case VCR_PLAY:
|
|
||||||
vcrFlag = 0;
|
|
||||||
vcrMutex.unlock();
|
|
||||||
if (pausedTime)
|
|
||||||
{
|
|
||||||
elapsedTime = av_gettime() - pausedTime;
|
|
||||||
pausedTime = 0;
|
|
||||||
}
|
|
||||||
isStopped = false;
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VCR_PAUSE:
|
|
||||||
vcrMutex.unlock();
|
|
||||||
if (!pausedTime)
|
|
||||||
{
|
|
||||||
/* save amount of video played so far */
|
|
||||||
pausedTime = av_gettime() - elapsedTime;
|
|
||||||
}
|
|
||||||
usleep(1000 * 100);
|
|
||||||
isStopped = false;
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VCR_STOP:
|
|
||||||
vcrMutex.unlock();
|
|
||||||
if (isStopped)
|
|
||||||
{
|
|
||||||
usleep(1000 * 100);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
clearVideoQ();
|
|
||||||
elapsedTime = 0;
|
|
||||||
pausedTime = 0;
|
|
||||||
la_seekPos = -1;
|
|
||||||
xrdpvr_seek_media(0, 0);
|
|
||||||
isStopped = true;
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
vcrMutex.unlock();
|
|
||||||
goto label1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
label1:
|
|
||||||
|
|
||||||
printf("video\n");
|
|
||||||
if (videoQueue->isEmpty())
|
if (videoQueue->isEmpty())
|
||||||
{
|
{
|
||||||
printf("---empty\n");
|
sendMutex->unlock();
|
||||||
usleep(1000);
|
usleep(10 * 1000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pkt = videoQueue->dequeue();
|
pkt = videoQueue->dequeue();
|
||||||
sendMutex->lock();
|
|
||||||
send_video_pkt(channel, stream_id, pkt->av_pkt);
|
send_video_pkt(channel, stream_id, pkt->av_pkt);
|
||||||
sendMutex->unlock();
|
sendMutex->unlock();
|
||||||
usl = 1000; // pkt->delay_in_us;
|
now_time = get_mstime();
|
||||||
if (usl < 0)
|
sleep_time = now_time - last_display_time;
|
||||||
|
if (sleep_time > (1000 / fps))
|
||||||
{
|
{
|
||||||
usl = 0;
|
sleep_time = (1000 / fps);
|
||||||
}
|
}
|
||||||
if (usl > 100 * 1000)
|
if (sleep_time > 0)
|
||||||
{
|
{
|
||||||
usl = 100 * 1000;
|
usleep(sleep_time * 1000);
|
||||||
}
|
}
|
||||||
usleep(usl);
|
last_display_time = now_time;
|
||||||
delete pkt;
|
|
||||||
updateMediaPos();
|
|
||||||
if (elapsedTime == 0)
|
|
||||||
elapsedTime = av_gettime();
|
|
||||||
|
|
||||||
/* time elapsed in 1/100th sec units since play started */
|
|
||||||
emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayVideo::onMediaRestarted()
|
|
||||||
{
|
|
||||||
elapsedTime = av_gettime();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayVideo::onMediaSeek(int value)
|
|
||||||
{
|
|
||||||
posMutex.lock();
|
|
||||||
la_seekPos = value;
|
|
||||||
posMutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayVideo::updateMediaPos()
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if (elapsedTime == 0)
|
|
||||||
elapsedTime = av_gettime();
|
|
||||||
|
|
||||||
/* time elapsed in 1/100th sec units since play started */
|
|
||||||
emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
posMutex.lock();
|
|
||||||
if (la_seekPos >= 0)
|
|
||||||
{
|
|
||||||
//qDebug() << "seeking to" << la_seekPos;
|
|
||||||
xrdpvr_seek_media(la_seekPos, 0);
|
|
||||||
elapsedTime = av_gettime() - la_seekPos * 1000000;
|
|
||||||
la_seekPos = -1;
|
|
||||||
}
|
|
||||||
posMutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayVideo::setVcrOp(int op)
|
|
||||||
{
|
|
||||||
vcrMutex.lock();
|
|
||||||
this->vcrFlag = op;
|
|
||||||
vcrMutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayVideo::clearVideoQ()
|
|
||||||
{
|
|
||||||
MediaPacket *pkt;
|
|
||||||
|
|
||||||
while (!videoQueue->isEmpty())
|
|
||||||
{
|
|
||||||
pkt = videoQueue->dequeue();
|
|
||||||
av_free_packet((AVPacket *) pkt->av_pkt);
|
|
||||||
delete pkt;
|
delete pkt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void DecoderThread::updateSlider()
|
|
||||||
{
|
|
||||||
if (elapsedTime == 0)
|
|
||||||
elapsedTime = av_gettime();
|
|
||||||
|
|
||||||
/* time elapsed in 1/100th sec units since play started */
|
|
||||||
emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
|
|
||||||
|
|
||||||
mutex.lock();
|
|
||||||
if (la_seekPos >= 0)
|
|
||||||
{
|
|
||||||
//qDebug() << "seeking to" << la_seekPos;
|
|
||||||
//audioTimer->stop();
|
|
||||||
//videoTimer->stop();
|
|
||||||
xrdpvr_seek_media(la_seekPos, 0);
|
|
||||||
elapsedTime = av_gettime() - la_seekPos * 1000000;
|
|
||||||
//audioTimer->start(10);
|
|
||||||
//videoTimer->start(10);
|
|
||||||
la_seekPos = -1;
|
|
||||||
}
|
|
||||||
mutex.unlock();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -39,34 +39,36 @@ public:
|
|||||||
QQueue<MediaPacket *> *videoQueue = 0,
|
QQueue<MediaPacket *> *videoQueue = 0,
|
||||||
QMutex *sendMutex = 0,
|
QMutex *sendMutex = 0,
|
||||||
void *channel = 0,
|
void *channel = 0,
|
||||||
int stream_id = 101);
|
int stream_id = 101,
|
||||||
|
int fps = 24);
|
||||||
|
|
||||||
void onMediaSeek(int value);
|
//void onMediaSeek(int value);
|
||||||
void setVcrOp(int op);
|
//void setVcrOp(int op);
|
||||||
void onMediaRestarted();
|
//void onMediaRestarted();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void play();
|
void play();
|
||||||
|
|
||||||
signals:
|
//signals:
|
||||||
void onElapsedtime(int val); /* in hundredth of a sec */
|
// void onElapsedtime(int val); /* in hundredth of a sec */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QQueue<MediaPacket *> *videoQueue;
|
QQueue<MediaPacket *> *videoQueue;
|
||||||
|
|
||||||
int vcrFlag;
|
// int vcrFlag;
|
||||||
QMutex vcrMutex;
|
// QMutex vcrMutex;
|
||||||
QMutex *sendMutex;
|
QMutex *sendMutex;
|
||||||
QMutex posMutex;
|
// QMutex posMutex;
|
||||||
int64_t la_seekPos; /* locked access; must hold posMutex */
|
// int64_t la_seekPos; /* locked access; must hold posMutex */
|
||||||
void *channel;
|
void *channel;
|
||||||
int stream_id;
|
int stream_id;
|
||||||
int64_t elapsedTime; /* elapsed time in usecs since play started */
|
int fps;
|
||||||
int64_t pausedTime; /* time at which stream was paused */
|
// int64_t elapsedTime; /* elapsed time in usecs since play started */
|
||||||
bool isStopped;
|
// int64_t pausedTime; /* time at which stream was paused */
|
||||||
|
// bool isStopped;
|
||||||
|
|
||||||
void updateMediaPos();
|
// void updateMediaPos();
|
||||||
void clearVideoQ();
|
// void clearVideoQ();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PLAYVIDEO_H
|
#endif // PLAYVIDEO_H
|
||||||
|
@ -222,7 +222,7 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
/* print media info to standard out */
|
/* print media info to standard out */
|
||||||
av_dump_format(g_psi.p_format_ctx, 0, filename, 0);
|
av_dump_format(g_psi.p_format_ctx, 0, filename, 0);
|
||||||
#endif
|
#endif
|
||||||
@ -231,13 +231,15 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
|
|||||||
for (i = 0; i < g_psi.p_format_ctx->nb_streams; i++)
|
for (i = 0; i < g_psi.p_format_ctx->nb_streams; i++)
|
||||||
{
|
{
|
||||||
if (g_psi.p_format_ctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO &&
|
if (g_psi.p_format_ctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO &&
|
||||||
g_video_index < 0)
|
g_psi.p_format_ctx->streams[i]->codec->codec_id == CODEC_ID_H264 &&
|
||||||
|
g_video_index < 0)
|
||||||
{
|
{
|
||||||
g_video_index = i;
|
g_video_index = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_psi.p_format_ctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO &&
|
if (g_psi.p_format_ctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO &&
|
||||||
g_audio_index < 0)
|
g_psi.p_format_ctx->streams[i]->codec->codec_id == CODEC_ID_AAC &&
|
||||||
|
g_audio_index < 0)
|
||||||
{
|
{
|
||||||
g_audio_index = i;
|
g_audio_index = i;
|
||||||
}
|
}
|
||||||
@ -468,7 +470,7 @@ xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audioTim
|
|||||||
AVBitStreamFilterContext *bsfc;
|
AVBitStreamFilterContext *bsfc;
|
||||||
AVPacket new_pkt;
|
AVPacket new_pkt;
|
||||||
|
|
||||||
printf("xrdpvr_play_frame:\n");
|
//printf("xrdpvr_play_frame:\n");
|
||||||
|
|
||||||
if (av_read_frame(g_psi.p_format_ctx, &av_pkt) < 0)
|
if (av_read_frame(g_psi.p_format_ctx, &av_pkt) < 0)
|
||||||
{
|
{
|
||||||
@ -726,7 +728,7 @@ xrdpvr_send_video_data(void *channel, uint32_t stream_id, uint32_t data_len, uin
|
|||||||
int rv;
|
int rv;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
printf("xrdpvr_send_video_data:\n");
|
//printf("xrdpvr_send_video_data:\n");
|
||||||
stream_new(s, MAX_PDU_SIZE + data_len);
|
stream_new(s, MAX_PDU_SIZE + data_len);
|
||||||
|
|
||||||
stream_ins_u32_le(s, 0); /* number of bytes to follow */
|
stream_ins_u32_le(s, 0); /* number of bytes to follow */
|
||||||
@ -771,7 +773,7 @@ xrdpvr_send_audio_data(void *channel, uint32_t stream_id, uint32_t data_len, uin
|
|||||||
int rv;
|
int rv;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
printf("xrdpvr_send_audio_data:\n");
|
//printf("xrdpvr_send_audio_data:\n");
|
||||||
stream_new(s, MAX_PDU_SIZE + data_len);
|
stream_new(s, MAX_PDU_SIZE + data_len);
|
||||||
|
|
||||||
stream_ins_u32_le(s, 0); /* number of bytes to follow */
|
stream_ins_u32_le(s, 0); /* number of bytes to follow */
|
||||||
@ -791,12 +793,6 @@ xrdpvr_send_audio_data(void *channel, uint32_t stream_id, uint32_t data_len, uin
|
|||||||
rv = xrdpvr_write_to_client(channel, s);
|
rv = xrdpvr_write_to_client(channel, s);
|
||||||
stream_free(s);
|
stream_free(s);
|
||||||
|
|
||||||
// read ack back
|
|
||||||
stream_new(s, MAX_PDU_SIZE);
|
|
||||||
xrdpvr_read_from_client(channel, s, 4, 1000);
|
|
||||||
//hexdump(s->data, s->p - s->data);
|
|
||||||
stream_free(s);
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,3 +1003,16 @@ xrdpvr_send_init(void *channel)
|
|||||||
stream_free(s);
|
stream_free(s);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xrdpvr_read_ack(void *channel, int *frame)
|
||||||
|
{
|
||||||
|
STREAM *s;
|
||||||
|
|
||||||
|
stream_new(s, MAX_PDU_SIZE);
|
||||||
|
xrdpvr_read_from_client(channel, s, 4, 1000);
|
||||||
|
s->p = s->data;
|
||||||
|
stream_ext_u32_le(s, *frame);
|
||||||
|
stream_free(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -48,6 +48,7 @@ int send_audio_pkt(void *channel, int stream_id, void *pkt_p);
|
|||||||
int send_video_pkt(void *channel, int stream_id, void *pkt_p);
|
int send_video_pkt(void *channel, int stream_id, void *pkt_p);
|
||||||
int xrdpvr_set_volume(void *channel, int volume);
|
int xrdpvr_set_volume(void *channel, int volume);
|
||||||
int xrdpvr_send_init(void *channel);
|
int xrdpvr_send_init(void *channel);
|
||||||
|
int xrdpvr_read_ack(void *channel, int *frame);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user