ffmpeg+sdl 播放器最新代码.docx

上传人:b****5 文档编号:7655467 上传时间:2023-01-25 格式:DOCX 页数:24 大小:21.55KB
下载 相关 举报
ffmpeg+sdl 播放器最新代码.docx_第1页
第1页 / 共24页
ffmpeg+sdl 播放器最新代码.docx_第2页
第2页 / 共24页
ffmpeg+sdl 播放器最新代码.docx_第3页
第3页 / 共24页
ffmpeg+sdl 播放器最新代码.docx_第4页
第4页 / 共24页
ffmpeg+sdl 播放器最新代码.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

ffmpeg+sdl 播放器最新代码.docx

《ffmpeg+sdl 播放器最新代码.docx》由会员分享,可在线阅读,更多相关《ffmpeg+sdl 播放器最新代码.docx(24页珍藏版)》请在冰豆网上搜索。

ffmpeg+sdl 播放器最新代码.docx

ffmpeg+sdl播放器最新代码

#include"libavformat/avformat.h"

#include"libswscale/swscale.h"

//#include

#include

#include

#include

#include

#include

#include

#ifdefmain

#undefmain

#endif

#defineSDL_AUDIO_BUFFER_SIZE1024

#defineMAX_AUDIOQ_SIZE(5*16*1024)

#defineMAX_VIDEOQ_SIZE(5*256*1024)

#defineFF_ALLOC_EVENT(SDL_USEREVENT)

#defineFF_REFRESH_EVENT(SDL_USEREVENT+1)

#defineFF_QUIT_EVENT(SDL_USEREVENT+2)

#defineVIDEO_PICTURE_QUEUE_SIZE1

#defineSDL_AUDIO_BUFFER_SIZE1024

staticintsws_flags=SWS_BICUBIC;

typedefstructPacketQueue

{

AVPacketList*first_pkt,*last_pkt;

intnb_packets;

intsize;

SDL_mutex*mutex;

SDL_cond*cond;

}PacketQueue;

typedefstructVideoPicture

{

SDL_Overlay*bmp;

intwidth,height;

intallocated;

}VideoPicture;

typedefstructVideoState

{

AVFormatContext*pFormatCtx;

intvideoStream,audioStream;

AVStream*audio_st;

PacketQueueaudioq;

uint8_taudio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE*3)/2];

unsignedintaudio_buf_size;

unsignedintaudio_buf_index;

AVPacketaudio_pkt;

uint8_t*audio_pkt_data;

intaudio_pkt_size;

AVStream*video_st;

PacketQueuevideoq;

VideoPicturepictq[VIDEO_PICTURE_QUEUE_SIZE];

intpictq_size,pictq_rindex,pictq_windex;

SDL_mutex*pictq_mutex;

SDL_cond*pictq_cond;

SDL_Thread*parse_tid;

SDL_Thread*video_tid;

charfilename[1024];

intquit;

}VideoState;

SDL_Surface*screen;

VideoState*global_video_state;

voidpacket_queue_init(PacketQueue*q)

{

memset(q,0,sizeof(PacketQueue));

q->mutex=SDL_CreateMutex();

q->cond=SDL_CreateCond();

}

intpacket_queue_put(PacketQueue*q,AVPacket*pkt)

{

AVPacketList*pkt1;

if(av_dup_packet(pkt)<0)

{

return-1;

}

pkt1=(AVPacketList*)av_malloc(sizeof(AVPacketList));

if(!

pkt1)

return-1;

pkt1->pkt=*pkt;

pkt1->next=NULL;

SDL_LockMutex(q->mutex);

if(!

q->last_pkt)

q->first_pkt=pkt1;

else

q->last_pkt->next=pkt1;

q->last_pkt=pkt1;

q->nb_packets++;

q->size+=pkt1->pkt.size;

SDL_CondSignal(q->cond);

SDL_UnlockMutex(q->mutex);

return0;

}

staticintpacket_queue_get(PacketQueue*q,AVPacket*pkt,intblock)

{

AVPacketList*pkt1;

intret;

SDL_LockMutex(q->mutex);

for(;;)

{

if(global_video_state->quit)

{

ret=-1;

break;

}

pkt1=q->first_pkt;

if(pkt1)

{

q->first_pkt=pkt1->next;

if(!

q->first_pkt)

q->last_pkt=NULL;

q->nb_packets--;

q->size-=pkt1->pkt.size;

*pkt=pkt1->pkt;

av_free(pkt1);

ret=1;

break;

}

elseif(!

block)

{

ret=0;

break;

}

else

{

SDL_CondWait(q->cond,q->mutex);

}

}

SDL_UnlockMutex(q->mutex);

returnret;

}

intaudio_decode_frame(VideoState*is,uint8_t*audio_buf,intbuf_size)

{

intlen1,data_size;

AVPacket*pkt=&is->audio_pkt;

for(;;)

{

while(is->audio_pkt_size>0)

{

data_size=buf_size;

len1=avcodec_decode_audio2(is->audio_st->codec,

(int16_t*)audio_buf,&data_size,

is->audio_pkt_data,is->audio_pkt_size);

if(len1<0)

{

is->audio_pkt_size=0;

break;

}

is->audio_pkt_data+=len1;

is->audio_pkt_size-=len1;

if(data_size<=0)

{

continue;

}

returndata_size;

}

if(pkt->data)

av_free_packet(pkt);

if(is->quit)

{

return-1;

}

if(packet_queue_get(&is->audioq,pkt,1)<0)

{

return-1;

}

is->audio_pkt_data=pkt->data;

is->audio_pkt_size=pkt->size;

}

}

voidaudio_callback(void*userdata,Uint8*stream,intlen)

{

VideoState*is=(VideoState*)userdata;

intlen1,audio_size;

while(len>0)

{

if(is->audio_buf_index>=is->audio_buf_size)

{

audio_size=audio_decode_frame(is,is->audio_buf,sizeof(is->audio_buf));

if(audio_size<0)

{

is->audio_buf_size=1024;

memset(is->audio_buf,0,is->audio_buf_size);

}

else

{

is->audio_buf_size=audio_size;

}

is->audio_buf_index=0;

}

len1=is->audio_buf_size-is->audio_buf_index;

if(len1>len)

len1=len;

memcpy(stream,(uint8_t*)is->audio_buf+is->audio_buf_index,len1);

len-=len1;

stream+=len1;

is->audio_buf_index+=len1;

}

}

staticUint32sdl_refresh_timer_cb(Uint32interval,void*opaque)

{

//printf("sdl_refresh_timer_cbcalled:

interval--%d\n",interval);

SDL_Eventevent;

event.type=FF_REFRESH_EVENT;

event.user.data1=opaque;

SDL_PushEvent(&event);//派发FF_REFRESH_EVENT事件

return0;

}

staticvoidschedule_refresh(VideoState*is,intdelay)

{

//printf("schedule_refreshcalled:

delay--%d\n",delay);

SDL_AddTimer(delay,sdl_refresh_timer_cb,is);//sdl_refresh_timer_cb函数在延时delay毫秒后,只会被执行一次,is是sdl_refresh_timer_cb的参数

}

voidvideo_display(VideoState*is)

{

//printf("video_displaycalled\n");

SDL_Rectrect;

VideoPicture*vp;

AVPicturepict;

floataspect_ratio;

intw,h,x,y;

inti;

vp=&is->pictq[is->pictq_rindex];

if(vp->bmp)

{

if(is->video_st->codec->sample_aspect_ratio.num==0)

{

aspect_ratio=0;

}

else

{

aspect_ratio=av_q2d(is->video_st->codec->sample_aspect_ratio)*

is->video_st->codec->width/is->video_st->codec->height;

}

if(aspect_ratio<=0.0)//aspect_ratio宽高比

{

aspect_ratio=(float)is->video_st->codec->width/

(float)is->video_st->codec->height;

}

h=screen->h;

w=((int)(h*aspect_ratio))&-3;

if(w>screen->w)

{

w=screen->w;

h=((int)(w/aspect_ratio))&-3;

}

x=(screen->w-w)/2;

y=(screen->h-h)/2;

rect.x=x;

rect.y=y;

rect.w=w;

rect.h=h;

SDL_DisplayYUVOverlay(vp->bmp,&rect);

}

}

voidvideo_refresh_timer(void*userdata)

{

VideoState*is=(VideoState*)userdata;

VideoPicture*vp;

if(is->video_st)

{

if(is->pictq_size==0)

{

schedule_refresh(is,1);

}

else

{

vp=&is->pictq[is->pictq_rindex];

schedule_refresh(is,80);

video_display(is);

if(++is->pictq_rindex==VIDEO_PICTURE_QUEUE_SIZE)

{

is->pictq_rindex=0;

}

SDL_LockMutex(is->pictq_mutex);

is->pictq_size--;

SDL_CondSignal(is->pictq_cond);

SDL_UnlockMutex(is->pictq_mutex);

}

}

else

{

schedule_refresh(is,100);

}

}

voidalloc_picture(void*userdata)

{

VideoState*is=(VideoState*)userdata;

VideoPicture*vp;

vp=&is->pictq[is->pictq_windex];

if(vp->bmp)

{

//wealreadyhaveonemakeanother,bigger/smaller

SDL_FreeYUVOverlay(vp->bmp);

}

//AllocateaplacetoputourYUVimageonthatscreen

vp->bmp=SDL_CreateYUVOverlay(is->video_st->codec->width,

is->video_st->codec->height,

SDL_YV12_OVERLAY,

screen);

vp->width=is->video_st->codec->width;

vp->height=is->video_st->codec->height;

SDL_LockMutex(is->pictq_mutex);

vp->allocated=1;

SDL_CondSignal(is->pictq_cond);

SDL_UnlockMutex(is->pictq_mutex);

}

intqueue_picture(VideoState*is,AVFrame*pFrame)

{

//printf("queue_picturecalled\n");

VideoPicture*vp;

intdst_pix_fmt;

AVPicturepict;

staticstructSwsContext*img_convert_ctx;

if(img_convert_ctx==NULL)

{

img_convert_ctx=sws_getContext(is->video_st->codec->width,is->video_st->codec->height,

is->video_st->codec->pix_fmt,

is->video_st->codec->width,is->video_st->codec->height,

PIX_FMT_YUV420P,

sws_flags,NULL,NULL,NULL);

if(img_convert_ctx==NULL)

{

fprintf(stderr,"Cannotinitializetheconversioncontext\n");

exit

(1);

}

}

SDL_LockMutex(is->pictq_mutex);

while(is->pictq_size>=VIDEO_PICTURE_QUEUE_SIZE&&

!

is->quit)

{

SDL_CondWait(is->pictq_cond,is->pictq_mutex);

}

SDL_UnlockMutex(is->pictq_mutex);

if(is->quit)

return-1;

//windexissetto0initially

vp=&is->pictq[is->pictq_windex];

if(!

vp->bmp||

vp->width!

=is->video_st->codec->width||

vp->height!

=is->video_st->codec->height)

{

SDL_Eventevent;

vp->allocated=0;

event.type=FF_ALLOC_EVENT;

event.user.data1=is;

SDL_PushEvent(&event);

SDL_LockMutex(is->pictq_mutex);

while(!

vp->allocated&&!

is->quit)

{

SDL_CondWait(is->pictq_cond,is->pictq_mutex);//没有得到消息时解锁,得到消息后加锁,和SDL_CondSignal配对使用

}

SDL_UnlockMutex(is->pictq_mutex);

if(is->quit)

{

return-1;

}

}

if(vp->bmp)

{

SDL_LockYUVOverlay(vp->bmp);

dst_pix_fmt=PIX_FMT_YUV420P;

pict.data[0]=vp->bmp->pixels[0];

pict.data[1]=vp->bmp->pixels[2];

pict.data[2]=vp->bmp->pixels[1];

pict.linesize[0]=vp->bmp->pitches[0];

pict.linesize[1]=vp->bmp->pitches[2];

pict.linesize[2]=vp->bmp->pitches[1];

//ConverttheimageintoYUVformatthatSDLuses

sws_scale(img_convert_ctx,pFrame->data,pFrame->linesize,

0,is->video_st->codec->height,pict.data,pict.linesize);

SDL_UnlockYUVOverlay(vp->bmp);

if(++is->pictq_windex==VIDEO_PICTURE_QUEUE_SIZE)

{

is->pictq_windex=0;

}

SDL_LockMutex(is->pictq_mutex);

is->pictq_size++;

SDL_UnlockMutex(is->pictq_mutex);

}

return0;

}

intvideo_thread(void*arg)

{

//printf("video_threadcalled");

VideoState*is=(VideoState*)arg;

AVPacketpkt1,*packet=&pkt1;

intlen1,frameFinished;

AVFrame*pFrame;

pFrame=avcodec_alloc_frame();

for(;;)

{

if(packet_queue_get(&is->videoq,packet,1)<0)

{

//meanswequitgettingpackets

break;

}

//Decodevideoframe

len1=avcodec_decode_video(is->video_st->codec,pFrame,&frameFinished,

packet->data,packet->size);

//Didwegetavideof

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1