⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdla_render.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
字号:
/*
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//       Copyright(c) 2003-2006 Intel Corporation. All Rights Reserved.
//
*/

#if defined(SDL_ON) && (defined(LINUX32) || defined(WIN32))

#include <string.h>
#include <malloc.h>
#include "vm_time.h"
#include "sdla_render.h"
#include "ipps.h"
#include "vm_debug.h"

SDLAudioRender::SDLAudioRender(void)
{
    if (!(SDL_WasInit(SDL_INIT_AUDIO)&SDL_INIT_AUDIO))
        SDL_InitSubSystem(SDL_INIT_AUDIO);
    memset(buffers, 0, sizeof(buffers));

    m_bInitSemaphore = 0;
}

SDLAudioRender::~SDLAudioRender(void)
{
    Close();
}

UMC_Status SDLAudioRender::Pause(bool pause)
{
    SDL_PauseAudio(pause);
    return UMC_OK;
}

void AudioCallBack(void *data,Uint8 *stream,Ipp32s nbytes)
{
    SDLAudioRender* pthis = (SDLAudioRender*)data;
    pthis->AudioThreadFunc(stream, nbytes);
}

void SDLAudioRender::AudioThreadFunc(Uint8 *stream, Ipp32s nbytes)
{
    Ipp64f rpts= (Ipp64f)vm_time_get_tick() / (Ipp64f)vm_time_get_frequency();
    if (!read_position)
        vm_semaphore_wait(&sm_read_buffer);

    Ipp64f pts=buffers[read_index].pts+
               (Ipp64f)read_position/spec.channels/sizeof(Ipp16s)/spec.freq;

    /* update offset for av synchronization */
    offset=(rpts-prev_rpts)-(pts-prev_pts);
    prev_rpts=rpts; prev_pts=pts;

    for (Ipp32s nbytes_copied=0;nbytes>0;nbytes-=nbytes_copied) {
        if (buffers[read_index].nbytes>0) {
            nbytes_copied=buffers[read_index].nbytes-read_position;
            if (nbytes<nbytes_copied) nbytes_copied=nbytes;

            ippsCopy_8u(buffers[read_index].buffer+read_position,
                        stream,nbytes_copied);

            stream+=nbytes_copied;
            read_position+=nbytes_copied;

            if (read_position>=buffers[read_index].nbytes) {
                vm_semaphore_post(&sm_write_buffer);
                if (++read_index>=NUM_SND_BUFFER) read_index=0;
                if (nbytes>nbytes_copied) vm_semaphore_wait(&sm_read_buffer);
                read_position=0;
            }
        } else {
            nbytes_copied=nbytes;
            ippsZero_8u(stream,nbytes_copied);
            read_position+=nbytes_copied;
        }
    }
}

UMC_Status SDLAudioRender::Init(sAudioStreamInfo *info)
{
    Ipp32s buffer_size = sizeof(Ipp16s) * info->channels * 1024;
    for (Ipp32s i=0; i < NUM_SND_BUFFER ; i++) {
        buffers[i].buffer = (Ipp8u *)malloc(buffer_size);
        if (!buffers[i].buffer)
            return UMC_ERR_ALLOC;
    }

    SDL_AudioSpec desired;
    desired.freq=info->sample_frequency;
    desired.channels=info->channels;
    desired.format=AUDIO_S16LSB;
    desired.samples=1024;
    desired.userdata=this;
    desired.callback=(void (*)(void*, Uint8*, Ipp32s))::AudioCallBack;

    vm_semaphore_init(&sm_read_buffer, 0);
    vm_semaphore_init(&sm_write_buffer, NUM_SND_BUFFER/2);
    m_bInitSemaphore = true;

    /* Try device specific audio first */
    if (SDL_OpenAudio(&desired, &spec) < 0) {
        vm_debug_trace(VM_DEBUG_ERROR, "Init: failed to open audio device\n");
        return UMC_ERR_OPEN_FAILED;
    }

    /* If format changed, let SDL handle the format conversion */
    if (desired.channels!=spec.channels || desired.format!=spec.format) {
        vm_debug_trace(VM_DEBUG_WARNING, "Init: simulated audio\n");
        memcpy(&spec, &desired, sizeof(spec));

        SDL_CloseAudio();
        if (SDL_OpenAudio(&spec, NULL) < 0) {
            vm_debug_trace(VM_DEBUG_ERROR, "Init: failed to open audio device\n");
            return UMC_ERR_OPEN_FAILED;
        }
    }
    read_index=write_index=read_position=0;
    return UMC_OK;
}

UMC_Status SDLAudioRender::Close(void)
{
    SDL_CloseAudio();

    if (m_bInitSemaphore) {
        vm_semaphore_destroy(&sm_read_buffer);
        vm_semaphore_destroy(&sm_write_buffer);
    }

    for (Ipp32s i=0;i<NUM_SND_BUFFER;i++) {
        if (buffers[i].buffer) free(buffers[i].buffer);
        buffers[i].buffer=NULL;
    }
    return UMC_OK;
}

Ipp64f SDLAudioRender::GetClockOffset(void) {
    // add other compensations here
    return offset;
}

UMC_Status SDLAudioRender::SendFrame(sMediaData* in)
{
    vm_semaphore_wait(&sm_write_buffer);
    ippsCopy_8u(in->pBuffer,buffers[write_index].buffer,in->cbBuffSize);
    buffers[write_index].nbytes=in->cbBuffSize;
    buffers[write_index].pts=in->frame_time;
    if (++write_index>=NUM_SND_BUFFER) write_index=0;
    vm_semaphore_post(&sm_read_buffer);
    return UMC_OK;
}

void SDLAudioRender::SendEOF(void)
{
    vm_semaphore_wait(&sm_write_buffer);
    buffers[write_index].nbytes=0;
    vm_semaphore_post(&sm_read_buffer);
}

Ipp64f SDLAudioRender::GetTime()
{
    return 0.;
}

#endif // defined(SDL_ON) && (defined(LINUX32) || defined(WIN32))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -