vrplayer: work on client timing

ulab-next
Jay Sorg 11 years ago
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,19 +45,41 @@ 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();
if (isStopped)
{
usleep(1000 * 100); usleep(1000 * 100);
continue; continue;
}
elapsedTime = 0;
pausedTime = 0;
la_seekPos = -1;
xrdpvr_seek_media(0, 0);
isStopped = true;
continue;
break; break;
default: default:
@ -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;
QQueue<MediaPacket *> *videoQueue;
QMutex vcrMutex; QMutex vcrMutex;
int vcrFlag; int vcrFlag;
void *channel; void *channel;
PlayVideo *playVideo;
QThread *playVideoThread;
PlayAudio *playAudio;
QThread *playAudioThread;
int stream_id; int stream_id;
bool threadsStarted;
QMutex sendMutex; 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;
PlayVideo *playVideo;
QThread *playVideoThread;
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;
} }
void PlayVideo::play() /**
******************************************************************************/
static int
get_mstime(void)
{ {
MediaPacket *pkt; struct timeval tp;
int usl;
while (1) gettimeofday(&tp, 0);
{ return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
vcrMutex.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: void PlayVideo::play()
vcrMutex.unlock();
if (!pausedTime)
{ {
/* save amount of video played so far */ MediaPacket *pkt;
pausedTime = av_gettime() - elapsedTime; int now_time;
} int sleep_time;
usleep(1000 * 100); int last_display_time;
isStopped = false;
continue;
break;
case VCR_STOP: last_display_time = 0;
vcrMutex.unlock(); while (1)
if (isStopped)
{ {
usleep(1000 * 100); sendMutex->lock();
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; 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;
}
}
#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,12 +231,14 @@ 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_psi.p_format_ctx->streams[i]->codec->codec_id == CODEC_ID_H264 &&
g_video_index < 0) 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_psi.p_format_ctx->streams[i]->codec->codec_id == CODEC_ID_AAC &&
g_audio_index < 0) 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…
Cancel
Save