diff options
| author | 2009-11-15 14:55:54 +0000 | |
|---|---|---|
| committer | 2009-11-15 14:55:54 +0000 | |
| commit | cf68e1549536e7e8646276891d35e08f65db19f0 (patch) | |
| tree | a50034f56858e0b8308bd4b28bdfda342484c4ff /src | |
| parent | probable fix for #534 (diff) | |
| download | KVIrc-cf68e1549536e7e8646276891d35e08f65db19f0.tar.gz KVIrc-cf68e1549536e7e8646276891d35e08f65db19f0.tar.bz2 KVIrc-cf68e1549536e7e8646276891d35e08f65db19f0.zip | |
some progress on dcc video.. it's even usable now :)
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@3611 17fca916-40b9-46aa-a4ea-0a15b648b75c
Diffstat (limited to 'src')
| -rw-r--r-- | src/modules/dcc/codec.cpp | 35 | ||||
| -rw-r--r-- | src/modules/dcc/codec.h | 6 | ||||
| -rw-r--r-- | src/modules/dcc/libkvidcc.cpp | 6 | ||||
| -rw-r--r-- | src/modules/dcc/video.cpp | 180 | ||||
| -rw-r--r-- | src/modules/dcc/video.h | 16 |
5 files changed, 115 insertions, 128 deletions
diff --git a/src/modules/dcc/codec.cpp b/src/modules/dcc/codec.cpp index 1ea1172c9..e70a532c9 100644 --- a/src/modules/dcc/codec.cpp +++ b/src/modules/dcc/codec.cpp @@ -122,36 +122,49 @@ const char * KviDccVideoCodec::name() return m_szName.ptr(); } -KviDccVideoNullCodec::KviDccVideoNullCodec() +KviDccVideoJpegCodec::KviDccVideoJpegCodec() : KviDccVideoCodec() { - m_szName = "null (no compression)"; + m_szName = "jpeg"; } -KviDccVideoNullCodec::~KviDccVideoNullCodec() +KviDccVideoJpegCodec::~KviDccVideoJpegCodec() { } -void KviDccVideoNullCodec::encode(KviDataBuffer * signal,KviDataBuffer * stream) +void KviDccVideoJpegCodec::encode(KviDataBuffer * signal,KviDataBuffer * stream) { if(signal->size() < 1)return; stream->append(signal->data(),signal->size()); signal->resize(0); } -void KviDccVideoNullCodec::decode(KviDataBuffer * stream,KviDataBuffer * signal) +void KviDccVideoJpegCodec::decode(KviDataBuffer * stream,KviDataBuffer * signal) { + static unsigned const char jpg_magic_init[4] = { 0xFF, 0xD8, 0xFF, 0xE0}; //SOI + APP0 + static unsigned const char jpg_magic_end[2] = { 0xFF, 0xD9}; //EOI + if(stream->size() < 1)return; - signal->append(stream->data(),stream->size()); - stream->resize(0); + + int start = stream->find(jpg_magic_init, 4); + int end = stream->find(jpg_magic_end, 2); + if(start != -1 && end != -1) + { + //remove junk before jpeg start + stream->remove(start); + int len = end - start + 1; + signal->clear(); + signal->append(stream->data(),stream->size()); + stream->remove(len); + } } -int KviDccVideoNullCodec::encodedFrameSize() +int KviDccVideoJpegCodec::encodedFrameSize() { - return 1024; + return 0; } -int KviDccVideoNullCodec::decodedFrameSize() +int KviDccVideoJpegCodec::decodedFrameSize() { - return 1024; + return 0; } diff --git a/src/modules/dcc/codec.h b/src/modules/dcc/codec.h index 7f0ed4f58..68da97c8d 100644 --- a/src/modules/dcc/codec.h +++ b/src/modules/dcc/codec.h @@ -69,11 +69,11 @@ public: virtual int decodedFrameSize(); }; -class KviDccVideoNullCodec : public KviDccVideoCodec +class KviDccVideoJpegCodec : public KviDccVideoCodec { public: - KviDccVideoNullCodec(); - virtual ~KviDccVideoNullCodec(); + KviDccVideoJpegCodec(); + virtual ~KviDccVideoJpegCodec(); public: virtual void encode(KviDataBuffer * signal,KviDataBuffer * stream); virtual void decode(KviDataBuffer * stream,KviDataBuffer * signal); diff --git a/src/modules/dcc/libkvidcc.cpp b/src/modules/dcc/libkvidcc.cpp index 3231a68df..4f6f467b0 100644 --- a/src/modules/dcc/libkvidcc.cpp +++ b/src/modules/dcc/libkvidcc.cpp @@ -1202,7 +1202,7 @@ static bool dcc_kvs_cmd_video(KviKvsModuleCommandCall * c) if(!dcc_kvs_parse_default_parameters(d,c))return false; - d->szCodec = "null"; + d->szCodec = "jpeg"; if(KviKvsVariant * pCodec = c->switches()->find('g',"codec")) { @@ -1211,8 +1211,8 @@ static bool dcc_kvs_cmd_video(KviKvsModuleCommandCall * c) if(!kvi_dcc_video_is_valid_codec(szCodec.toUtf8().data())) { - c->warning(__tr2qs_ctx("Invalid codec specified, defaulting to 'null'","dcc")); - d->szCodec = "null"; + c->warning(__tr2qs_ctx("Invalid codec specified, defaulting to 'jpeg'","dcc")); + d->szCodec = "jpeg"; } } diff --git a/src/modules/dcc/video.cpp b/src/modules/dcc/video.cpp index 0a42fea37..1835af942 100644 --- a/src/modules/dcc/video.cpp +++ b/src/modules/dcc/video.cpp @@ -46,21 +46,23 @@ extern KviDccBroker * g_pDccBroker; +#ifndef COMPILE_DISABLE_DCC_VIDEO + Kopete::AV::VideoDevicePool *g_pVideoDevicePool=0; + int g_iVideoDevicePoolInstances=0; +#endif + //Check for the *SS Api....we don't want to fail here... bool kvi_dcc_video_is_valid_codec(const char * codecName) { -// if(kvi_strEqualCI("jpeg",codecName))return true; - if(kvi_strEqualCI("null",codecName))return true; + if(kvi_strEqualCI("jpeg",codecName))return true; return false; } static KviDccVideoCodec * kvi_dcc_video_get_codec(const char *) { -// if(kvi_strEqualCI("jpeg",codecName))return new KviDccVoiceAdpcmCodec(); - //if(kvi_strEqualCI("null",codecName)) - return new KviDccVideoNullCodec(); -// return new KviDccVoiceAdpcmCodec(); +// if(kvi_strEqualCI("jpeg",codecName))return new KviDccVideoJpegCodec(); + return new KviDccVideoJpegCodec(); } @@ -73,6 +75,17 @@ KviDccVideoThread::KviDccVideoThread(KviWindow * wnd,kvi_socket_t fd,KviDccVideo m_bRecording = false; m_pInfoMutex = new KviMutex(); m_bRecordingRequestPending = false; + + //local video input + if(!g_pVideoDevicePool) + { + g_pVideoDevicePool = Kopete::AV::VideoDevicePool::self(); + g_pVideoDevicePool->open(); + g_pVideoDevicePool->setSize(320, 240); + } + g_iVideoDevicePoolInstances++; + //ensure capturing + g_pVideoDevicePool->startCapturing(); #endif startRecording(); startPlaying(); @@ -83,6 +96,10 @@ KviDccVideoThread::~KviDccVideoThread() { stopRecording(); #ifndef COMPILE_DISABLE_DCC_VIDEO + g_iVideoDevicePoolInstances--; + if(g_iVideoDevicePoolInstances==0) + g_pVideoDevicePool->close(); + delete m_pOpt->pCodec; delete m_pOpt; delete m_pInfoMutex; @@ -98,7 +115,7 @@ bool KviDccVideoThread::readWriteStep() if(kvi_select(m_fd,&bCanRead,&bCanWrite)) { - if(bCanRead) + while(bCanRead) { unsigned int actualSize = m_inFrameBuffer.size(); m_inFrameBuffer.resize(actualSize + 1024); @@ -109,12 +126,11 @@ bool KviDccVideoThread::readWriteStep() m_pOpt->pCodec->decode(&m_inFrameBuffer,&m_inSignalBuffer); //#warning "A maximum length for the signal buffer is actually needed!!!" } else { - if(!handleInvalidSocketRead(readLen))return false; + bCanRead=false; +// if(!handleInvalidSocketRead(readLen))return false; m_inFrameBuffer.resize(actualSize); } - }// else { - // m_uSleepTime += 100; - //} + } if(bCanWrite) { @@ -128,23 +144,10 @@ bool KviDccVideoThread::readWriteStep() } else { if(!handleInvalidSocketRead(written))return false; } - }// else { - // m_uSleepTime += 100; - // } - }// else { - // m_uSleepTime += 100; -// } + } + } //#warning "Usleep here ?" - }// else { -// if(!(m_bPlaying || m_bRecording)) -// { -// // Really NOTHING is happening...sleep a bit more -// m_uSleepTime += 800; -// } else { -// m_uSleepTime += 100; -// } -// } - + } #endif // !COMPILE_DISABLE_DCC_VOICE return true; } @@ -157,25 +160,11 @@ bool KviDccVideoThread::videoStep() { if(m_inSignalBuffer.size() > 0) { - unsigned const char jpg_magic_init[4] = { 0xFF, 0xD8, 0xFF, 0xE0}; //SOI + APP0 - unsigned const char jpg_magic_end[2] = { 0xFF, 0xD9}; //EOI - int start = m_inSignalBuffer.find(jpg_magic_init, 4); - int end = m_inSignalBuffer.find(jpg_magic_end, 2); - qDebug("start %d end %d", start, end); - if(start != -1 && end != -1) - { - //remove junk before jpeg start - m_inSignalBuffer.remove(start); - int len = end - start + 1; - QImage img; - img.loadFromData(m_inSignalBuffer.data(), len, "JPEG"); - if(!img.isNull()) - { - m_inImage = img; - qDebug("img in"); - } - m_inSignalBuffer.remove(len); - } + QImage img; + img.loadFromData(m_inSignalBuffer.data(), m_inSignalBuffer.size()); + if(!img.isNull()) + m_inImage = img; + m_inSignalBuffer.clear(); } } @@ -183,13 +172,17 @@ bool KviDccVideoThread::videoStep() if(m_bRecording) { //grab the image, compress using the codec + g_pVideoDevicePool->getFrame(); + g_pVideoDevicePool->getImage(&m_outImage); + QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); //0 to obtain small compressed files, //100 for large uncompressed files, //and -1 (the default) to use the default settings. - ((KviDccVideo*)KviDccThread::parent())->m_Image.save(&buffer, "JPEG", 20); + m_outImage.save(&buffer, "JPEG", 20); +// qDebug("framesize %d",ba.size()); if(ba.size() > 0) { m_outSignalBuffer.append((const unsigned char*) ba.data(), ba.size()); @@ -272,7 +265,7 @@ void KviDccVideoThread::run() #ifndef COMPILE_DISABLE_DCC_VIDEO for(;;) { -// m_uSleepTime = 0; + m_uSleepTime = 0; // Dequeue events while(KviThreadEvent * e = dequeueEvent()) @@ -298,10 +291,14 @@ void KviDccVideoThread::run() if(!videoStep())goto exit_dcc; m_pInfoMutex->lock(); - m_iInputBufferSize = m_inSignalBuffer.size(); - m_iOutputBufferSize = (m_outFrameBuffer.size() / m_pOpt->pCodec->encodedFrameSize()) * m_pOpt->pCodec->decodedFrameSize(); +// m_iInputBufferSize = m_inSignalBuffer.size(); +// m_iOutputBufferSize = m_outSignalBuffer.size(); m_pInfoMutex->unlock(); + //if(m_uSleepTime)usleep(m_uSleepTime); + //qDebug("in %d out %d in_sig %d out_sig %d", m_inFrameBuffer.size(), m_outFrameBuffer.size(), m_inSignalBuffer.size(), m_outSignalBuffer.size()); +// usleep(200); + // Start recording if the request was not fulfilled yet if(m_bRecordingRequestPending)startRecording(); } @@ -341,22 +338,12 @@ KviDccVideo::KviDccVideo(KviFrame *pFrm,KviDccDescriptor * dcc,const char * name m_pOutVideoLabel->setAlignment(Qt::AlignCenter); m_pLayout->addWidget(m_pOutVideoLabel, 11, 0, 10, 1); -#ifndef COMPILE_DISABLE_DCC_VIDEO - //local video input - m_pVideoDevicePool = Kopete::AV::VideoDevicePool::self(); - m_pVideoDevicePool->open(); - m_pVideoDevicePool->setSize(320, 240); -#endif - //local video input: config m_pLabel[0] = new QLabel(); m_pLabel[0]->setText(__tr2qs_ctx("Video device:","dcc")); m_pLayout->addWidget(m_pLabel[0], 11, 1, 1, 1); m_pCDevices = new QComboBox(); -#ifndef COMPILE_DISABLE_DCC_VIDEO - m_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); -#endif m_pLayout->addWidget(m_pCDevices, 12, 1, 1, 1); m_pLabel[1] = new QLabel(); @@ -364,9 +351,6 @@ KviDccVideo::KviDccVideo(KviFrame *pFrm,KviDccDescriptor * dcc,const char * name m_pLayout->addWidget(m_pLabel[1], 13, 1, 1, 1); m_pCInputs = new QComboBox(); -#ifndef COMPILE_DISABLE_DCC_VIDEO - m_pVideoDevicePool->fillInputQComboBox(m_pCInputs); -#endif m_pLayout->addWidget(m_pCInputs, 14, 1, 1, 1); m_pLabel[2] = new QLabel(); @@ -374,25 +358,14 @@ KviDccVideo::KviDccVideo(KviFrame *pFrm,KviDccDescriptor * dcc,const char * name m_pLayout->addWidget(m_pLabel[2], 15, 1, 1, 1); m_pCStandards = new QComboBox(); -#ifndef COMPILE_DISABLE_DCC_VIDEO - m_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); -#endif m_pLayout->addWidget(m_pCStandards, 16, 1, 1, 1); setLayout(m_pLayout); -#ifndef COMPILE_DISABLE_DCC_VIDEO - m_pVideoDevicePool->startCapturing(); + connect(&m_Timer, SIGNAL(timeout()), this, SLOT(slotUpdateImage()) ); - connect(m_pVideoDevicePool, SIGNAL(deviceRegistered(const QString &) ), SLOT(deviceRegistered(const QString &)) ); - connect(m_pVideoDevicePool, SIGNAL(deviceUnregistered(const QString &) ), SLOT(deviceUnregistered(const QString &)) ); + m_Timer.start(200); //5fps - connect(&m_Timer, SIGNAL(timeout()), this, SLOT(slotUpdateImage()) ); - if ( m_pVideoDevicePool->hasDevices() ) - { - m_Timer.start(40); //25fps - } -#endif m_pMarshal = new KviDccMarshal(this); connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); @@ -403,9 +376,6 @@ KviDccVideo::KviDccVideo(KviFrame *pFrm,KviDccDescriptor * dcc,const char * name KviDccVideo::~KviDccVideo() { -#ifndef COMPILE_DISABLE_DCC_VIDEO - m_pVideoDevicePool->close(); -#endif if(m_pInVideoLabel) { delete m_pInVideoLabel; @@ -628,6 +598,19 @@ void KviDccVideo::connected() output(KVI_OUT_DCCMSG,__tr2qs_ctx("Actual codec used is '%s'","dcc"),opt->pCodec->name()); m_pSlaveThread = new KviDccVideoThread(this,m_pMarshal->releaseSocket(),opt); + +#ifndef COMPILE_DISABLE_DCC_VIDEO + if(g_pVideoDevicePool) + { + g_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); + g_pVideoDevicePool->fillInputQComboBox(m_pCInputs); + g_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); + + connect(g_pVideoDevicePool, SIGNAL(deviceRegistered(const QString &) ), SLOT(deviceRegistered(const QString &)) ); + connect(g_pVideoDevicePool, SIGNAL(deviceUnregistered(const QString &) ), SLOT(deviceUnregistered(const QString &)) ); + } +#endif + m_pSlaveThread->start(); // m_pTalkButton->setEnabled(true); @@ -656,46 +639,47 @@ void KviDccVideo::startOrStopTalking(bool bStart) void KviDccVideo::slotUpdateImage() { #ifndef COMPILE_DISABLE_DCC_VIDEO - m_pVideoDevicePool->getFrame(); - m_pVideoDevicePool->getImage(&m_Image); - if(isVisible()) + if(m_pSlaveThread && isVisible()) { - m_pOutVideoLabel->setPixmap(QPixmap::fromImage(m_Image.mirrored(m_pVideoDevicePool->getImageAsMirror(),false))); - if(m_pSlaveThread) - m_pInVideoLabel->setPixmap(QPixmap::fromImage(m_pSlaveThread->m_inImage)); + m_pOutVideoLabel->setPixmap(QPixmap::fromImage(m_pSlaveThread->m_outImage)); + m_pInVideoLabel->setPixmap(QPixmap::fromImage(m_pSlaveThread->m_inImage)); } #endif } void KviDccVideo::deviceRegistered(const QString &) { + /* #ifndef COMPILE_DISABLE_DCC_VIDEO - m_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); - m_pVideoDevicePool->fillInputQComboBox(m_pCInputs); - m_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); + g_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); + g_pVideoDevicePool->fillInputQComboBox(m_pCInputs); + g_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); // update the mVideoImageLabel to show the camera frames - m_pVideoDevicePool->open(); - m_pVideoDevicePool->setSize(320, 240); - m_pVideoDevicePool->startCapturing(); + g_pVideoDevicePool->open(); + g_pVideoDevicePool->setSize(320, 240); + g_pVideoDevicePool->startCapturing(); // setVideoInputParameters(); - if ( m_pVideoDevicePool->hasDevices() ) - { - m_Timer.start(200); //5fps - } +// if ( g_pVideoDevicePool->hasDevices() ) +// { +// m_Timer.start(200); //5fps +// } #endif +#*/ } void KviDccVideo::deviceUnregistered(const QString & ) { +/* #ifndef COMPILE_DISABLE_DCC_VIDEO - m_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); - m_pVideoDevicePool->fillInputQComboBox(m_pCInputs); - m_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); + g_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); + g_pVideoDevicePool->fillInputQComboBox(m_pCInputs); + g_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); #endif +*/ } #ifndef COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/video.h b/src/modules/dcc/video.h index 22fc1310d..40967aada 100644 --- a/src/modules/dcc/video.h +++ b/src/modules/dcc/video.h @@ -79,11 +79,14 @@ protected: bool m_bPlaying; bool m_bRecording; bool m_bRecordingRequestPending; + unsigned int m_uSleepTime; KviMutex * m_pInfoMutex; // stuff protected by the mutex: int m_iInputBufferSize; int m_iOutputBufferSize; +protected: QImage m_inImage; + QImage m_outImage; protected: bool readWriteStep(); bool videoStep(); @@ -106,25 +109,12 @@ public: protected: QLabel *m_pInVideoLabel; QLabel *m_pOutVideoLabel; -#ifndef COMPILE_DISABLE_DCC_VIDEO - Kopete::AV::VideoDevicePool *m_pVideoDevicePool; -#endif QComboBox *m_pCDevices; QComboBox *m_pCInputs; QComboBox *m_pCStandards; QGridLayout *m_pLayout; - QImage m_Image; QTimer m_Timer; QLabel * m_pLabel[2]; -/* - KviTalHBox * m_pHBox; - QSlider * m_pVolumeSlider; - QLabel * m_pInputLabel; - QLabel * m_pOutputLabel; - QLabel * m_pRecordingLabel; - QLabel * m_pPlayingLabel; - QToolButton * m_pTalkButton; -*/ QString * m_pszTarget; KviDccVideoThread * m_pSlaveThread; protected: |
