Linux下ffmpeg库开发之读取摄像头数据

阅读: 评论:0

Linux下ffmpeg库开发之读取摄像头数据

Linux下ffmpeg库开发之读取摄像头数据

Linux下ffmpeg库开发之读取摄像头数据

  FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。

1.ffmpeg源码安装

  安装ffmpeg库之前需要先安装yasm库和x264库。

 1.1 Yasm安装

  下载地址:/

  安装yasm

#解压
tar xvf /mnt/hgfs/ubuntu/software_pack/yasm-1.3.  
#配置信息,生成Makefile
./configure 
#编译安装
make && make install 

 1.2 x264安装

  下载地址:.html

  安装x264

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


  若配置时提示找不到nasm则下载nasm
  安装nasm
  nasm下载地址:.15.03/

  Netwide Assembler (简称 NASM)是一款基于x86架构的汇编与反汇编软件。它可以用来编写16位(8086、80286等)、32位(IA-32)和64位(x86_64)的程序。 NASM被认为是Linux平台上最受欢迎的汇编工具之一。
  NASM可以输出包括通用对象文件格式(COFF)、OMF(Relocatable Object Module Format,用于80x86系列处理器上)、a.out、可执行与可链接格式(ELF)、Mach-O、二进制文件(.bin,二进制磁盘映像,用于编译操作系统)等多种二进制格式,而地址无关代码仅支持ELF对象文件。 NASM也有自己的称为RDOFF(Relocatable Dynamic Object File Format)的二进制格式。

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

  再重新编译x264,按照1.2小结操作:

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

  拷贝相关库到系统目录下

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

 1.3 ffmpeg安装

  为了保证后续音视频录制正常,需要先安装声卡驱动。

sudo apt-get install libasound2-dev

  下载地址:.html

编译安装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

拷贝相关库到系统目录下

[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代码开发读取摄像头数据通过SDL显示

 3.1 参考代码

#include <stdio.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include <libswresample/swresample.h>
#include <libavdevice/avdevice.h>
#include <libavutil/imgutils.h>
#include <SDL.h>
#include <SDL_image.h>
#include <pthread.h>
#include <unistd.h>
#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()
{/*创建摄像头采集线程*/pthread_t pthid;pthread_create(&pthid,NULL,Video_CollectImage, NULL);pthread_detach(pthid);/*设置分离属性*/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);/*创建窗口 */SDL_Window *window=SDL_CreateWindow("SDL_VIDEO", SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,800,480,SDL_WINDOW_ALLOW_HIGHDPI|SDL_WINDOW_RESIZABLE);/*创建渲染器*/SDL_Renderer *render=SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED);/*清空渲染器*/SDL_RenderClear(render);/*创建纹理*/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))/*事件监测*/{pe==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();/*关闭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());/*注册设备*/avdevice_register_all();/*查找输入格式*/AVInputFormat *ifmt=av_find_input_format("video4linux2");if(ifmt==NULL){printf("av_find_input_format failedn");video_flag=0;return 0;}/*打开输入流并读取头部信息*/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;}/*打印有关输入或输出格式信息*/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();/*申请YUV空间*//*分配空间,进行图像转换*/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颜色数据/*存储一帧图像数据*/av_image_fill_arrays(frameyuv->data,frameyuv->linesize,buff,AV_PIX_FMT_YUV420P,width,height, 16);/*转换上下文,使用sws_scale()执行缩放/转换操作。*/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)/*判断是否为视频*/{/*解码一帧视频数据。输入一个压缩编码的结构体AVPacket,输出一个解码后的结构体AVFrame*/res=avcodec_decode_video2(ps->streams[videostream]->codec,frame,&go,packet);if(res<0){printf("avcodec_decode_video2 failedn");break;}if(go){/*转换像素的函数*/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);/*关闭流*/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 运行效果


SDL2.0库编译参考:SDL2.0

本文发布于:2024-02-02 07:28:45,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170683012442276.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:摄像头   数据   Linux   ffmpeg
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23