You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
6.1 KiB
247 lines
6.1 KiB
/*
|
|
* Copyright (C) 2010-2013 Groupement d'Intérêt Public pour l'Education Numérique en Afrique (GIP ENA)
|
|
*
|
|
* This file is part of Open-Sankoré.
|
|
*
|
|
* Open-Sankoré is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, version 3 of the License,
|
|
* with a specific linking exception for the OpenSSL project's
|
|
* "OpenSSL" library (or with modified versions of it that use the
|
|
* same license as the "OpenSSL" library).
|
|
*
|
|
* Open-Sankoré is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Open-Sankoré. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
|
|
#include "UBWindowsMediaVideoEncoder.h"
|
|
|
|
#include <QtGui>
|
|
|
|
#include "frameworks/UBFileSystemUtils.h"
|
|
|
|
#include "core/UBApplication.h"
|
|
|
|
#include "UBWindowsMediaFile.h"
|
|
|
|
#include "core/memcheck.h"
|
|
|
|
UBWindowsMediaVideoEncoder::UBWindowsMediaVideoEncoder(QObject* pParent)
|
|
: UBAbstractVideoEncoder(pParent)
|
|
, mWMVideo(0)
|
|
, mWaveRecorder(0)
|
|
, mRecordAudio(true)
|
|
, mLastAudioLevel(0)
|
|
, mIsPaused(false)
|
|
{
|
|
// NOOP
|
|
}
|
|
|
|
|
|
UBWindowsMediaVideoEncoder::~UBWindowsMediaVideoEncoder()
|
|
{
|
|
// NOOP
|
|
}
|
|
|
|
|
|
bool UBWindowsMediaVideoEncoder::start()
|
|
{
|
|
QString profile = UBFileSystemUtils::readTextFile(":/podcast/OpenBoard.prx");
|
|
|
|
profile.replace("{in.videoWidth}", QString("%1").arg(videoSize().width()));
|
|
profile.replace("{in.videoHeight}", QString("%1").arg(videoSize().height()));
|
|
profile.replace("{in.bitsPerSecond}", QString("%1").arg(videoBitsPerSecond()));
|
|
profile.replace("{in.nanoSecondsPerFrame}", QString("%1").arg(10000000 / framesPerSecond()));
|
|
|
|
qDebug() << profile;
|
|
|
|
if(mRecordAudio)
|
|
{
|
|
mWaveRecorder = new UBWaveRecorder(this);
|
|
|
|
bool audioAvailable = mWaveRecorder->init(audioRecordingDevice()) && mWaveRecorder->start();
|
|
|
|
if (!audioAvailable)
|
|
{
|
|
mWaveRecorder->deleteLater();
|
|
mWaveRecorder = 0;
|
|
mRecordAudio = false;
|
|
}
|
|
}
|
|
|
|
mWMVideo = new UBWindowsMediaFile(this);
|
|
|
|
if(!mWMVideo->init(videoFileName().replace("/", "\\"), profile, framesPerSecond(),
|
|
videoSize().width(), videoSize().height(), 32))
|
|
{
|
|
mWMVideo->deleteLater();
|
|
return false;
|
|
}
|
|
|
|
if (mRecordAudio)
|
|
{
|
|
connect(mWaveRecorder, SIGNAL(newWaveBuffer(WAVEHDR*, long)), mWMVideo
|
|
, SLOT(appendAudioBuffer(WAVEHDR*, long)), Qt::DirectConnection);
|
|
connect(mWaveRecorder, SIGNAL(newWaveBuffer(WAVEHDR*, long)), this
|
|
, SLOT(processAudioBuffer(WAVEHDR*, long)), Qt::DirectConnection);
|
|
}
|
|
|
|
mIsRecording = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool UBWindowsMediaVideoEncoder::stop()
|
|
{
|
|
bool audioOk = true;
|
|
|
|
if (mWaveRecorder)
|
|
{
|
|
disconnect(mWaveRecorder, SIGNAL(newWaveBuffer(WAVEHDR*, long)), mWMVideo
|
|
, SLOT(appendAudioBuffer(WAVEHDR*, long)));
|
|
disconnect(mWaveRecorder, SIGNAL(newWaveBuffer(WAVEHDR*, long)), this
|
|
, SLOT(processAudioBuffer(WAVEHDR*, long)));
|
|
|
|
mWaveRecorder->stop();
|
|
audioOk = mWaveRecorder->close();
|
|
mLastErrorMessage = mWaveRecorder->lastErrorMessage();
|
|
mWaveRecorder->deleteLater();
|
|
mWaveRecorder = 0;
|
|
emit audioLevelChanged(0);
|
|
}
|
|
|
|
bool videoOk = true;
|
|
|
|
if (mWMVideo)
|
|
{
|
|
videoOk = mWMVideo->close();
|
|
mLastErrorMessage = mWMVideo->lastErrorMessage();
|
|
mWMVideo->deleteLater();
|
|
mWMVideo = 0;
|
|
}
|
|
|
|
bool ok = audioOk && videoOk;
|
|
|
|
emit encodingFinished(ok);
|
|
|
|
mIsRecording = false;
|
|
|
|
return ok;
|
|
}
|
|
|
|
|
|
void UBWindowsMediaVideoEncoder::newPixmap(const QImage& pPix, long timestamp)
|
|
{
|
|
if(mWMVideo && !mIsPaused)
|
|
{
|
|
if(!mWMVideo->appendVideoFrame(pPix, timestamp))
|
|
{
|
|
qWarning() << "Error adding new video frame" << mWMVideo->lastErrorMessage();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void UBWindowsMediaVideoEncoder::newChapter(const QString& pLabel, long timestamp)
|
|
{
|
|
if(mWMVideo)
|
|
mWMVideo->startNewChapter(pLabel, timestamp);
|
|
}
|
|
|
|
|
|
void UBWindowsMediaVideoEncoder::setRecordAudio(bool pRecordAudio)
|
|
{
|
|
if (mRecordAudio != pRecordAudio)
|
|
{
|
|
mRecordAudio = pRecordAudio;
|
|
|
|
if (mRecordAudio)
|
|
{
|
|
connect(mWaveRecorder, SIGNAL(newWaveBuffer(WAVEHDR*, long)), mWMVideo, SLOT(appendAudioBuffer(WAVEHDR*, long)), Qt::DirectConnection);
|
|
}
|
|
else
|
|
{
|
|
disconnect(mWaveRecorder, SIGNAL(newWaveBuffer(WAVEHDR*, long)), mWMVideo, SLOT(appendAudioBuffer(WAVEHDR*, long)));
|
|
emit audioLevelChanged(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void UBWindowsMediaVideoEncoder::processAudioBuffer(WAVEHDR* waveBuffer, long timestamp)
|
|
{
|
|
Q_UNUSED(timestamp);
|
|
|
|
if(mWaveRecorder && mRecordAudio)
|
|
{
|
|
long samplesCount = waveBuffer->dwBytesRecorded / 2;
|
|
qint16* samples = (qint16*)waveBuffer->lpData;
|
|
quint16 maxRMS = 0;
|
|
|
|
for(long i = 0; i < samplesCount; i++)
|
|
{
|
|
quint8 current = qAbs(samples[i] / 128);
|
|
|
|
quint16 currentRMS = current * current;
|
|
maxRMS = qMax(maxRMS, currentRMS);
|
|
}
|
|
|
|
quint8 max = sqrt((qreal)maxRMS);
|
|
|
|
if (max != mLastAudioLevel)
|
|
{
|
|
mLastAudioLevel = max;
|
|
emit audioLevelChanged(mLastAudioLevel);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
bool UBWindowsMediaVideoEncoder::pause()
|
|
{
|
|
bool result = true;
|
|
|
|
if(!mIsPaused && mIsRecording)
|
|
{
|
|
if(mWaveRecorder)
|
|
{
|
|
result = mWaveRecorder->stop();
|
|
emit audioLevelChanged(0);
|
|
}
|
|
|
|
mIsPaused = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
bool UBWindowsMediaVideoEncoder::unpause()
|
|
{
|
|
bool result = true;
|
|
|
|
if (mIsPaused && mIsRecording)
|
|
{
|
|
if(mWaveRecorder)
|
|
{
|
|
result = mWaveRecorder->start();
|
|
}
|
|
|
|
mIsPaused = false;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
|