/* * This program 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, either version 3 of the License, or * (at your option) any later version. * * This program 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 this program. 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/uniboard.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; }