📄 sdla_render.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-2005 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_StatusSDLAudioRender::Pause(bool pause) { SDL_PauseAudio(pause); return UMC_OK;}voidAudioCallBack(void *data,Uint8 *stream,int nbytes){ SDLAudioRender* pthis = (SDLAudioRender*)data; pthis->AudioThreadFunc(stream,nbytes);}voidSDLAudioRender::AudioThreadFunc(Uint8 *stream, int nbytes){ double rpts=(double)vm_time_get_tick()/(double)vm_time_get_frequency(); if (!read_position) vm_semaphore_wait(&sm_read_buffer); double pts=buffers[read_index].pts+ (double)read_position/spec.channels/sizeof(short)/spec.freq; /* update offset for av synchronization */ offset=(rpts-prev_rpts)-(pts-prev_pts); prev_rpts=rpts; prev_pts=pts; for (int 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_StatusSDLAudioRender::Init(sAudioStreamInfo *info){ int buffer_size=sizeof(short)*info->channels*1024; for (int i=0;i<NUM_SND_BUFFER;i++) { buffers[i].buffer=(unsigned char *)malloc(buffer_size); if (!buffers[i].buffer) return UMC_FAILED_TO_ALLOCATE_BUFFER; } 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*, int))::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_msg(1,"Init: failed to open audio device\n"); return UMC_FAILED_TO_OPEN_DEVICE; } /* If format changed, let SDL handle the format conversion */ if (desired.channels!=spec.channels || desired.format!=spec.format) { vm_debug_msg(2,"Init: simulated audio\n"); memcpy(&spec,&desired,sizeof(spec)); SDL_CloseAudio(); if (SDL_OpenAudio(&spec,NULL)<0) { vm_debug_msg(1,"Init: failed to open audio device\n"); return UMC_FAILED_TO_OPEN_DEVICE; } } read_index=write_index=read_position=0; return UMC_OK;}UMC_StatusSDLAudioRender::Close(void){ SDL_CloseAudio(); if (m_bInitSemaphore) { vm_semaphore_destroy(&sm_read_buffer); vm_semaphore_destroy(&sm_write_buffer); } for (int i=0;i<NUM_SND_BUFFER;i++) { if (buffers[i].buffer) free(buffers[i].buffer); buffers[i].buffer=NULL; } return UMC_OK;}double SDLAudioRender::GetClockOffset(void) { // add other compensations here return offset;}UMC_StatusSDLAudioRender::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;}voidSDLAudioRender::SendEOF(void){ vm_semaphore_wait(&sm_write_buffer); buffers[write_index].nbytes=0; vm_semaphore_post(&sm_read_buffer);}double SDLAudioRender::GetTime(){ return 0.;}#endif // defined(SDL_ON) && (defined(LINUX32) || defined(WIN32))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -