Пример #1
0
	void startAudioCapture()
	{
		if (audioDeviceInfo.isNull())
		{
			audioInput = nullptr;
			return;
		}

		audioInput = std::make_unique<QAudioInput>(audioDeviceInfo, audioFormat);
		QIODevice * audioDevice = audioInput->start();
		audioBuffer.clear();
		QObject::connect(audioDevice, &QIODevice::readyRead, audioDevice, [=](){
			audioBuffer += audioDevice->readAll();
			int frameSize = 1024 * audioFormat.channelCount();
			while (audioBuffer.size() > frameSize)
			{
				QByteArray data = audioBuffer.left(frameSize);
				audioBuffer.remove(0, frameSize);
				writeAudioFrame(audioStreamIndex, data);
			}
		});
	}
Пример #2
0
void EncoderFfmpegCore::encodeBuffer(const CSAMPLE *samples, const int size) {
    unsigned char *l_strBuffer = NULL;
    int l_iBufferLen = 0;
    //int l_iAudioCpyLen = m_iAudioInputFrameSize *
    //                     av_get_bytes_per_sample(m_pEncoderAudioStream->codec->sample_fmt) *
    //                     m_pEncoderAudioStream->codec->channels;
    long l_iLeft = size;
    long j = 0;
    unsigned int l_iBufPos = 0;
    unsigned int l_iPos = 0;

    // TODO(XXX): Get rid of repeated malloc here!
    float *l_fNormalizedSamples = (float *)malloc(size * sizeof(float));

    // We use normalized floats in the engine [-1.0, 1.0] and FFMPEG expects
    // samples in the range [-1.0, 1.0] so no conversion is required.
    for (j = 0; j < size; j++) {
        l_fNormalizedSamples[j] = samples[j];
    }

    // In MP3 this writes Header same In ogg
    // They are written once front of the encoded stuff
    if (m_bStreamInitialized == false) {
        m_bStreamInitialized = true;
        // Write a header.
        avio_open_dyn_buf(&m_pEncodeFormatCtx->pb);
        if (avformat_write_header(m_pEncodeFormatCtx, NULL) != 0) {
            qDebug() << "EncoderFfmpegCore::encodeBuffer: failed to write a header.";
            return;
        }

        l_iBufferLen = avio_close_dyn_buf(m_pEncodeFormatCtx->pb,
                                          (uint8_t**)(&l_strBuffer));
        m_pCallback->write(NULL, l_strBuffer, 0, l_iBufferLen);
        av_free(l_strBuffer);
    }

    while (l_iLeft > (m_iFltAudioCpyLen / 4)) {
        memset(m_pFltSamples, 0x00, m_iFltAudioCpyLen);

        for (j = 0; j < m_iFltAudioCpyLen / 4; j++) {
            if (m_lBufferSize > 0) {
                m_pFltSamples[j] = m_SBuffer[ l_iBufPos++ ];
                m_lBufferSize--;
                m_lRecordedBytes++;
            } else {
                m_pFltSamples[j] = l_fNormalizedSamples[l_iPos++];
                l_iLeft--;
                m_lRecordedBytes++;
            }

            if (l_iLeft <= 0) {
                qDebug() << "ffmpegencodercore: No samples left.. for encoding!";
                break;
            }
        }

        m_lBufferSize = 0;

        // Open dynamic buffer for writing next bytes
        if (avio_open_dyn_buf(&m_pEncodeFormatCtx->pb) < 0) {
            qDebug() << "Can't alloc Dyn buffer!";
            return;
        }

        // Write it to buffer (FILE) and then close buffer for waiting
        // Next encoded buffe to come or we stop encode
        if (! writeAudioFrame(m_pEncodeFormatCtx, m_pEncoderAudioStream)) {
            l_iBufferLen = avio_close_dyn_buf(m_pEncodeFormatCtx->pb,
                                              (uint8_t**)(&l_strBuffer));
            m_pCallback->write(NULL, l_strBuffer, 0, l_iBufferLen);
            av_free(l_strBuffer);
        }
    }

    // Keep things clean
    memset(m_SBuffer, 0x00, 65535);

    for (j = 0; j < l_iLeft; j++) {
        m_SBuffer[ j ] = l_fNormalizedSamples[ l_iPos++ ];
    }
    m_lBufferSize = l_iLeft;
    free(l_fNormalizedSamples);
}