一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux下ffmpeg庫(kù)開(kāi)發(fā)之讀取攝像頭數(shù)據(jù)

嵌入式技術(shù) ? 來(lái)源:嵌入式技術(shù) ? 作者:嵌入式技術(shù) ? 2022-09-29 15:08 ? 次閱讀

Linux下ffmpeg庫(kù)開(kāi)發(fā)之讀取攝像頭數(shù)據(jù)

?FFmpeg是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開(kāi)源計(jì)算機(jī)程序。采用LGPL或GPL許可證。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案。它包含了非常先進(jìn)的音頻/視頻編解碼庫(kù)libavcodec,為了保證高可移植性和編解碼質(zhì)量,libavcodec里很多code都是從頭開(kāi)發(fā)的。

1.ffmpeg源碼安裝

??安裝ffmpeg庫(kù)之前需要先安裝yasm庫(kù)和x264庫(kù)。

?1.1 Yasm安裝

??下載地址:http://yasm.tortall.net/

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRf6Zi_5rC0,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center

??安裝yasm

#解壓
tar xvf /mnt/hgfs/ubuntu/software_pack/yasm-1.3.0.tar.gz  
#配置信息,生成Makefile
./configure 
#編譯安裝
make && make install 

?1.2 x264安裝

??下載地址:https://www.videolan.org/developers/x264.html

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRf6Zi_5rC0,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center

??安裝x264

#解壓
tar xvf /mnt/hgfs/ubuntu/software_pack/x264-master.tar.bz2
#配置信息,生成Makefile
./configure --prefix=$PWD/_install --enable-shared --enable-static
watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRf6Zi_5rC0,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center

??若配置時(shí)提示找不到nasm則下載nasm
??安裝nasm
??nasm下載地址:https://www.nasm.us/pub/nasm/releasebuilds/2.15.03/

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRf6Zi_5rC0,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center

?Netwide Assembler (簡(jiǎn)稱 NASM)是一款基于x86架構(gòu)的匯編與反匯編軟件。它可以用來(lái)編寫(xiě)16位(8086、80286等)、32位(IA-32)和64位(x86_64)的程序。 NASM被認(rèn)為是Linux平臺(tái)上最受歡迎的匯編工具之一。
NASM可以輸出包括通用對(duì)象文件格式(COFF)、OMF(Relocatable Object Module Format,用于80x86系列處理器上)、a.out、可執(zhí)行與可鏈接格式(ELF)、Mach-O、二進(jìn)制文件(.bin,二進(jìn)制磁盤(pán)映像,用于編譯操作系統(tǒng))等多種二進(jìn)制格式,而地址無(wú)關(guān)代碼僅支持ELF對(duì)象文件。 NASM也有自己的稱為RDOFF(Relocatable Dynamic Object File Format)的二進(jìn)制格式。

tar xvf /mnt/hgfs/ubuntu/software_pack/nasm-2.15.03.tar.gz
./autogen.sh 
./configure
make && make install

?再重新編譯x264,按照1.2小結(jié)操作:

#解壓
tar xvf /mnt/hgfs/ubuntu/software_pack/x264-master.tar.bz2
#配置信息,生成Makefile
./configure --prefix=$PWD/_install --enable-shared --enable-static
make && make install

??拷貝相關(guān)庫(kù)到系統(tǒng)目錄下

[wbyq@wbyq _install]$ sudo cp ./lib/*.so* /usr/lib -fdv

?1.3 ffmpeg安裝

??為了保證后續(xù)音視頻錄制正常,需要先安裝聲卡驅(qū)動(dòng)。

sudo apt-get install libasound2-dev

??下載地址:http://www.ffmpeg.org/download.html

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRf6Zi_5rC0,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center

?編譯安裝ffmpeg

#解壓
tar xvf /mnt/hgfs/ubuntu/software_pack/ffmpeg-4.2.5.tar.bz2
#配置信息,生成Makefile
./configure --enable-static --enable-shared --prefix=$PWD/_install --extra-cflags=-I/home/wbyq/src_pack/x264-master/_install/include --extra-ldflags=-L/home/wbyq/src_pack/x264-master/_install/lib --enable-ffmpeg --enable-libx264 --enable-gpl
#編譯安裝
make && make install

?拷貝相關(guān)庫(kù)到系統(tǒng)目錄下

[wbyq@wbyq _install]$ sudo  cp ./bin/ffmpeg /usr/bin/
[wbyq@wbyq _install]$ sudo cp lib/*.so* /usr/lib -rfdv

2. 查看ffmpeg版本信息

[wbyq@wbyq ~]$ ffmpeg -version
ffmpeg version 4.2.5 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
configuration: --enable-static --enable-shared --prefix=/home/wbyq/src_pack/ffmpeg-4.2.5/_install --extra-cflags=-I/home/wbyq/src_pack/x264-master/_install/include --extra-ldflags=-L/home/wbyq/src_pack/x264-master/_install/lib --enable-ffmpeg --enable-libx264 --enable-gpl
libavutil      56. 31.100 / 56. 31.100
libavcodec     58. 54.100 / 58. 54.100
libavformat    58. 29.100 / 58. 29.100
libavdevice    58.  8.100 / 58.  8.100
libavfilter     7. 57.100 /  7. 57.100
libswscale      5.  5.100 /  5.  5.100
libswresample   3.  5.100 /  3.  5.100
libpostproc    55.  5.100 / 55.  5.100

3.ffmpeg代碼開(kāi)發(fā)讀取攝像頭數(shù)據(jù)通過(guò)SDL顯示

?3.1 參考代碼

#include 
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define VIDEO_DEV "/dev/video2"
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;//互斥鎖
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;//條件變量
typedef enum
{
	false=0,
	true,
}bool;
int width;
int height;
int size;
unsigned char *rgb_buff=NULL;
unsigned char video_flag=1;
void *Video_CollectImage(void *arg);
int main()
{
	/*創(chuàng)建攝像頭采集線程*/
	pthread_t pthid;
    pthread_create(&pthid,NULL,Video_CollectImage, NULL);
	pthread_detach(pthid);/*設(shè)置分離屬性*/
	sleep(1);
	while(1)
	{
		if(width!=0 && height!=0 && size!=0)break;
		if(video_flag==0)return 0;
	}
	printf("image:%d * %d,%dn",width,height,size);
	unsigned char *rgb_data=malloc(size);
 	/*創(chuàng)建窗口 */
	SDL_Window *window=SDL_CreateWindow("SDL_VIDEO", SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,800,480,SDL_WINDOW_ALLOW_HIGHDPI|SDL_WINDOW_RESIZABLE);
    /*創(chuàng)建渲染器*/
	SDL_Renderer *render=SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED);
	/*清空渲染器*/
	SDL_RenderClear(render);
   /*創(chuàng)建紋理*/
	SDL_Texture*sdltext=SDL_CreateTexture(render,SDL_PIXELFORMAT_IYUV,SDL_TEXTUREACCESS_STREAMING,width,height);
	bool quit=true;
	SDL_Event event;
	SDL_Rect rect;
	while(quit)
	{
		while(SDL_PollEvent(&event))/*事件監(jiān)測(cè)*/
		{
			if(event.type==SDL_QUIT)/*退出事件*/
			{
				quit=false;
				video_flag=0;
				pthread_cancel(pthid);/*殺死指定線程*/
				continue;
			}
		}
		if(!video_flag)
		{
			quit=false;
			continue;
		}
		pthread_mutex_lock(&fastmutex);//互斥鎖上鎖
		pthread_cond_wait(&cond,&fastmutex);
		memcpy(rgb_data,rgb_buff,size);
		pthread_mutex_unlock(&fastmutex);//互斥鎖解鎖
		SDL_UpdateTexture(sdltext,NULL,rgb_data,width);
		//SDL_RenderCopy(render, sdltext, NULL,NULL); // 拷貝紋理到渲染器
		SDL_RenderCopyEx(render, sdltext,NULL,NULL,0,NULL,SDL_FLIP_NONE);
		SDL_RenderPresent(render); // 渲染
	}
	SDL_DestroyTexture(sdltext);/*銷毀紋理*/
    SDL_DestroyRenderer(render);/*銷毀渲染器*/
    SDL_DestroyWindow(window);/*銷毀窗口 */
    SDL_Quit();/*關(guān)閉SDL*/
    pthread_mutex_destroy(&fastmutex);/*銷毀互斥鎖*/
    pthread_cond_destroy(&cond);/*銷毀條件變量*/
	free(rgb_buff);
	free(rgb_data);
	return 0;
}
void *Video_CollectImage(void *arg)
{
	int res=0;
	AVFrame *Input_pFrame=NULL;
	AVFrame *Output_pFrame=NULL;
	printf("pth:%sn",avcodec_configuration());
	/*注冊(cè)設(shè)備*/
	avdevice_register_all();
	/*查找輸入格式*/
	AVInputFormat *ifmt=av_find_input_format("video4linux2");
	if(ifmt==NULL)
	{
		printf("av_find_input_format failedn");
		video_flag=0;
		return 0;
	}
	/*打開(kāi)輸入流并讀取頭部信息*/
	AVFormatContext *ps=NULL;
	res=avformat_open_input(&ps,VIDEO_DEV,ifmt,NULL);
	if(res)
	{
		printf("open input failedn");
		video_flag=0;
		return 0;
	}
	/*查找流信息*/
	res=avformat_find_stream_info(ps,NULL);
	if(res)
	{
		printf("find stream failedn");
		video_flag=0;
		return 0;
	}
	/*打印有關(guān)輸入或輸出格式信息*/
	av_dump_format(ps, 0, "video4linux2", 0);
	/*尋找視頻流*/
	int videostream=-1;
	videostream=av_find_best_stream(ps,AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);
	printf("videostram=%dn",videostream);
	/*尋找編解碼器*/
	AVCodec *video_avcodec=NULL;/*保存解碼器信息*/
	AVStream *stream = ps->streams[videostream];
	AVCodecContext *context=stream->codec;
	video_avcodec=avcodec_find_decoder(context->codec_id);
	if(video_avcodec==NULL)
	{
		printf("find video decodec failedn");
		video_flag=0;
		return 0;
	}	
	/*初始化音視頻解碼器*/
	res=avcodec_open2(context,video_avcodec,NULL);
	if(res)
	{
		printf("avcodec_open2 failedn");
		video_flag=0;
		return 0;
	}	
	AVPacket *packet=av_malloc(sizeof(AVPacket));/*分配包*/
	AVFrame *frame=av_frame_alloc();/*分配視頻幀*/
	AVFrame *frameyuv=av_frame_alloc();/*申請(qǐng)YUV空間*/
	/*分配空間,進(jìn)行圖像轉(zhuǎn)換*/
	width=context->width;
	height=context->height;
	int fmt=context->pix_fmt;/*流格式*/
	size=av_image_get_buffer_size(AV_PIX_FMT_YUV420P,width,height,16);
	unsigned char *buff=NULL;
	printf("w=%d,h=%d,size=%dn",width,height,size);	
	buff=av_malloc(size);
	rgb_buff=malloc(size);//保存RGB顏色數(shù)據(jù)
	/*存儲(chǔ)一幀圖像數(shù)據(jù)*/
	av_image_fill_arrays(frameyuv->data,frameyuv->linesize,buff,AV_PIX_FMT_YUV420P,width,height, 16);
	/*轉(zhuǎn)換上下文,使用sws_scale()執(zhí)行縮放/轉(zhuǎn)換操作。*/
	struct SwsContext *swsctx=sws_getContext(width,height, fmt,width,height, AV_PIX_FMT_YUV420P,SWS_BICUBIC,NULL,NULL,NULL);
	/*讀幀*/
	int go=0;
	int Framecount=0;
	printf("read fream buffn");
	while(av_read_frame(ps,packet)>=0 && video_flag)
	{
		Framecount++;
		if(packet->stream_index == AVMEDIA_TYPE_VIDEO)/*判斷是否為視頻*/
		{
			/*解碼一幀視頻數(shù)據(jù)。輸入一個(gè)壓縮編碼的結(jié)構(gòu)體AVPacket,輸出一個(gè)解碼后的結(jié)構(gòu)體AVFrame*/
			res=avcodec_decode_video2(ps->streams[videostream]->codec,frame,&go,packet);
			if(res<0)
			{
				printf("avcodec_decode_video2 failedn");
				break;
			}
			if(go)
			{
				/*轉(zhuǎn)換像素的函數(shù)*/
				sws_scale(swsctx,(const uint8_t * const*)frame->data,frame->linesize,0,height,frameyuv->data,frameyuv->linesize);
				pthread_mutex_lock(&fastmutex);//互斥鎖上鎖
				memcpy(rgb_buff,buff,size);
		        pthread_cond_broadcast(&cond);//廣播喚醒所有線程
		        pthread_mutex_unlock(&fastmutex);//互斥鎖解鎖
			}
		}		
	}
	sws_freeContext(swsctx);/*釋放上下文*/
	av_frame_free(&frameyuv);/*釋放YUV空間*/
	av_packet_unref(packet);/*釋放包*/
	av_frame_free(&frame);/*釋放視頻幀*/
	avformat_close_input(&ps);/*關(guān)閉流*/
	video_flag=0;
	pthread_exit(NULL);	
}

?3.2 Makefile文件

OBJ=get_cameraimage.c
CFLAGS =-I/home/wbyq/src_pack/SDL2-2.0.14/_install/include -I/home/wbyq/src_pack/SDL2-2.0.14/_install/include/SDL2 -L/home/wbyq/src_pack/SDL2-2.0.14/_install/lib
CFLAGS +=-L/home/wbyq/src_pack/SDL2_image-2.0.5/_install/lib -I/home/wbyq/src_pack/SDL2_image-2.0.5/_install/include -I/home/wbyq/src_pack/SDL2_image-2.0.5/_install/include/SDL2
CFLAGS+=-lSDL2 -lpthread -lm -ldl -lSDL2_image -lavcodec -lavfilter -lavutil -lswresample -lavdevice -lavformat -lpostproc -lswscale -lpthread -lstdc++ -lm -lasound
CFLAGS+=-I/home/wbyq/src_pack/ffmpeg-4.2.5/_install/include -L/home/wbyq/src_pack/ffmpeg-4.2.5/_install/lib -I/home/wbyq/src_pack/SDL2-2.0.14/_install/include -I/home/wbyq/src_pack/SDL2-2.0.14/_install/include/SDL2 
app:
	gcc $(OBJ) $(CFLAGS)

?3.3 運(yùn)行效果

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRf6Zi_5rC0,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center
審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11420

    瀏覽量

    212319
  • 攝像頭
    +關(guān)注

    關(guān)注

    60

    文章

    4927

    瀏覽量

    97417
  • ffmpeg
    +關(guān)注

    關(guān)注

    0

    文章

    46

    瀏覽量

    7558
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux攝像頭應(yīng)用編程

    V4L2是Video for linux2的簡(jiǎn)稱,為linux中關(guān)于視頻設(shè)備的內(nèi)核驅(qū)動(dòng)。在Linux中,視頻設(shè)備是設(shè)備文件,可以像訪問(wèn)普通文件一樣對(duì)其進(jìn)行讀寫(xiě),攝像頭在/dev/vid
    的頭像 發(fā)表于 08-26 21:39 ?3300次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>下</b><b class='flag-5'>攝像頭</b>應(yīng)用編程

    《深入理解FFmpeg閱讀體驗(yàn)》FFmpeg攝像頭測(cè)試

    零、前期工作 上文FFmpeg移植完成后,需要將x264/lib文件夾下的庫(kù)文件拷貝到開(kāi)發(fā)板的/lib/目錄下,將ffmpeg_install/lib文件夾下的
    發(fā)表于 04-17 19:06

    如何將連接到FPGA的攝像頭數(shù)據(jù)發(fā)送到主機(jī)PC?

    我正在尋找一種方法,將連接到 FPGA 的攝像頭數(shù)據(jù)發(fā)送到主機(jī) PC。 攝像頭 ---> FPGA ---> FX3 ---> USB 主機(jī) (PC) 我
    發(fā)表于 07-05 07:31

    求教大神 串口發(fā)送攝像頭數(shù)據(jù)問(wèn)題

    我想做一個(gè)攝像頭數(shù)據(jù)幀的幀頭。就是我將采集的圖像(很小而且是灰度圖)數(shù)據(jù)通過(guò)串口發(fā)送給LabVIEW, 在圖像數(shù)據(jù)前發(fā)送一個(gè)字節(jié),值為0xff,圖像數(shù)據(jù)一個(gè)字節(jié)一個(gè)字節(jié)傳送。請(qǐng)問(wèn)該怎么
    發(fā)表于 11-28 21:47

    【DragonBoard 410c試用體驗(yàn)】初試攝像頭

    龍板上使用攝像頭,歸根到底還是Linux系統(tǒng)使用攝像頭,無(wú)非就是打開(kāi)設(shè)備文件,然后讀取攝像頭數(shù)據(jù)。讀取
    發(fā)表于 09-19 15:35

    請(qǐng)問(wèn)攝像頭數(shù)據(jù)做PID控制是控制四軸的什么量?

    你們說(shuō)那攝像頭數(shù)據(jù)做PID控制 是控制四軸的什么量的啊 ,控制油門(mén)原來(lái)的前后左右值還是什么?還有四軸調(diào)好后可以垂直起飛,之后很飄正常嗎?這樣還可以攝像頭控制嗎? 求大神解答
    發(fā)表于 05-26 21:50

    stm32如何通過(guò)串口將攝像頭數(shù)據(jù)以bmp格式輸出?

    stm32通過(guò)串口將攝像頭數(shù)據(jù)以bmp格式輸出大俠們 給個(gè)思路
    發(fā)表于 04-28 04:35

    TM4C對(duì)ov7620攝像頭數(shù)據(jù)的直接讀取?

    大家好!剛剛接觸到攝像頭這一塊,當(dāng)我用ccs5.4定義一個(gè)640*480的uchar型大數(shù)組時(shí),編譯一定不會(huì)通過(guò)。不過(guò)我不能把數(shù)組定義為常量,因?yàn)?b class='flag-5'>攝像頭數(shù)據(jù)需要實(shí)時(shí)讀取,更新與分析,需要在內(nèi)存里。這種情況應(yīng)該如何解決?謝謝大家!
    發(fā)表于 08-26 11:46

    單片機(jī)攝像頭數(shù)據(jù)采集驅(qū)動(dòng)

    一、攝像頭數(shù)據(jù)采集驅(qū)動(dòng)1.時(shí)序2.代碼二、圖像數(shù)據(jù)的簡(jiǎn)單處理參考:
    發(fā)表于 11-22 07:13

    RK3399pro使用python3讀取USB攝像頭數(shù)據(jù)出現(xiàn)錯(cuò)誤怎么解決?

    RK3399pro使用python3讀取USB攝像頭數(shù)據(jù)出現(xiàn)錯(cuò)誤怎么解決?SSD模型輸出之后,后處理時(shí)間太長(zhǎng)怎么解決?
    發(fā)表于 03-07 07:26

    如何在Android平臺(tái)實(shí)現(xiàn)對(duì)攝像頭數(shù)據(jù)采集并發(fā)送H.264格式的視頻數(shù)據(jù)

    本帖子主要展示如何在Android平臺(tái)實(shí)現(xiàn)對(duì)攝像頭數(shù)據(jù)采集,再通過(guò)JNI調(diào)用ffmpeg庫(kù)壓制成H.264格式的視頻數(shù)據(jù),再通過(guò)簡(jiǎn)單UDP協(xié)議外發(fā)到WIN平臺(tái)的簡(jiǎn)易例程,沒(méi)有實(shí)現(xiàn)RTS
    發(fā)表于 07-01 16:56

    【米爾MYD-YT507開(kāi)發(fā)板試用體驗(yàn)】ubuntuFFmpeg攝像頭流體驗(yàn)

    體驗(yàn)了。之后我們需要完成我們的攝像頭數(shù)據(jù)推流實(shí)驗(yàn),需要一個(gè)攝像頭。這里可以選擇某寶的USB免驅(qū)攝像頭,看掛載與否可以參考命令。ls /dev 查看下面,插入是否有video0這樣的設(shè)備。由于其沒(méi)有插入
    發(fā)表于 07-21 20:11

    如何將采集到攝像頭數(shù)據(jù)完全傳輸?shù)絇C?

    如何將采集到攝像頭數(shù)據(jù)完全傳輸?shù)絇C有什么好的方法?
    發(fā)表于 10-18 08:31

    OV7620攝像頭數(shù)據(jù)手冊(cè)

    OV7620攝像頭數(shù)據(jù)手冊(cè)
    發(fā)表于 10-24 13:48 ?44次下載
    OV7620<b class='flag-5'>攝像頭數(shù)據(jù)</b>手冊(cè)

    Linux開(kāi)發(fā)_攝像頭編程(實(shí)現(xiàn)拍照功能)

    這篇文章主要介紹LinuxUVC免驅(qū)攝像頭操作流程,介紹V4L2框架、完成攝像頭拍照保存為BMP圖像到本地,最后貼出了利用CJSON庫(kù)解析
    的頭像 發(fā)表于 09-17 15:34 ?2232次閱讀