ffmpeg学习笔记

2019-08-29 19:56

准备工作:

1.登录http://ffmpeg.zeranoe.com/builds/下载对应的开发版本 如xp32位系统下载FFmpeg 32-bit Dev Versions与FFmpeg 32-bit Shared Versions

中dev版本里有头文件与静态lib库,在开发的时候包含进工程,share版本里有程序运行发布时候需要的dll动态库。

2.在vs2010中配置inclue与lib

工程?属性?配置属性?c/c++?常规?附加包含目录?添加dev版本中的include路径

工程?属性?配置属性?链接器?常规?附加库目录?添加dev版本中的lib路径

工程?属性?配置属性?链接器?输入?附加依赖项?添加dev版本中的lib文件,具体包括:avcodec.lib,avformat.lib,avdevice.lib,avfilter.lib,avutil.lib,postproc.lib,swresample.lib,swscale.lib

3.在工程中引用ffmpeg头文件,因为ffmepeg是纯C程序,因此,在C++中包含其头文件需要加上extern “C”标识符,如:

extern \ {

#include \ #include \ }

4.工程调试运行时需要将dll添加至工程目录,具体包括:avcodec-55.dll,

avdevice-55.dll,avfilter-3.dll,avformat-55.dll,avutil-52.dll,postproc-52.dll,swresample-0.dll,swscale-2.dll

5.程序编译会报无法打开包括文件:“inttypes.h”: No such file or directory 原因是因为VS2010不支持inttypes.h。 解决方法删除,并在之前添加如下代码

#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) # define CONFIG_WIN32 #endif

#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(EMULATE_INTTYPES) #define EMULATE_INTTYPES #endif

#ifndef EMULATE_INTTYPES #include #else

typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t;

#ifdef CONFIG_WIN32

typedef signed __int64 int64_t; typedef unsigned __int64uint64_t; #else

typedef signed long long int64_t; typedef unsigned long long uint64_t; #endif #endif

6.打开一个视频文件:

首先调用av_register_all()初始化并注册视频文件格式与编解码库,注意只需要初始化一次。

然后调用avformat_open_input()打开具体的视频文件 如:

AVFormatContext *pFormatCtx = NULL; const char* filename = \; int ret;

if ((ret = avformat_open_input(&pFormatCtx,filename,NULL,NULL))<0) { }

abort();

其中avformat_open_input具体实现与参数含义

avformat_open_input

[cpp] view plaincopy

1. //参数ps包含一切媒体相关的上下文结构,有它就有了一切,本函数如果打开媒体成功, 2. //会返回一个AVFormatContext的实例. 3. //参数filename是媒体文件名或URL.

4. //参数fmt是要打开的媒体格式的操作结构,因为是读,所以是inputFormat.此处可以 5. //传入一个调用者定义的inputFormat,对应命令行中的 -f xxx段,如果指定了它, 6. //在打开文件中就不会探测文件的实际格式了,以它为准了.

7. //参数options是对某种格式的一些操作,是为了在命令行中可以对不同的格式传入 8. //特殊的操作参数而建的, 为了了解流程,完全可以无视它. 9. int avformat_open_input(AVFormatContext **ps, 10. const char *filename, 11. AVInputFormat *fmt, 12. AVDictionary **options) 13. {

14. AVFormatContext *s = *ps; 15. int ret = 0;

16. AVFormatParameters ap = { { 0 } }; 17. AVDictionary *tmp = NULL; 18.

19. //创建上下文结构

20. if (!s && !(s = avformat_alloc_context())) 21. return AVERROR(ENOMEM); 22. //如果用户指定了输入格式,直接使用它 23. if (fmt)

24. s->iformat = fmt; 25.

26. //忽略 27. if (options)

28. av_dict_copy(&tmp, *options, 0); 29.

30. if ((ret = av_opt_set_dict(s, &tmp)) < 0) 31. goto fail; 32.

33. //打开输入媒体(如果需要的话),初始化所有与媒体读写有关的结构们,比如 34. //AVIOContext,AVInputFormat等等

35. if ((ret = init_input(s, filename)) < 0) 36. goto fail;

37. //执行完此函数后,s->pb和s->iformat都已经指向了有效实例.pb是用于读写数据的,

38. //把媒体数据当做流来读写,不管是什么媒体格式,而iformat把pb读出来的流按某种媒

体格

39. //式进行分析,也就是说pb在底层,iformat在上层. 40.

41. //很多静态图像文件格式,都被当作一个格式处理,比如要打开.jpeg文件,需要的格式 42. //名为image2.此处还不是很了解具体细节,作不得准哦.

43. /* check filename in case an image number is expected */ 44. if (s->iformat->flags & AVFMT_NEEDNUMBER) { 45. if (!av_filename_number_test(filename)) { 46. ret = AVERROR(EINVAL); 47. goto fail; 48. } 49. } 50.

51. s->duration = s->start_time = AV_NOPTS_VALUE; 52. //上下文中保存下文件名

53. av_strlcpy(s->filename, filename, sizeof(s->filename)); 54.

55. /* allocate private data */

56. //为当前格式分配私有数据,主要用于某格式的读写操作时所用的私有结构. 57. //此结构的大小在定义AVInputFormat时已指定了. 58. if (s->iformat->priv_data_size > 0) {

59. if (!(s->priv_data = av_mallocz(s->iformat->priv_data_size))) { 60. ret = AVERROR(ENOMEM); 61. goto fail; 62. }

63. //这个可以先不必管它

64. if (s->iformat->priv_class) {

65. *(const AVClass**) s->priv_data = s->iformat->priv_class; 66. av_opt_set_defaults(s->priv_data);

67. if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0) 68. goto fail; 69. } 70. } 71.

72. /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */ 73. //从mp3文件中读ID3数据并保存之. 74. if (s->pb)

75. ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC); 76.

77. //读一下媒体的头部,在read_header()中主要是做某种格式的初始化工作,比如填充自

己的

78. //私有结构,根据流的数量分配流结构并初始化,把文件指针指向数据区开始处等. 79. if (!(s->flags & AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header) 80. if ((ret = s->iformat->read_header(s, &ap)) < 0) 81. goto fail; 82.

83. //保存数据区开始的位置

84. if (!(s->flags & AVFMT_FLAG_PRIV_OPT) && s->pb && !s->data_offset) 85. s->data_offset = avio_tell(s->pb);

86.

87. s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; 88.

89. if (options) {

90. av_dict_free(options); 91. *options = tmp; 92. } 93. *ps = s; 94. //执行成功 95. return 0; 96.

97. //执行失败

98. fail: av_dict_free(&tmp);

99. if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO)) 100. avio_close(s->pb); 101. avformat_free_context(s); 102. *ps = NULL; 103. return ret; 104. }

init_input

[cpp] view plaincopy

1. //打开输入媒体并填充其AVInputFormat结构

2. static int init_input(AVFormatContext *s, const char *filename) 3. {

4. int ret;

5. AVProbeData pd = { filename, NULL, 0 }; 6.

7. //当调用者已指定了pb(数据取得的方式)--一般不会这样. 8. if (s->pb) {

9. s->flags |= AVFMT_FLAG_CUSTOM_IO; 10. if (!s->iformat)

11. //如果已指定了pb但没指定iformat,以pb读取媒体数据进行探测,取得.取

得iformat.

12. return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0,

0);

13. else if (s->iformat->flags & AVFMT_NOFILE)

14. //如果已指定pb也指定了iformat,但是又指定了不需要文件(也包括URL指定

的地址),这就矛盾了,

15. //此时应是不需要pb的,因为不需操作文件,提示一下吧,也不算错. 16. av_log(s, AV_LOG_WARNING, \

\

17. \);


ffmpeg学习笔记.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:高职考试英语模拟试卷

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: