ffplay on SDL2

背景介绍

SDL2官方已支持android了, 而git ffmpeg 上还是沿用老的SDL1.2。据目前我搜索的信息,目前还没有ffplay在sdl2上跑的实例。 能把ffplay 放到android上跑,也算是为开源社区尽一份绵薄之力。


计划

avplay -- 简单的视频播放,使用SDL2, 在PC上测试。

ffplay -- 完整的音视频播放,使用SDL2, 在PC上测试。

configure -- 修改支持SDL2自动编译。

移植SDL2 到android 手机上。

移植完整版ffmpeg/ffplay 到android手机上。


下载和准备

由于我在两个地方使用windows xp 和ubuntu14.04,而ubuntu上编译异常顺利。下面介绍xp上的编译环境。


目前的2.0.3 msys 编译不过, 需要用hg上的:
http://www.libsdl.org/hg.php
http://www.libsdl.org/tmp/SDL-2.0.4-9174.tar.gz

如果想偷懒(xp上编译实在很慢):

http://ffmpeg.zeranoe.com/builds/win32/dev/ffmpeg-20141204-git-5fe026f-win32-dev.7z

http://ffmpeg.zeranoe.com/builds/win32/shared/ffmpeg-20141204-git-5fe026f-win32-shared.7z

都解压到/e/tools/Players/ffmpeg下面。

然后在/etc/profile 加上PATH="/e/tools/Player/ffmpeg/bin":$PATH


编译

cd SDL-2.0.4-9174

./configure --prefix=$HOME/porting/host && make && make install

./configure --with-sdl-prefix=/e/ludi/porting/host

make -- 编不过,见下面的注意事项0。

然后就是下面头文件里面的:

/*
../ffmpeg/configure --prefix=$HOME/porting/host \
 --disable-outdev=sdl --disable-ffplay \
 --enable-version3 --enable-nonfree --disable-optimizations \
 --enable-gpl --enable-libx264 
make -j16 && make install
export PKG_CONFIG_PATH=$HOME/porting/host/lib/pkgconfig

compile:
gcc avplay.c -g $(~/porting/host/bin/sdl2-config --cflags --libs) \
$(pkg-config --cflags libavcodec --libs libavcodec libavformat libavutil)

on windows:
gcc avplay.c -g $(~/porting/host/bin/sdl2-config --cflags --libs) \
-I/e/tools/Player/ffmpeg/include/ -L/e/tools/Player/ffmpeg/lib/ -lavformat -lavcodec -lswresample -lavutil -lm


*/
#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      

#include 
      
      
       
       
#include 
       
       
         int main(int ac, char **av) { AVFormatContext *fmtctx = NULL; int ret, i, vidx = -1; AVCodecContext *cdctx = NULL; AVCodec *dec = NULL; AVPacket pkt; AVFrame *frame; SDL_Rect rect; SDL_Window *win; SDL_Renderer *render; SDL_Texture *texture; SDL_Event evt; if(ac < 2){ return printf("usage: play infile\n"); } av_register_all(); ret = avformat_open_input(&fmtctx, av[1], NULL, NULL); if(ret < 0){ return printf("cant open %s\n", av[1]); } ret = avformat_find_stream_info(fmtctx, NULL); if(ret < 0){ return printf("cant find stream\n"); } av_dump_format(fmtctx, 0, av[1], 0); for(i = 0; i < fmtctx->nb_streams; ++i){ if(fmtctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){ vidx = i; break; } } if(-1 == vidx){ return printf("no video stream\n"); } cdctx = fmtctx->streams[vidx]->codec; if(cdctx->pix_fmt != AV_PIX_FMT_YUV420P){ return printf("unkown pix fmt %d\n", cdctx->pix_fmt); } dec = avcodec_find_decoder(cdctx->codec_id); if(!dec){ return printf("no decoder\n"); } ret = avcodec_open2(cdctx, dec, NULL); if(ret < 0){ return printf("cant open dec\n"); } frame = av_frame_alloc(); rect.x = rect.y = 0; rect.w = cdctx->width; rect.h = cdctx->height; if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)){ return printf("cant init: %s\n", SDL_GetError()); } win = SDL_CreateWindow(av[1], SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, cdctx->width, cdctx->height, 0); if(!win){ return printf("cant create win mode\n"); } render = SDL_CreateRenderer(win, -1, SDL_RENDERER_TARGETTEXTURE); texture = SDL_CreateTexture(render, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, cdctx->width, cdctx->height); if(!texture){ return printf("cant create texture\n"); } #if 1 void *pixels = 0; int pitch = 0; unsigned char *d = NULL; SDL_LockTexture(texture, NULL, &pixels, &pitch); d = (unsigned char *)pixels;//U ? cdctx->height*pitch; printf("pixels/pitch %p/%u -- %02x %02x %02x %02x\n", pixels, pitch, d[0], d[1], d[2], d[3]); SDL_UnlockTexture(texture); #endif while(av_read_frame(fmtctx, &pkt) >= 0){ if(pkt.stream_index == vidx){ avcodec_decode_video2(cdctx, frame, &ret, &pkt); if(ret){ SDL_UpdateYUVTexture(texture, NULL, frame->data[0], frame->linesize[0], frame->data[1], frame->linesize[1], frame->data[2], frame->linesize[2]); SDL_RenderClear(render); SDL_RenderCopy(render, texture, &rect, &rect); SDL_RenderPresent(render); } SDL_Delay(50); } av_free_packet(&pkt); SDL_PollEvent(&evt); if(SDL_QUIT == evt.type){ break; } } SDL_Quit(); av_free(frame); avcodec_close(cdctx); avformat_close_input(&fmtctx); return 0; } 
       
      
      
     
     
    
    
   
   

注意事项

0. hg版本的sd2-config 需要改成:

    --libs|--static-libs)
      echo -L${exec_prefix}/lib  -lmingw32 -lSDL2main -lSDL2  -Wl,--no-undefined -lm -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid  -static-libgcc

1. 要把SDL2.dll 拷贝到 SDL-2.0.4-9174/test 下面才能跑那些例子。

2.确保ffmpeg相关dll在PATH里面。


小结

第一步算是走出来了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值