1. 程式人生 > >Linux下安裝FFMPEG 編譯 以及基本的Demo開發

Linux下安裝FFMPEG 編譯 以及基本的Demo開發

(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:

CC=g++

#工作路徑定義
CURRENT_PATH=./
WORK_DIR_PATH=..
MAIN_TEST_PATH=$(CURRENT_PATH)
FFMPEG_PATH=$(WORK_DIR_PATH)/lib
FFMPEG_INTERFACE_PATH=$(WORK_DIR_PATH)/Src
#庫檔案路徑定義
LINK_LIB_PATH=$(WORK_DIR_PATH)/lib/lib

#標頭檔案定義路徑
FFMPEG_H=$(FFMPEG_PATH)/include
FFMPEG_INTERFACE_H=$(WORK_DIR_PATH)/Inc


#原始檔路徑定義
FFMPEG_INTERFACE_SRC = $(wildcard $(FFMPEG_INTERFACE_PATH)/*.cpp)
MAIN_TEST_SRC=$(wildcard $(MAIN_TEST_PATH)/*.cpp)


#編譯中間檔案定義
FFMPEG_INTERFACE_OBJ = $(FFMPEG_INTERFACE_SRC:.cpp=.o)
MAIN_TEST_OBJ = $(MAIN_TEST_SRC:.cpp=.o)

#編譯選項
CXXFLAGS = -I$(FFMPEG_H) -I$(FFMPEG_INTERFACE_H) -L $(LINK_LIB_PATH)
#CXXFLAGS = -I$(FFMPEG_INTERFACE_H)
#echo $(CXXFLAGS)
# -WI,-Bstatic -$(mysqlName) -WI,-Bdynamic -lpthread -ldl -lrt

app:$(FFMPEG_INTERFACE_OBJ) $(MAIN_TEST_OBJ)
	$(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
$(FFMPEG_INTERFACE_OBJ):%.o:%.cpp
	$(CC) -c $(CXXFLAGS) $< -o [email protected]
$(MAIN_TEST_OBJ):%.o:%.cpp
	$(CC) -c $(CXXFLAGS) $< -o [email protected] 
#	 g++ -c main.o main.cpp -I ../lib/include/

#	

clean:
	rm -f $(FFMPEG_INTERFACE_OBJ) $(MAIN_TEST_OBJ) 
	


main.cpp測試程式碼:
#include <stdio.h>

#ifndef   UINT64_C
#define   UINT64_C(value)__CONCAT(value,ULL)
#endif

extern "C"
{
#include "../lib/include/libavformat/avformat.h"
#include "../lib/include/libswscale/swscale.h"

}
#include <iostream>
#include "../Inc/ffmpegInterface.h"




using namespace std;
CFfmpegInterface myffmpegInterface;

typedef unsigned short u_int16_t;
typedef unsigned int u_int32_t;
#pragma pack(2)

typedef struct BITMAPFILEHEADER  
{   
    u_int16_t bfType;   
    u_int32_t bfSize;   
    u_int16_t bfReserved1;   
    u_int16_t bfReserved2;   
    u_int32_t bfOffBits;   
}BITMAPFILEHEADER;   
 #pragma pack() 

 #pragma pack(2)
typedef struct BITMAPINFOHEADER  
{   
    u_int32_t biSize;   
    u_int32_t biWidth;   
    u_int32_t biHeight;   
    u_int16_t biPlanes;   
    u_int16_t biBitCount;   
    u_int32_t biCompression;   
    u_int32_t biSizeImage;   
    u_int32_t biXPelsPerMeter;   
    u_int32_t biYPelsPerMeter;   
    u_int32_t biClrUsed;   
    u_int32_t biClrImportant;   
}BITMAPINFODEADER;  
#pragma pack()

int img_convert(AVPicture *dst, enum AVPixelFormat dst_pix_fmt,
                const AVPicture *src, enum AVPixelFormat src_pix_fmt,
                int src_width, int src_height)
{
    int w;
    int h;
    SwsContext *pSwsCtx;
    w = src_width;
    h = src_height;
    pSwsCtx = sws_getContext(w, h, src_pix_fmt, w, h, dst_pix_fmt,SWS_BICUBIC, NULL, NULL, NULL);
    sws_scale(pSwsCtx, src->data, src->linesize,0, h, dst->data, dst->linesize);
 
    //這裡釋放掉pSwsCtx的記憶體
 
    return 0;
}
int CreateBmp(const char *filename, uint8_t *pRGBBuffer, int width, int height, int bpp)  
{  
	 BITMAPFILEHEADER bmpheader;  
	 BITMAPINFOHEADER bmpinfo;  
	 FILE *fp = NULL;  
	  
	 fp = fopen(filename,"wb");  
	 if( fp == NULL )  
	 {  
	  return -1;  
	 }  
	  
	 bmpheader.bfType = ('M' <<8)|'B';  
	 bmpheader.bfReserved1 = 0;  
	 bmpheader.bfReserved2 = 0;  
	 bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
	 bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8;  
	  
	 bmpinfo.biSize = sizeof(BITMAPINFOHEADER);  
	 bmpinfo.biWidth = width;  
	 bmpinfo.biHeight = 0 - height;  
	 bmpinfo.biPlanes = 1;  
	 bmpinfo.biBitCount = bpp;  
	 bmpinfo.biCompression = 0;  
	 bmpinfo.biSizeImage = 0;  
	 bmpinfo.biXPelsPerMeter = 100;  
	 bmpinfo.biYPelsPerMeter = 100;  
	 bmpinfo.biClrUsed = 0;  
	 bmpinfo.biClrImportant = 0;  
	  
	 fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,fp);  
	 fwrite(&bmpinfo,sizeof(BITMAPINFOHEADER),1,fp);  
	 fwrite(pRGBBuffer,width*height*bpp/8,1,fp);  
	 fclose(fp);  
	 fp = NULL;  
	  
	 return 0;  
}


int DecodeVideo()
{
		//開啟視訊檔案
	AVFormatContext *pFormatCtx=NULL;
	const char *filename = "music.mp4";
	int videoStream=-1;
	int i;
	AVFrame *pFrameRGB=NULL;
	AVFrame *pFrame=NULL;

	
	uint8_t *buffer=NULL;
	int numBytes;

	AVCodec *pCodec=NULL;
	AVCodecContext *pCodecCtx=NULL;

	int frameFinished;
    AVPacket packet;

	unsigned int bmpi=0;
	char BmpName[40] ={0};
	//註冊所有的編解碼器

	av_register_all();
	
	while(1)
		{
		 //開啟檔案
		if(avformat_open_input(&pFormatCtx,filename,NULL,NULL)!=0)
			{//這一步會用有效的資訊把 AVFormatContext填滿
				printf("####error: av_Open_input_file error \n");
				return 0;
			}
		// Retrieve stream information
		if(av_find_stream_info(pFormatCtx)<0)
			{
				cout<<"find stream info error"<<endl;
				return -1; // Couldn't find stream information
			}

	
		videoStream=-1;
		for(i=0; i<pFormatCtx->nb_streams; i++)
			{
				 if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)//CODEC_TYPE_VIDEO
					{
					 	videoStream=i;
						break;
					}
			}
		if(videoStream==-1)
		 return -1; // Didn't find a video stream
	
		 //找到解碼器
		pCodecCtx=pFormatCtx->streams[videoStream]->codec;
		pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
		
		if(pCodec==NULL) 
			{
				fprintf(stderr, "Unsupported codec!\n");
				return -1; // Codec not found
			}
		if(pCodec->capabilities&CODEC_CAP_TRUNCATED)
			pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
		// 開啟解碼器
		if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
		  return -1; // Could not open codec
	
		 
	
	
	
	
		// Allocate video frame
		pFrame=avcodec_alloc_frame();
		// Allocate an AVFrame structure
		pFrameRGB=avcodec_alloc_frame();
		if(pFrameRGB==NULL)
			return -1;
		// Determine required buffer size and allocate buffer
		numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height);
		buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
	
		// Assign appropriate parts of buffer to image planes in pFrameRGB
	// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
	// of AVPicture
		avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height);
	
	//	CreateBmp("SaveBmp.bmp", buffer,pCodecCtx->width, pCodecCtx->height, 24);
		i=0;
	
	while(av_read_frame(pFormatCtx, &packet)>=0) 
		{
			  //是視訊幀嗎
			  if(packet.stream_index==videoStream) 
				{
				//ffmpeg中的avcodec_decode_video2()的作用是解碼一幀視訊資料。輸入一個壓縮編碼的結構體AVPacket,輸出一個解碼後的結構體AVFrame
				avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,&packet);
			   
				// Did we get a video frame?
				if(frameFinished) 
					{
						//yuv資料
						pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height - 1);
					    pFrame->linesize[0] *= -1;
					    pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height / 2 - 1);
					    pFrame->linesize[1] *= -1;
					    pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height / 2 - 1);
					    pFrame->linesize[2] *= -1;
					    
					 //   sws_scale (pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
					// Convert the image from its native(YUV FMT) format to RGB
						img_convert((AVPicture *)pFrameRGB, AV_PIX_FMT_BGR24,(AVPicture*)pFrame, pCodecCtx->pix_fmt,pCodecCtx->width, pCodecCtx->height);
	
						//這個函式的使用本質上是為已經分配的空間的結構體AVPicture掛上一段用於儲存資料的空間,這個結構體中有一個指標陣列data[4],掛在這個數組裡
			//			avpicture_fill((AVPicture *)pFrame, buffer, PIX_FMT_BGR24,pCodecCtx->width, pCodecCtx->height);
						
						sprintf(BmpName,"%s_%d.bmp","SaveBmp",bmpi);
						bmpi++;
						cout<<"decode one frame "<<endl;
						CreateBmp(BmpName, buffer,pCodecCtx->width, pCodecCtx->height, 24);
						
						//SaveVideoFile("SaveVideo.rgb24", buffer,pCodecCtx->width, pCodecCtx->height, 24);
						// Save the frame to disk
					   // if(++i<=5)
						//	SaveFrame(pFrameRGB, pCodecCtx->width,
						 // 		  pCodecCtx->height, i);
					}
			  }
	
				// Free the packet that was allocated by av_read_frame
			  av_free_packet(&packet);
		}
		avcodec_close(pCodecCtx);
		av_close_input_file(pFormatCtx);
		pCodecCtx = NULL;
		pFormatCtx = NULL;
		cout<<"the video file was decoded over..."<<endl;
		break;
		}
	return 0;	
}

int main(int argc,char **argv)
{

	DecodeVideo();
	
	cout<<"kll"<<endl;
	while(1);
	AVFormatContext *pFormatCtx=NULL;
	const char *filename = "20101013093728.avi";


	av_register_all();
	cout<<"run herer"<<endl;
	 //開啟檔案
	 int err_code;
	 char buf[20];
	if(err_code=avformat_open_input(&pFormatCtx,filename,NULL,NULL))
		{//這一步會用有效的資訊把 AVFormatContext填滿
			av_strerror(err_code, buf, 1024);
   			printf("Couldn't open file %s: %d(%s)", filename, err_code, buf);
			return 0;
		}
	else
		cout<<"open file success"<<endl;
	cout<<"run over"<<endl;
	return 0;
}

以上程式碼可解碼一個視訊檔案,並把視訊資料封裝成.bmp格式圖片 存放。。。

相關推薦

Linux安裝FFMPEG 編譯 以及基本Demo開發

(windows下編譯ffmpeg   http://bbs.chinavideo.org/viewthread.php?tid=1897&extra=page%3D1) 1.首先去官網下載ffmpeg最新版ffmpeg.2.3.1 version 2.複製  

linux安裝ffmpeg

環境變量 例如 ima oca bz2 解壓 tar -1 logs 1、官網下載 : http://ffmpeg.org/download.html 2、解壓 .tar.bz2包 tar -jxvf xx.tar.bz2 3、因為官網只提供源碼,所以需要進行編譯 進入f

關於在linux安裝git,以及在idea上將項目部署到碼雲上

配置jdk 公鑰 entos 進入 項目部 最新 pen ive min

Linux安裝Python,以及環境變量的配置

gcc python36 步驟 configure evel windows 永久 min ads 1.安裝環境 centos7 + vmware + xshell 2.安裝Python3   2.1下載Python資源包 網址:https://www.pytho

linux安裝node環境以及cnpm

1.原始碼安裝 推薦使用原始碼安裝, 不推薦使用nvm 以及apt -get 官網找到linux版本連結 $ wget https://nodejs.org/dist/v4.5.0/node-v4.5.0-linux-x86.tar.gz   解壓 $ tar xvzf node-v

linux 安裝ffmpeg

http://www.tuicool.com/articles/2YFjayY 首先安裝編譯環境,如果系統有就不用安裝了。 yum install -y automake autoconf libtool gcc gcc-c++ yum install mak

在win10系統安裝ubuntu17.10以及基本配置

我的工具: 16G 3.0U盤 ubuntu17.10 iso映象(MSDN I tell you,或者國內的映象源) UltraISO燒錄軟體 分出100G磁碟做ubunt

Linux安裝YASM--編譯x264

下載原始碼: 配置: ./configure [email protected] ~/yasm-1.2.0 $ ./configure checking for a BSD-compatible install... /usr/bin/install -c

Linux安裝配置Nginx以及安裝PHP

1.編譯安裝Nginx 需要先安裝兩個庫 # yum -y install openssl openssl-devel 然後下載,編譯Nginx # wget http://nginx.org/download/nginx-1.8.0.tar.gz (這

Linux安裝eclipse的C/C++整合開發環境

1.在Ubuntu軟體中心搜尋eclipse,並下載安裝。自動安裝一般沒有問題。或者 2.開啟終端,然後輸入(中間需要你輸入密碼):                                  

linux的Mysql編譯安裝基本使用

load 虛擬機 sysctl 操作 依賴 down png 技術分享 徹底 一、大致操作步驟   環境介紹: OS:center OS6.5   mysql:5.6版本    1.關閉防火墻     查看防火墻狀態:service iptables stat

Debussy在win7系統安裝編譯xilinx庫、以及基本使用方法

自從到了新公司,coding及simulate時就回到了原始社會,只用modelsim了。 modelsim對於小工程設計及模擬是夠用的,但是涉及到一些類似於程式碼追蹤時,modelsim就欠缺了,想想還是debussy(debussy算古董級別了,現在推出的都是linux

Linux安裝jdk報Permission denied以及chmod詳解

添加 一個數 rwx inux mission 進制 沒有 以及 csdn 一、發現問題 在Linux中安裝jdk.bin的時候發現問題,報錯./config.sh: line 103: /home/jdk.bin : Permission denied 修改權限:chmo

linux安裝mongodb的方法和終端基本操作

base 當前 操作 god --help 客戶 drop tar -s 在linux環境安裝mongoDB: 一般認為偶數版本為穩定版 如 1.6.x,奇數版本為開發版如1.7.x 32bit的mongoDB最大能存放2g的數據,64bit沒有限制 方法

linux(centos)安裝ffmpeg

視頻 prior mir php 源碼編譯 category 緩存 www 一個 【備忘】windows環境下20行php代碼搞定音頻裁剪 上次我的這篇文章將了windows下web中如何操作ffmpeg的文章,這裏則記錄下linux(centos)下的安裝 首先:我花了中

linux安裝protobuf及cmake編譯

light present mini require fetching AS exp web .gz 一.protobuf 安裝 protobuf版本:2.6.1 下載地址:https://github.com/google/protobuf/archive/v2.6.1.

如何在linux閱讀源碼以及提取寫簡單demo

lse AD debian control %d aging sca view cmd //如何在linux下閱讀源碼以及提取寫demo這裏以 ps 為例用到的工具有 clion先查看 ps 路徑which root@ubuntu:~# which ps /bin/ps r

linux 安裝 Cisco Packet Tracer 7.11以及一些註意

家目錄 sta 註意 qt5 .html csdn 依賴 clas pac https://blog.csdn.net/qq_35882901/article/details/77652571 https://linux.cn/article-5576-1.html 開啟登

Linux安裝MySQL以及一些小坑

還需 .com star itl inux ret sdn 鏈接 keyword 第一次寫博客,各位湊合著看吧(假裝有人看)。 我這裏使用的是centos7。 1、首先打開終端,查看有沒有安裝過MySQL: [root@localhost lyp]# rpm -qa |

Linuxat 和 crontab的基本運用以及臨時檔案基本管理

一、at的基本運用 在終端輸入watch -n 1 ls -R /mnt/           //監控檔案每秒檢視一次並以第歸的方式列出來 使用at命令制定延時任務