SDL_PauseAudio函数

SDL_PauseAudio函数:

用此函数来暂停播放,或播放。根据参数来决定,如果参数是非0值就暂停,如果是0值就播放。

void SDL_PauseAudio(int pause_on)
例子:

int main(int argc, char* argv[])  
{  
    //Init  
    if(SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER)) {    
        printf( "Could not initialize SDL - %s\n", SDL_GetError());   
        return -1;  
    }  
    //SDL_AudioSpec  
    SDL_AudioSpec wanted_spec;  
    wanted_spec.freq = 44100;   
    wanted_spec.format = AUDIO_S16SYS;   
    wanted_spec.channels = 2;   
    wanted_spec.silence = 0;   
    wanted_spec.samples = 1024;   
    wanted_spec.callback = fill_audio;   
  
    if (SDL_OpenAudio(&wanted_spec, NULL)<0){   
        printf("can't open audio.\n");   
        return -1;   
    }   
  
    FILE *fp=fopen("../NocturneNo2inEflat_44.1k_s16le.pcm","rb+");  
    if(fp==NULL){  
        printf("cannot open this file\n");  
        return -1;  
    }  
    int pcm_buffer_size=4096;  
    char *pcm_buffer=(char *)malloc(pcm_buffer_size);  
    int data_count=0;  
  
    //Play  
    SDL_PauseAudio(0);  
  
    while(1){  
        if (fread(pcm_buffer, 1, pcm_buffer_size, fp) != pcm_buffer_size){  
            // Loop  
            fseek(fp, 0, SEEK_SET);  
            fread(pcm_buffer, 1, pcm_buffer_size, fp);  
            data_count=0;  
        }  
        printf("Now Playing %10d Bytes data.\n",data_count);  
        data_count+=pcm_buffer_size;  
        //Set audio buffer (PCM data)  
        audio_chunk = (Uint8 *) pcm_buffer;   
        //Audio buffer length  
        audio_len =pcm_buffer_size;  
        audio_pos = audio_chunk;  
          
        while(audio_len>0)//Wait until finish  
            SDL_Delay(1);   
    }  
    free(pcm_buffer);  
    SDL_Quit();  
  
    return 0;  
}  

蔡军生


老蔡学堂




发布了2059 篇原创文章 · 获赞 574 · 访问量 767万+
展开阅读全文

关于SDL音频播放没声音的问题~

06-30

开始光播放视频正常,但加上音频线程后,不但没有声音,而且连视频也卡在了一帧上,求教,谢谢~ # videoplay.cpp #include "videoplay.h" videoplay::videoplay(){ pFormatContext = avformat_alloc_context(); pFrame = avcodec_alloc_frame(); pFrameRGB = avcodec_alloc_frame(); pktQueue = new packetQueue(); pktQueueAudio = new packetQueue(); } void videoplay::reset(){ av_free(pFormatContext); pFormatContext = avformat_alloc_context(); av_free(pFrame); pFrame = avcodec_alloc_frame(); av_free(pFrameRGB); pFrameRGB = avcodec_alloc_frame(); delete pktQueue; packetQueue_init(); } //打开视频文件,获取解码器 int videoplay::open_file(){ av_register_all(); if( avformat_open_input(&pFormatContext, path.c_str(), NULL, NULL )!=0 ) return -1; if( av_find_stream_info(pFormatContext)<0 ) return -1; av_dump_format(pFormatContext, 0, path.c_str(), 0); videoStream = -1; audioStream = -1; for( unsigned int i=0;i<pFormatContext->nb_streams;i++ ){ if( pFormatContext->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO ){ videoStream = i; } else if( pFormatContext->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO ){ audioStream = i; } } if( videoStream==-1 ) return -1; if( audioStream==-1 ) return -1; // video pCodecContext = pFormatContext->streams[videoStream]->codec; pCodec = avcodec_find_decoder(pCodecContext->codec_id); // audio aCodecContext = pFormatContext->streams[audioStream]->codec; aCodec = avcodec_find_decoder(aCodecContext->codec_id); if( pCodec==NULL || aCodec==NULL ) return -1; // video if( avcodec_open2( pCodecContext, pCodec, NULL )<0 ) return -1; ud *userdata = (ud*) malloc(sizeof(ud)); userdata->aCodecContext = aCodecContext; userdata->vp = this; // audio wanted_spec = (SDL_AudioSpec*) av_mallocz(sizeof(SDL_AudioSpec)); wanted_spec->freq = aCodecContext->sample_rate; wanted_spec->format = AUDIO_S16SYS; wanted_spec->channels = aCodecContext->channels; wanted_spec->silence = 0; wanted_spec->samples = SDL_AUDIO_BUFFER_SIZE; wanted_spec->callback = audio_callback; wanted_spec->userdata = userdata; if( SDL_OpenAudio(wanted_spec, NULL)<0 ) return -1; av_free(pCodec); av_free(aCodec); } //获取包,加入队列 int videoplay::getPackets(){ int numBytes; packetQueue_init(); pFrame = avcodec_alloc_frame(); pFrameRGB = avcodec_alloc_frame(); if( pFrame==NULL || pFrameRGB==NULL ) return -1; numBytes = avpicture_get_size( PIX_FMT_RGB24, pCodecContext->width, pCodecContext->height ); buffer = (uint8_t*)av_malloc(numBytes*sizeof(uint8_t)); avpicture_fill( (AVPicture*)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecContext->width, pCodecContext->height ); AVPacket packet; while( av_read_frame(pFormatContext, &packet)>=0 ){ if( packet.stream_index==videoStream ) packetQueue_put( pktQueue, &packet ); if( packet.stream_index==audioStream ) packetQueue_put( pktQueueAudio, &packet ); } av_free(pCodecContext); } void videoplay::packetQueue_init(){ pktQueue = (packetQueue*)malloc(sizeof(packetQueue)); memset( pktQueue, 0, sizeof(packetQueue) ); pktQueue->mutex = SDL_CreateMutex(); pktQueue->cond = SDL_CreateCond(); pktQueueAudio = (packetQueue*)malloc(sizeof(packetQueue)); memset( pktQueueAudio, 0, sizeof(packetQueue) ); pktQueueAudio->mutex = SDL_CreateMutex(); pktQueueAudio->cond = SDL_CreateCond(); } bool videoplay::packetQueue_get(packetQueue *pktQueue, AVPacket *packet){ int ret = 0; //quit=0; AVPacketList *pkt1; SDL_LockMutex(pktQueue->mutex); if(pktQueue->nb_packets<=VIDEO_BUFFER_MIN_SIZE){ SDL_CondSignal(pktQueue->cond); } while(1) { pkt1=pktQueue->first; if(pkt1) { pktQueue->first=pkt1->next; if(!pktQueue->first)pktQueue->last=NULL; pktQueue->nb_packets--; *packet = pkt1->pkt; av_free(pkt1); ret=1; break; } else { SDL_CondWait(pktQueue->cond,pktQueue->mutex); } } SDL_UnlockMutex(pktQueue->mutex); return ret; } //往队列加包 void videoplay::packetQueue_put(packetQueue *pktQueue, AVPacket *packet){ AVPacketList *pkt1=(AVPacketList*)av_malloc(sizeof(AVPacketList)); pkt1->pkt=*packet; pkt1->next=NULL; SDL_LockMutex( pktQueue->mutex); if( pktQueue->nb_packets>=VIDEO_BUFFER_MAX_SIZE ){ SDL_CondWait( pktQueue->cond, pktQueue->mutex ); } if(!pktQueue->last) pktQueue->first=pkt1; else pktQueue->last->next=pkt1; pktQueue->last=pkt1; pktQueue->nb_packets++; if( pktQueue->nb_packets>=VIDEO_BUFFER_MIN_SIZE ){ SDL_CondSignal(pktQueue->cond); } SDL_CondSignal(pktQueue->cond); SDL_UnlockMutex(pktQueue->mutex); return ; } QImage* videoplay::play(QImage &image){ AVPacket *packet = new AVPacket(); struct SwsContext *pSwsCtx; int frameFinished; while( packetQueue_get( pktQueue, packet) ){ avcodec_decode_video2( pCodecContext, pFrame, &frameFinished, packet ); if( frameFinished ){ pSwsCtx = sws_getContext( pCodecContext->width, pCodecContext->height,pCodecContext->pix_fmt, pCodecContext->width, pCodecContext->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL ); sws_scale (pSwsCtx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecContext->height, pFrameRGB->data, pFrameRGB->linesize); bmp->pixels[0] = pFrameRGB->data[0]; bmp->pixels[1] = pFrameRGB->data[2]; bmp->pixels[2] = pFrameRGB->data[1]; bmp->pitches[0] = pFrameRGB->linesize[0]; bmp->pitches[1] = pFrameRGB->linesize[2]; bmp->pitches[2] = pFrameRGB->linesize[1]; SDL_UnlockYUVOverlay(bmp); rect.x=0; rect.y=0; rect.w=pCodecContext->width; rect.h=pCodecContext->height; SDL_DisplayYUVOverlay(bmp,&rect); */ memcpy( buffer,pFrameRGB,sizeof(AVFrame) ); QImage tmpImage( (uchar*)buffer, pCodecContext->width, pCodecContext->height, QImage::Format_RGB888 ); image = tmpImage.copy(); SDL_Delay(40); int i = 0; return ℑ } } return NULL; } int videoplay::audio_decode_frame( videoplay *vp, AVCodecContext *aCodecContext, Uint8 *audio_buf, int buf_size ){ static AVPacket pkt; static Uint8 *audio_pkt_data = NULL; static int audio_pkt_size = 0; int len_1, data_size; while(1){ while(audio_pkt_size>0){ data_size = buf_size; len_1 = avcodec_decode_audio3( aCodecContext, (int16_t*)audio_buf, &data_size, &pkt); if( len_1<0 ){ audio_pkt_size = 0; break; } audio_pkt_data = audio_pkt_data + len_1; audio_pkt_size = audio_pkt_size - len_1; if( data_size<=0 ) continue; return data_size; } if(pkt.data) av_free_packet(&pkt); if( vp->packetQueue_get(vp->pktQueueAudio, &pkt)==0 ) return -1; audio_pkt_data = pkt.data; audio_pkt_size = pkt.size; } } void videoplay::audio_callback( void*userdata, Uint8 *stream, int len ){ ud *udata = (ud*)userdata; AVCodecContext *aCodecContext = udata->aCodecContext; videoplay *vp = udata->vp; int len_1, audio_size; static Uint8 audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE*3/2]; static unsigned int audio_buf_size = 0; static unsigned int audio_buf_index = 0; while( len>0 ){ if( audio_buf_index>=audio_buf_size ){ audio_size = audio_decode_frame( vp, aCodecContext, audio_buf, sizeof(audio_buf) ); if( audio_size<0 ){ audio_buf_size = 1024; memset( audio_buf, 0 , audio_buf_size ); } else audio_buf_size = audio_size; audio_buf_index = 0; } } len_1 = audio_buf_size - audio_buf_index; if( len_1>len ) len_1 = len; // memcpy( stream, (Uint8*)audio_buf+audio_buf_index, len_1 ); SDL_MixAudio(stream,(Uint8*)audio_buf+audio_buf_index, len_1, SDL_MIX_MAXVOLUME ); len = len - len_1; stream = stream + len_1; audio_buf_index = audio_buf_index + len_1; } # mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include <Windows.h> #include "videoplay.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connect( this, SIGNAL(readOneFrame(QPixmap)), this, SLOT(setPic(QPixmap)) ); } MainWindow::~MainWindow() { delete ui; } int threadFunc( void *arg){ videoplay *vp = (videoplay*)arg; vp->getPackets(); return 1; } int MainWindow::threadFunc_1( void *arg){ MainWindow *mainWindow = (MainWindow*)arg; QImage *image = new QImage(); while( mainWindow->vp.play(*image) ){ QPixmap pixmap = QPixmap::fromImage(image->scaled(mainWindow->ui->label->size(), Qt::KeepAspectRatio)); emit mainWindow->readOneFrame(pixmap); Sleep(1); mainWindow->state = 1; } delete image; return 1; } int threadFunc_2( void *arg){ while(1) SDL_PauseAudio(5); return 1; } void MainWindow::closeEvent(QCloseEvent *event){ SDL_KillThread(decodeTid); SDL_KillThread(videoTid); SDL_KillThread(audioTid); } void MainWindow::on_pushButton_clicked() //打开,获取到视频文件路径 path { vp.reset(); QFileDialog* fileDialog = new QFileDialog(this); QString path = fileDialog->getOpenFileName(this, "打开", ".", "Video Files(*.mp4 *.avi,*rmvb);;all(*)", 0, 0); decodeTid=NULL; videoTid=NULL; if( path.length()!=0 ){ if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) ) return ; ui->label->setText( path ); vp.setPath(path.toStdString()); vp.open_file(); decodeTid = SDL_CreateThread(threadFunc,&vp); videoTid = SDL_CreateThread(threadFunc_1,this); SDL_PauseAudio(0); audioTid = SDL_CreateThread(threadFunc_2,NULL); } } void MainWindow::on_pushButton_2_clicked() //快退 { } void MainWindow::on_pushButton_3_clicked() //播放/停止 { if( state==1 ){ //点击后暂停 ui->pushButton_3->setText(tr("暂停")); state = 0; } else{ ui->pushButton_3->setText(tr("播放")); //点击后播放 state = 1; } } void MainWindow::on_pushButton_4_clicked() //快进 { } void MainWindow::setPic(QPixmap pixmap){ ui->label->setPixmap(pixmap); ui->label->repaint(); } 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览