diff options
| author | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2012-12-08 16:36:41 -0800 |
|---|---|---|
| committer | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2012-12-08 16:36:41 -0800 |
| commit | 4c67aad4c46be80466017b082eae8d9ffad2768d (patch) | |
| tree | a970451c336fa2078d4511ffa9660826f1517ac4 /vrplayer/decoderthread.cpp | |
| parent | 309f2225b1f6c56d954c4eaf512474a7d1303a95 (diff) | |
| download | xrdp-proprietary-4c67aad4c46be80466017b082eae8d9ffad2768d.tar.gz xrdp-proprietary-4c67aad4c46be80466017b082eae8d9ffad2768d.zip | |
o development checkin
o added vrplayer
Diffstat (limited to 'vrplayer/decoderthread.cpp')
| -rw-r--r-- | vrplayer/decoderthread.cpp | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/vrplayer/decoderthread.cpp b/vrplayer/decoderthread.cpp new file mode 100644 index 00000000..2ee7a524 --- /dev/null +++ b/vrplayer/decoderthread.cpp @@ -0,0 +1,217 @@ +#include "decoderthread.h" + +DecoderThread::DecoderThread() +{ + vsi = NULL; + channel = NULL; + geometry.setX(0); + geometry.setY(0); + geometry.setWidth(0); + geometry.setHeight(0); + stream_id = 101; + elapsedTime = 0; + la_seekPos = 0; +} + +void DecoderThread::run() +{ + int64_t start_time; + int64_t duration; + + /* TODO what happens if we get called a 2nd time while we are still running */ + + /* need a media file */ + if (filename.length() == 0) + { + emit on_decoderErrorMsg("No media file", + "Please select a media file to play"); + return; + } + + /* connect to remote client */ + if (openVirtualChannel()) + return; + + vsi = (VideoStateInfo *) av_mallocz(sizeof(VideoStateInfo)); + if (vsi == NULL) + { + emit on_decoderErrorMsg("Resource error", + "Memory allocation failed, system out of memory"); + return; + } + + /* register all formats/codecs */ + av_register_all(); + + if (sendMetadataFile()) + return; + + if (sendVideoFormat()) + return; + + if (sendAudioFormat()) + return; + + if (sendGeometry()) + return; + + xrdpvr_play_media(channel, 101, filename.toAscii().data()); + + xrdpvr_get_media_duration(&start_time, &duration); + emit on_mediaDurationInSeconds(duration); + + qDebug() << "start_time=" << start_time << " duration=" << duration; + + while (xrdpvr_play_frame(channel, 101) == 0) + { + if (elapsedTime == 0) + elapsedTime = av_gettime(); + + /* time elapsed in 1/100th sec units since play started */ + emit on_elapsedtime((av_gettime() - elapsedTime) / 10000); + + mutex.lock(); + if (la_seekPos) + { + qDebug() << "seeking to" << la_seekPos; + xrdpvr_seek_media(la_seekPos, 0); + elapsedTime = av_gettime() - la_seekPos * 1000000; + la_seekPos = 0; + } + mutex.unlock(); + } + + /* perform clean up */ + xrdpvr_deinit_player(channel, 101); + + /* clean up resources */ + closeVirtualChannel(); + if (vsi) + av_free(vsi); +} + +void DecoderThread::on_geometryChanged(int x, int y, int width, int height) +{ + geometry.setX(x); + geometry.setY(y); + geometry.setWidth(width); + geometry.setHeight(height); + +#if 0 + qDebug() << "decoderThread:signal" << + "" << geometry.x() << + "" << geometry.y() << + "" << geometry.width() << + "" << geometry.height(); +#endif + + if (channel) + { + xrdpvr_set_geometry(channel, 101, geometry.x(), geometry.y(), + geometry.width(), geometry.height()); + } +} + +void DecoderThread::on_mediaSeek(int value) +{ + mutex.lock(); + la_seekPos = value; + mutex.unlock(); +} + +void DecoderThread::setFilename(QString filename) +{ + this->filename = filename; +} + +/** + * @brief Open a virtual connection to remote client + * + * @return 0 on success, -1 on failure + ******************************************************************************/ +int DecoderThread::openVirtualChannel() +{ + /* is channel already open? */ + if (channel) + return -1; + + /* open a virtual channel and connect to remote client */ + channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "xrdpvr", 0); + if (channel == NULL) + { + emit on_decoderErrorMsg("Connection failure", + "Error connecting to remote client"); + return -1; + } + return 0; +} + +int DecoderThread::closeVirtualChannel() +{ + /* channel must be opened first */ + if (!channel) + return -1; + + WTSVirtualChannelClose(channel); + return 0; +} + +/** + * @brief this is a temp hack while we figure out how to set up the right + * context for avcodec_decode_video2() on the server side; the workaround + * is to send the first 1MB of the media file to the server end which + * reads this file and sets up its context + * + * @return 0 on success, -1 on failure + ******************************************************************************/ +int DecoderThread::sendMetadataFile() +{ + if (xrdpvr_create_metadata_file(channel, filename.toAscii().data())) + { + emit on_decoderErrorMsg("I/O Error", + "An error occurred while sending data to remote client"); + return -1; + } + + return 0; +} + +int DecoderThread::sendVideoFormat() +{ + if (xrdpvr_set_video_format(channel, stream_id)) + { + emit on_decoderErrorMsg("I/O Error", + "Error sending video format to remote client"); + return -1; + } + + return 0; +} + +int DecoderThread::sendAudioFormat() +{ + if (xrdpvr_set_audio_format(channel, stream_id)) + { + emit on_decoderErrorMsg("I/O Error", + "Error sending audio format to remote client"); + return -1; + } + + return 0; +} + +int DecoderThread::sendGeometry() +{ + int rv; + + rv = xrdpvr_set_geometry(channel, stream_id, geometry.x(), geometry.y(), + geometry.width(), geometry.height()); + + if (rv) + { + emit on_decoderErrorMsg("I/O Error", + "Error sending screen geometry to remote client"); + return -1; + } + return 0; +} |
