новые иконки в OpenBoard
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.
 
 
 
 
 
 
OpenBoard/src/podcast/windowsmedia/UBWindowsMediaVideoEncoder.cpp

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;
}