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;
}
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);
        }
    }
}
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;
}
Exemplo n.º 5
0
bool UBQuickTimeFile::createCompressionSession()
{
    CodecType codecType = kH264CodecType;

    CFStringRef keys[] = {kCVPixelBufferPixelFormatTypeKey, kCVPixelBufferWidthKey, kCVPixelBufferHeightKey};

    int width = mFrameSize.width();
    int height = mFrameSize.height();
    int pixelFormat = k32BGRAPixelFormat;

    CFTypeRef values[] =
    {
        (CFTypeRef)CFNumberCreate(0, kCFNumberIntType, (void*)&pixelFormat),
        (CFTypeRef)CFNumberCreate(0, kCFNumberIntType, (void*)&width),
        (CFTypeRef)CFNumberCreate(0, kCFNumberIntType, (void*)&height)
    };

    CFDictionaryRef pixelBufferAttributes = CFDictionaryCreate(kCFAllocatorDefault
            , (const void **)keys, (const void **)values, 3, 0, 0);

    if(!pixelBufferAttributes)
    {
        setLastErrorMessage("Could not create CV buffer pool pixel buffer attributes");
        return false;
    }

    OSStatus err = noErr;
    ICMEncodedFrameOutputRecord encodedFrameOutputRecord = {0};
    ICMCompressionSessionOptionsRef sessionOptions = 0;

    err = ICMCompressionSessionOptionsCreate(0, &sessionOptions);
    if(err)
    {
        setLastErrorMessage(QString("ICMCompressionSessionOptionsCreate() failed %1").arg(err));
        goto bail;
    }

    // We must set this flag to enable P or B frames.
    err = ICMCompressionSessionOptionsSetAllowTemporalCompression(sessionOptions, true);
    if(err)
    {
        setLastErrorMessage(QString("ICMCompressionSessionOptionsSetAllowTemporalCompression() failed %1").arg(err));
        goto bail;
    }

    // We must set this flag to enable B frames.
    err = ICMCompressionSessionOptionsSetAllowFrameReordering(sessionOptions, true);
    if(err)
    {
        setLastErrorMessage(QString("ICMCompressionSessionOptionsSetAllowFrameReordering() failed %1").arg(err));
        goto bail;
    }

    // Set the maximum key frame interval, also known as the key frame rate.
    err = ICMCompressionSessionOptionsSetMaxKeyFrameInterval(sessionOptions, mFramesPerSecond);
    if(err)
    {
        setLastErrorMessage(QString("ICMCompressionSessionOptionsSetMaxKeyFrameInterval() failed %1").arg(err));
        goto bail;
    }

    // This allows the compressor more flexibility (ie, dropping and coalescing frames).
    err = ICMCompressionSessionOptionsSetAllowFrameTimeChanges(sessionOptions, true);
    if(err)
    {
        setLastErrorMessage(QString("ICMCompressionSessionOptionsSetAllowFrameTimeChanges() failed %1").arg(err));
        goto bail;
    }

    // Set the average quality.
    err = ICMCompressionSessionOptionsSetProperty(sessionOptions,
                                                      kQTPropertyClass_ICMCompressionSessionOptions,
                                                      kICMCompressionSessionOptionsPropertyID_Quality,
                                                      sizeof(mSpatialQuality),
                                                      &mSpatialQuality);
    if(err)
    {
        setLastErrorMessage(QString("ICMCompressionSessionOptionsSetProperty(Quality) failed %1").arg(err));
        goto bail;
    }

    //qDebug() << "available quality" << mSpatialQuality;

    encodedFrameOutputRecord.encodedFrameOutputCallback = addEncodedFrameToMovie;
    encodedFrameOutputRecord.encodedFrameOutputRefCon = this;
    encodedFrameOutputRecord.frameDataAllocator = 0;

    err = ICMCompressionSessionCreate(0, mFrameSize.width(), mFrameSize.height(), codecType, mTimeScale,
                                                                      sessionOptions, pixelBufferAttributes, &encodedFrameOutputRecord, &mVideoCompressionSession);
    if(err)
    {
        setLastErrorMessage(QString("ICMCompressionSessionCreate() failed %1").arg(err));
        goto bail;
    }

    mCVPixelBufferPool = ICMCompressionSessionGetPixelBufferPool(mVideoCompressionSession);

    if(!mCVPixelBufferPool)
    {
        setLastErrorMessage("ICMCompressionSessionGetPixelBufferPool() failed.");
        err = !noErr;
        goto bail;
    }

    if(mRecordAudio)
    {
        mWaveRecorder = new UBAudioQueueRecorder();

        if(mWaveRecorder->init(mAudioRecordingDeviceName))
        {
            connect(mWaveRecorder, SIGNAL(newWaveBuffer(void*, long, int , const AudioStreamPacketDescription*))
                                    , this, SLOT(appendAudioBuffer(void*, long, int, const AudioStreamPacketDescription*)));

            connect(mWaveRecorder, SIGNAL(audioLevelChanged(quint8)), this, SIGNAL(audioLevelChanged(quint8)));
        }
        else
        {