ffmpeg+SDL  linux下最简单的播放器

#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h" 

#include "SDL/SDL.h"  
#include "SDL/SDL_thread.h" 

int main(int argc ,char *argv[])
{
//与解复用相关的结构体
AVFormatContext   *pFormatCtx;
int i,videoindex;
//编解码相关结构体
AVCodecContext    *pCodeCtx;
AVCodec           *pCode;
//char filepath[]={"a.ts"};
av_register_all();
avformat_network_init();
pFormatCtx=avformat_alloc_context();
if(argc<2)
{
printf("please  input inputfile !!! \n");
return  -1;
}
//打开输入文件
if(avformat_open_input(&pFormatCtx,argv[1],NULL,NULL))
{
printf("could't open input file %s\n",argv[1]);
return -1;
}
//得到相关流信息
if(avformat_find_stream_info(pFormatCtx,NULL)<0)
{
printf("couldn't find stream information\n");
return  -1;
}
videoindex =-1;
//找到相关视频流的索引
for(i=0;i<pFormatCtx->nb_streams;i++)
{
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
{
videoindex=i;
break;
}
}


if(videoindex==-1)
{
printf("没有找到视频流\n");
return -1;
}
//查找解码器
pCodeCtx=pFormatCtx->streams[videoindex]->codec;
pCode=avcodec_find_decoder(pCodeCtx->codec_id);
if(pCode==NULL)
{
printf("不能找到解码器\n");
return  -1;
}
//打开视频流以便后面使用
if(avcodec_open2(pCodeCtx,pCode,NULL)<0)
{
printf("无法打开解码器\n");
return -1;
}


//开辟内存
AVFrame *pFrame,*pFrameYUV;
pFrame=avcodec_alloc_frame();  
pFrameYUV=avcodec_alloc_frame();  


printf("--------------\n");
uint8_t *out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodeCtx->width, pCodeCtx->height));  
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodeCtx->width, pCodeCtx->height);
//----SDL----
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
{
printf("不能初始化SDL\n");
return  -1;





int screen_w=0,screen_h=0;  
SDL_Surface *screen;   
#if SHOW_FULLSCREEN  
const SDL_VideoInfo *vi = SDL_GetVideoInfo();  
screen_w = vi->current_w;  
screen_h = vi->current_h;  
screen = SDL_SetVideoMode(screen_w, screen_h, 0,SDL_FULLSCREEN);  
#else  
screen_w = pCodeCtx->width;  
screen_h = pCodeCtx->height;  
screen = SDL_SetVideoMode(screen_w, screen_h, 0,0);  
#endif  


if(!screen)
{    
printf("SDL: could not set video mode - exiting:%s\n",SDL_GetError());    
return -1;  
}  
SDL_Overlay *bmp;   
bmp = SDL_CreateYUVOverlay(pCodeCtx->width, pCodeCtx->height,SDL_YV12_OVERLAY, screen);   
SDL_Rect rect; 
int ret, got_picture;
AVPacket *packet=(AVPacket *)av_malloc(sizeof(AVPacket));


printf("File Information(文件信息)---------------------\n");  
av_dump_format(pFormatCtx,0,argv[1],0);  
printf("-------------------------------------------------\n");


struct SwsContext *img_convert_ctx;


img_convert_ctx = sws_getContext(pCodeCtx->width, pCodeCtx->height, pCodeCtx->pix_fmt, pCodeCtx->width, pCodeCtx->height, PIX_FMT_YUV420P,SWS_BICUBIC, NULL, NULL, NULL);   
// 循环读取数据包
while(av_read_frame(pFormatCtx, packet)>=0)  
{  
if(packet->stream_index==videoindex)  
{  
ret = avcodec_decode_video2(pCodeCtx, pFrame, &got_picture, packet);  
if(ret < 0)  
{  
printf("Decode Error.(解码错误)\n");  
return -1;  
}  
if(got_picture)  
{  
//转换视频输出格式
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodeCtx->height, pFrameYUV->data, pFrameYUV->linesize);  


#if OUTPUT_YUV420P  
int y_size=pCodecCtx->width*pCodecCtx->height;    
fwrite(pFrameYUV->data[0],1,y_size,fp_yuv);    //Y   
fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv);  //U  
fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv);  //V  
#endif  
SDL_LockYUVOverlay(bmp);  
bmp->pixels[0]=pFrameYUV->data[0];  
bmp->pixels[2]=pFrameYUV->data[1];  
bmp->pixels[1]=pFrameYUV->data[2];       
bmp->pitches[0]=pFrameYUV->linesize[0];  
bmp->pitches[2]=pFrameYUV->linesize[1];     
bmp->pitches[1]=pFrameYUV->linesize[2];  
SDL_UnlockYUVOverlay(bmp);   
rect.x = 0;      
rect.y = 0;      
rect.w = screen_w;      
rect.h = screen_h;    
//测试自己填充数据----------------  
SDL_DisplayYUVOverlay(bmp, &rect);   
//延时40ms  
// SDL_Delay(40);  
}  
}  
av_free_packet(packet);  
}  
sws_freeContext(img_convert_ctx);  


#if OUTPUT_YUV420P   
fclose(fp_yuv);  
#endif   
SDL_Quit();  
av_free(out_buffer);  
av_free(pFrameYUV);  
avcodec_close(pCodeCtx);  
avformat_close_input(&pFormatCtx);  

return 0;   
}


编译选项:
gcc   play2.c  -omain  -I/home/fengfei/ffmpeg_Bin/include   -L/home/fengfei/ffmpeg_Bin/lib  -lavformat -lavdevice  -lavcodec -lavutil  -lpthread  -l
        swscale -lswresample -lSDL  -lbz2    -lz -lm  -lrt 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值