当前位置:   article > 正文

Linux下安装FFMPEG 编译 以及基本的Demo开发_ffbuild/library.mak:119

ffbuild/library.mak:119

(windows下编译ffmpeg   http://bbs.chinavideo.org/viewthread.php?tid=1897&extra=page%3D1)


1.首先去官网下载ffmpeg最新版ffmpeg.2.3.1 version


2.复制    ffmpeg.2.3.1.tar.bz2 到/root/kmcflyCode/目录下


3.解压包. tar -xjfv ffmpeg.2.3.1.tar.bz2 到目录下


4.配置ffmpeg ----配置,生成Makefile
./configure --enable-shared --disable-yasm --prefix=/usr/local/ffmpeg


5.make

(假如此时出现编译错误

ln: creating symbolic link `libavutil.so' to `libavutil.so.50': 

Operation not supported 

make: *** [libavutil/libavutil.so] Error 1

ln: creating symbolic link `libavutil.so' to `libavutil.so.50': 

Operation not supported 

make: *** [libavutil/libavutil.so] Error 1

ln :failed to create symbolic link 'libavutil.so',则是因为当前文件夹是windows共享过来的 需要链接目录,导致权限出错,解决方法:把ffmpeg.2.3.1.tar.bz2 拷贝到Linux 目录而非从Windows共享的目录,Windows共享目录

mount -t vboxsf share /mnt/nfs/ 把Windows  share共享文件夹 挂在到/mnt/nfs/目录)

6.make install


以上步骤执行完毕,则在/usr/local/ffmpeg/目录下生成了 lib include bin 文件夹,为使自己的程序调用方便,把lib动态库目录文件复制到自己的工程文件夹,然后把Include中的几个文件夹复制到/usr/include/目录中,,即系统默认头文件搜索目录

(若在/usr/local/ffmpeg/bin 目录下 执行ffmpeg 命令出错,

ffmpeg: error while loading shared libraries: libavdevice.so.53: cannot open shared object file: No such file or directory

解决办法:

vi /etc/ld.so.conf

加入:/usr/local/lib

执行ldconfig

)

7.建立自己的工程文件目录   Src(自己的源文件夹)   lib(ffmpeg 库文件目录,包含ffmpeg include 和lib动态库文件夹)  Maintest(测试程序目录,存放测试文件,以及makefile 编译规则)

makefile:

  1. CC=g++
  2. #工作路径定义
  3. CURRENT_PATH=./
  4. WORK_DIR_PATH=..
  5. MAIN_TEST_PATH=$(CURRENT_PATH)
  6. FFMPEG_PATH=$(WORK_DIR_PATH)/lib
  7. FFMPEG_INTERFACE_PATH=$(WORK_DIR_PATH)/Src
  8. #库文件路径定义
  9. LINK_LIB_PATH=$(WORK_DIR_PATH)/lib/lib
  10. #头文件定义路径
  11. FFMPEG_H=$(FFMPEG_PATH)/include
  12. FFMPEG_INTERFACE_H=$(WORK_DIR_PATH)/Inc
  13. #源文件路径定义
  14. FFMPEG_INTERFACE_SRC = $(wildcard $(FFMPEG_INTERFACE_PATH)/*.cpp)
  15. MAIN_TEST_SRC=$(wildcard $(MAIN_TEST_PATH)/*.cpp)
  16. #编译中间文件定义
  17. FFMPEG_INTERFACE_OBJ = $(FFMPEG_INTERFACE_SRC:.cpp=.o)
  18. MAIN_TEST_OBJ = $(MAIN_TEST_SRC:.cpp=.o)
  19. #编译选项
  20. CXXFLAGS = -I$(FFMPEG_H) -I$(FFMPEG_INTERFACE_H) -L $(LINK_LIB_PATH)
  21. #CXXFLAGS = -I$(FFMPEG_INTERFACE_H)
  22. #echo $(CXXFLAGS)
  23. # -WI,-Bstatic -$(mysqlName) -WI,-Bdynamic -lpthread -ldl -lrt
  24. app:$(FFMPEG_INTERFACE_OBJ) $(MAIN_TEST_OBJ)
  25. $(CC) -o app $(CXXFLAGS) $(FFMPEG_INTERFACE_OBJ) $(MAIN_TEST_OBJ) $(LINK_LIB_PATH)/libswscale.so $(LINK_LIB_PATH)/libavutil.so.52 -WI,-Bdynamic -lavformat -lavcodec -ldl -lrt
  26. $(FFMPEG_INTERFACE_OBJ):%.o:%.cpp
  27. $(CC) -c $(CXXFLAGS) $< -o $@
  28. $(MAIN_TEST_OBJ):%.o:%.cpp
  29. $(CC) -c $(CXXFLAGS) $< -o $@
  30. # g++ -c main.o main.cpp -I ../lib/include/
  31. #
  32. clean:
  33. rm -f $(FFMPEG_INTERFACE_OBJ) $(MAIN_TEST_OBJ)

main.cpp测试代码:

  1. #include <stdio.h>
  2. #ifndef UINT64_C
  3. #define UINT64_C(value)__CONCAT(value,ULL)
  4. #endif
  5. extern "C"
  6. {
  7. #include "../lib/include/libavformat/avformat.h"
  8. #include "../lib/include/libswscale/swscale.h"
  9. }
  10. #include <iostream>
  11. #include "../Inc/ffmpegInterface.h"
  12. using namespace std;
  13. CFfmpegInterface myffmpegInterface;
  14. typedef unsigned short u_int16_t;
  15. typedef unsigned int u_int32_t;
  16. #pragma pack(2)
  17. typedef struct BITMAPFILEHEADER
  18. {
  19. u_int16_t bfType;
  20. u_int32_t bfSize;
  21. u_int16_t bfReserved1;
  22. u_int16_t bfReserved2;
  23. u_int32_t bfOffBits;
  24. }BITMAPFILEHEADER;
  25. #pragma pack()
  26. #pragma pack(2)
  27. typedef struct BITMAPINFOHEADER
  28. {
  29. u_int32_t biSize;
  30. u_int32_t biWidth;
  31. u_int32_t biHeight;
  32. u_int16_t biPlanes;
  33. u_int16_t biBitCount;
  34. u_int32_t biCompression;
  35. u_int32_t biSizeImage;
  36. u_int32_t biXPelsPerMeter;
  37. u_int32_t biYPelsPerMeter;
  38. u_int32_t biClrUsed;
  39. u_int32_t biClrImportant;
  40. }BITMAPINFODEADER;
  41. #pragma pack()
  42. int img_convert(AVPicture *dst, enum AVPixelFormat dst_pix_fmt,
  43. const AVPicture *src, enum AVPixelFormat src_pix_fmt,
  44. int src_width, int src_height)
  45. {
  46. int w;
  47. int h;
  48. SwsContext *pSwsCtx;
  49. w = src_width;
  50. h = src_height;
  51. pSwsCtx = sws_getContext(w, h, src_pix_fmt, w, h, dst_pix_fmt,SWS_BICUBIC, NULL, NULL, NULL);
  52. sws_scale(pSwsCtx, src->data, src->linesize,0, h, dst->data, dst->linesize);
  53. //这里释放掉pSwsCtx的内存
  54. return 0;
  55. }
  56. int CreateBmp(const char *filename, uint8_t *pRGBBuffer, int width, int height, int bpp)
  57. {
  58. BITMAPFILEHEADER bmpheader;
  59. BITMAPINFOHEADER bmpinfo;
  60. FILE *fp = NULL;
  61. fp = fopen(filename,"wb");
  62. if( fp == NULL )
  63. {
  64. return -1;
  65. }
  66. bmpheader.bfType = ('M' <<8)|'B';
  67. bmpheader.bfReserved1 = 0;
  68. bmpheader.bfReserved2 = 0;
  69. bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  70. bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8;
  71. bmpinfo.biSize = sizeof(BITMAPINFOHEADER);
  72. bmpinfo.biWidth = width;
  73. bmpinfo.biHeight = 0 - height;
  74. bmpinfo.biPlanes = 1;
  75. bmpinfo.biBitCount = bpp;
  76. bmpinfo.biCompression = 0;
  77. bmpinfo.biSizeImage = 0;
  78. bmpinfo.biXPelsPerMeter = 100;
  79. bmpinfo.biYPelsPerMeter = 100;
  80. bmpinfo.biClrUsed = 0;
  81. bmpinfo.biClrImportant = 0;
  82. fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,fp);
  83. fwrite(&bmpinfo,sizeof(BITMAPINFOHEADER),1,fp);
  84. fwrite(pRGBBuffer,width*height*bpp/8,1,fp);
  85. fclose(fp);
  86. fp = NULL;
  87. return 0;
  88. }
  89. int DecodeVideo()
  90. {
  91. //打开视频文件
  92. AVFormatContext *pFormatCtx=NULL;
  93. const char *filename = "music.mp4";
  94. int videoStream=-1;
  95. int i;
  96. AVFrame *pFrameRGB=NULL;
  97. AVFrame *pFrame=NULL;
  98. uint8_t *buffer=NULL;
  99. int numBytes;
  100. AVCodec *pCodec=NULL;
  101. AVCodecContext *pCodecCtx=NULL;
  102. int frameFinished;
  103. AVPacket packet;
  104. unsigned int bmpi=0;
  105. char BmpName[40] ={0};
  106. //注册所有的编解码器
  107. av_register_all();
  108. while(1)
  109. {
  110. //打开文件
  111. if(avformat_open_input(&pFormatCtx,filename,NULL,NULL)!=0)
  112. {//这一步会用有效的信息把 AVFormatContext填满
  113. printf("####error: av_Open_input_file error \n");
  114. return 0;
  115. }
  116. // Retrieve stream information
  117. if(av_find_stream_info(pFormatCtx)<0)
  118. {
  119. cout<<"find stream info error"<<endl;
  120. return -1; // Couldn't find stream information
  121. }
  122. videoStream=-1;
  123. for(i=0; i<pFormatCtx->nb_streams; i++)
  124. {
  125. if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)//CODEC_TYPE_VIDEO
  126. {
  127. videoStream=i;
  128. break;
  129. }
  130. }
  131. if(videoStream==-1)
  132. return -1; // Didn't find a video stream
  133. //找到解码器
  134. pCodecCtx=pFormatCtx->streams[videoStream]->codec;
  135. pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  136. if(pCodec==NULL)
  137. {
  138. fprintf(stderr, "Unsupported codec!\n");
  139. return -1; // Codec not found
  140. }
  141. if(pCodec->capabilities&CODEC_CAP_TRUNCATED)
  142. pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
  143. // 打开解码器
  144. if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
  145. return -1; // Could not open codec
  146. // Allocate video frame
  147. pFrame=avcodec_alloc_frame();
  148. // Allocate an AVFrame structure
  149. pFrameRGB=avcodec_alloc_frame();
  150. if(pFrameRGB==NULL)
  151. return -1;
  152. // Determine required buffer size and allocate buffer
  153. numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height);
  154. buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
  155. // Assign appropriate parts of buffer to image planes in pFrameRGB
  156. // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
  157. // of AVPicture
  158. avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height);
  159. // CreateBmp("SaveBmp.bmp", buffer,pCodecCtx->width, pCodecCtx->height, 24);
  160. i=0;
  161. while(av_read_frame(pFormatCtx, &packet)>=0)
  162. {
  163. //是视频帧吗
  164. if(packet.stream_index==videoStream)
  165. {
  166. //ffmpeg中的avcodec_decode_video2()的作用是解码一帧视频数据。输入一个压缩编码的结构体AVPacket,输出一个解码后的结构体AVFrame
  167. avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,&packet);
  168. // Did we get a video frame?
  169. if(frameFinished)
  170. {
  171. //yuv数据
  172. pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height - 1);
  173. pFrame->linesize[0] *= -1;
  174. pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height / 2 - 1);
  175. pFrame->linesize[1] *= -1;
  176. pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height / 2 - 1);
  177. pFrame->linesize[2] *= -1;
  178. // sws_scale (pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
  179. // Convert the image from its native(YUV FMT) format to RGB
  180. img_convert((AVPicture *)pFrameRGB, AV_PIX_FMT_BGR24,(AVPicture*)pFrame, pCodecCtx->pix_fmt,pCodecCtx->width, pCodecCtx->height);
  181. //这个函数的使用本质上是为已经分配的空间的结构体AVPicture挂上一段用于保存数据的空间,这个结构体中有一个指针数组data[4],挂在这个数组里
  182. // avpicture_fill((AVPicture *)pFrame, buffer, PIX_FMT_BGR24,pCodecCtx->width, pCodecCtx->height);
  183. sprintf(BmpName,"%s_%d.bmp","SaveBmp",bmpi);
  184. bmpi++;
  185. cout<<"decode one frame "<<endl;
  186. CreateBmp(BmpName, buffer,pCodecCtx->width, pCodecCtx->height, 24);
  187. //SaveVideoFile("SaveVideo.rgb24", buffer,pCodecCtx->width, pCodecCtx->height, 24);
  188. // Save the frame to disk
  189. // if(++i<=5)
  190. // SaveFrame(pFrameRGB, pCodecCtx->width,
  191. // pCodecCtx->height, i);
  192. }
  193. }
  194. // Free the packet that was allocated by av_read_frame
  195. av_free_packet(&packet);
  196. }
  197. avcodec_close(pCodecCtx);
  198. av_close_input_file(pFormatCtx);
  199. pCodecCtx = NULL;
  200. pFormatCtx = NULL;
  201. cout<<"the video file was decoded over..."<<endl;
  202. break;
  203. }
  204. return 0;
  205. }
  206. int main(int argc,char **argv)
  207. {
  208. DecodeVideo();
  209. cout<<"kll"<<endl;
  210. while(1);
  211. AVFormatContext *pFormatCtx=NULL;
  212. const char *filename = "20101013093728.avi";
  213. av_register_all();
  214. cout<<"run herer"<<endl;
  215. //打开文件
  216. int err_code;
  217. char buf[20];
  218. if(err_code=avformat_open_input(&pFormatCtx,filename,NULL,NULL))
  219. {//这一步会用有效的信息把 AVFormatContext填满
  220. av_strerror(err_code, buf, 1024);
  221. printf("Couldn't open file %s: %d(%s)", filename, err_code, buf);
  222. return 0;
  223. }
  224. else
  225. cout<<"open file success"<<endl;
  226. cout<<"run over"<<endl;
  227. return 0;
  228. }


以上代码可解码一个视频文件,并把视频数据封装成.bmp格式图片 存放。。。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/75775?site
推荐阅读
相关标签
  

闽ICP备14008679号