Ffmpeg学习进阶二----ffplay的使用和分析

Ffmpeg中的ffplay的使用和分析

1、默认的ffmpeg中没有编译fffplay(可能是因为ffplay引用了SDL库,而SDL库需要另外下载),config后,确认Makefile中指定的config.mak(在ffmpeg根目录下)中:CONFIG_FFPLAY=yes,如果不是需要重新./configure

2、下载SDL媒体库库,类似于QT,MW等图像引擎,这个SDL库是视频显示时用,编译时需要安装libsdl1.2-dev,命令为sudo apt-get install libsdl1.2-dev,如果安装失败,之前如果安装过sdl-devel包最好将其卸载。根据错误原因来解决。

3、make,结束后发现ffplay已经生成了

4、make install

目前在ubuntu12.04上播放视频,会出现问题,会报如下错,

t@ubuntu:/home/hfl/hflsamb/ffmpeg-1.2.4# ./ffplay abc.avi 
ffplay version 1.2.4 Copyright (c) 2003-2013 the FFmpeg developers
  built on Feb  6 2014 06:38:02 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: 
  libavutil      52. 18.100 / 52. 18.100
  libavcodec     54. 92.100 / 54. 92.100
  libavformat    54. 63.104 / 54. 63.104
  libavdevice    54.  3.103 / 54.  3.103
  libavfilter     3. 42.103 /  3. 42.103
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
Input #0, avi, from 'abc.avi':=    0KB vq=    0KB sq=    0B f=0/0   
  Metadata:
    encoder         : Lavf55.22.103
  Duration: 00:01:02.81, start: 0.000000, bitrate: 710 kb/s
    Stream #0:0    nan A-V:  0.000 fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0: Video: mpeg4 (Simple Profile) (FMP4 / 0x34504D46), yuv420p, 720x540 [SAR 135:136 DAR 45:34], 25 tbr, 25 tbn, 25 tbc
    Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 128 kb/s
X Error of failed request:  BadAlloc (insufficient resources for operation)
  Major opcode of failed request:  134 (XVideo)
  Minor opcode of failed request:  19 ()
  Serial number of failed request:  25
  Current serial number in output stream:  26

google一下,很多人遇到同样的问题,是12.04版本的一个bug,有很多网友是通过修改/etc/X11/navia_cofnig文件的一个参数来完成,但我的系统没有这个文件,重新安装显卡驱动,繁琐。而以外在ubuntu9.10上没问题,所以目前开发的思路是:ubuntu12.04 开发,ubuntu9.10上测试验证(因为ubuntu9.10太老,很多source已经关闭,也懒得去更换源了)

Ffplay 除了可以播放文件,也可以播放网络。即file ,udp,http都支持

ffplay.exe http://192.168.1.108/myserver/ctl.mp3

ffplay.exe ctl.avi

ffplay基本框架分析:

1.      初始化化工作:注册解码器,编码器,demux.mux,网络等 

    avcodec_register_all();

#if CONFIG_AVDEVICE

    avdevice_register_all();

#endif

#if CONFIG_AVFILTER

    avfilter_register_all();

#endif

    av_register_all();

    avformat_network_init();

av_register_all();

包含编解码器资源,demux资源,拉流协议资源

这里注册了所有的文件格式和编解码器的库,所以它们将被自动的使用在被打开的合适格式的文件上。注意你只需要调用 av_register_all()一次,因此我们在主函数main()中来调用它。如果你喜欢,也可以只注册特定的格式和编解码器,但是通常你没有必要这样做。

注意av_register_all();包含 avcodec_register_all(); 所以在ffplay中注册avcodec_register_all();是多余的。不过没有关系,每次注册都要检测是否已经注册了,如果已经注册了,就不会第二次注册了

2.      解析命令行,打显示banner信息

     show_banner(argc, argv, options);

     parse_options(NULL, argc, argv, options,opt_input_file);

3.      初始化SDL(因为视频显示是基于SDL媒体框架,所以必须出示SDL)

SDL_Init()

4.      初始化化AVPacket;(改结构体描述音视频的属性信息,如pts,dts,pos,duration等)

av_init_packet(&flush_pkt);

5.      打开流对象,进行解码播放

   stream_open(input_filename,file_iformat);

   ffplay核心就在这个函数,这个函数创建了一个read_thread,线程完成了拉流(读文件),demux(解析,解复用),decoder(解码),display(显示)动作,即完成读文件模块(source filter),解复用模块(Demux filter),视/音频解码模块(Decode filter),颜色空间转换模块(Color Space converter filter),视频/音频播放模块(Renderfilter)三个模块的过程。

6.      事件处理event_loop(is);

event_loop(is);就是一个死循环,不断接受外部事件的动作,完成对播放的控制,如暂停,快进,快退,resume,窗口缩放等。这些事件来自于SDL从GUI中获取,触发源主要是鼠标和键盘的动作。

这样5,6动作就是实现了主线程完成播放控制,子线程完成解码播放的动作。主线程在循环中,由于某种外部事件触发,改变全局的播放控制变量,而子线程在每解码一帧前都要判断该控制变量,进而决定trick的动作或窗口的大小。

stream_open(input_filename, file_iformat)函数的简要分析:

1.      为VideoState分配内存

2.        av_strlcpy(is->filename, filename,sizeof(is->filename));将文件名赋给VideoState

初始化VideoState其他成员。

3.         创建read_thread 线程

read_thread 的分析

avformat_open_input()完成各种协议拉流(读文件)动作

av_find_best_stream()找到因视频流,字幕流

stream_component_open()打开音视频流并音打开视频解码器并创建

video_thread(),subtitle_thread()进行解码

refresh_thread()开启屏幕视频显示刷新线程

av_read_frame()将音视频读取,解析并写入解码器

猜你喜欢

转载自blog.csdn.net/special00/article/details/82596796