一、程序的逻辑主要分两部分:

1、通过video4linux2读取摄像头的V4L2_PIX_FMT_YUYV格式的原始数据

2、把V4L2_PIX_FMT_YUYV格式的数据转换成AV_PIX_FMT_YUV422P格式的yuv数据,并存放在AVFrame结构中;         把AVFrame结构送到编码器;

收取编码后的h264数据流,并存到文件中

二、代码中主要用到的库:

1、通过一个叫uvccapture-0.5库(我直接改了里面的代码),获取摄像头的V4L2_PIX_FMT_YUYV格式数据。

2、通过libav编码

三、主要代码:

/** main.cpp**  Created on: 2014-3-2*      Author: xy*/#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <linux/videodev2.h>
//ffplay -f video4linux2 -framerate 30 -video_size hd720 /dev/video0
#ifdef __cplusplus
extern "C" {
#endif
#define __STDC_CONSTANT_MACROS
#ifdef _STDINT_H
#undef _STDINT_H
#endif
# include <stdint.h>
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include <libavutil/imgutils.h>
#include <libavutil/opt.h>#ifdef __cplusplus
}
#endif
//输入设备
#include "v4l2uvc.h"
int main() {//v4l2 valchar *videodevice = "/dev/video0";int width = 640; //320;int height = 480; //240;int brightness = 0, contrast = 0, saturation = 0, gain = 0;int quality = 95;int format = V4L2_PIX_FMT_YUYV;struct vdIn *videoIn;int grabmethod = 1;//video encoder initavcodec_register_all();AVCodec *codec;AVCodecContext *c = NULL;int i, ret, x, y, got_output;FILE *f;AVFrame *frame;AVPacket pkt;uint8_t endcode[] = { 0, 0, 1, 0xb7 };char filename[] = "test.264";printf("Encode video file %s\n", filename);/* find the mpeg1 video encoder */codec = avcodec_find_encoder(AV_CODEC_ID_H264);if (!codec) {fprintf(stderr, "Codec not found\n");exit(1);}c = avcodec_alloc_context3(codec);if (!c) {fprintf(stderr, "Could not allocate video codec context\n");exit(1);}/* put sample parameters */c->bit_rate = 400000;/* resolution must be a multiple of two */c->width = width; // 352;c->height = height; // 288;/* frames per second */c->time_base = (AVRational) {1,10/*25*/};c->gop_size = 10; /* emit one intra frame every ten frames */c->max_b_frames = 0; //1c->pix_fmt = AV_PIX_FMT_YUV422P; //v4l2是这个格式  AV_PIX_FMT_YUV420P;//av_opt_set(c->priv_data, "preset", "slow", 0);av_opt_set(c->priv_data, "tune", "zerolatency", 0); //这个可以让libav不缓存视频帧/********************************************************************************* 有两个地方影响libav是不是缓存编码后的视频帧,也就是影响实时性:* 1、av_opt_set(c->priv_data, "tune", "zerolatency", 0);这个比较主要。* 2、参数中有c->max_b_frames = 1;如果这个帧设为0,就没有B帧了,编码会很快的。********************************************************************************//* open it */if (avcodec_open2(c, codec, NULL) < 0) {fprintf(stderr, "Could not open codec\n");exit(1);}f = fopen(filename, "wb");if (!f) {fprintf(stderr, "Could not open %s\n", filename);exit(1);}frame = av_frame_alloc();if (!frame) {fprintf(stderr, "Could not allocate video frame\n");exit(1);}frame->format = c->pix_fmt;frame->width = c->width;frame->height = c->height;/* the image can be allocated by any means and av_image_alloc() is* just the most convenient way if av_malloc() is to be used */ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,c->pix_fmt, 32);if (ret < 0) {fprintf(stderr, "Could not allocate raw picture buffer\n");exit(1);}//v4l2 initvideoIn = (struct vdIn *) calloc(1, sizeof(struct vdIn));if (init_videoIn(videoIn, (char *) videodevice, width, height, format,grabmethod) < 0)exit(1);printf("w:%d,h:%d\n", c->width, c->height);time_t timep;timep = time(NULL);printf("%s\n", asctime(gmtime(&timep)));for (i = 0; i < 100; i++) {//usleep(200000);//从v4l2中获取数据格式为AV_PIX_FMT_YUV422Pif (uvcGrab(videoIn) < 0) {fprintf(stderr, "Error grabbing\n");close_v4l2(videoIn);free(videoIn);exit(1);}unsigned char *yuyv = videoIn->framebuffer;//把数据复制到libav想要的结构中av_init_packet(&pkt);pkt.data = NULL; // packet data will be allocated by the encoderpkt.size = 0;printf("debug!!!");fflush(stdout);
#if 0/* prepare a dummy image *//* Y */for (y = 0; y < c->height; y++) {for (x = 0; x < c->width; x++) {frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;}}/* Cb and Cr */for (y = 0; y < c->height/2; y++) {for (x = 0; x < c->width/2; x++) {frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;}}
#else/* prepare  image *//* Y  Cb Rb */for (y = 0; y < c->height; y++) {for (x = 0; x < c->width; x++) {frame->data[0][y * frame->linesize[0] + x] = yuyv[y* frame->linesize[0] * 2 + 2 * x];}}/* Cb and Cr */for (y = 0; y < c->height; y++) {for (x = 0; x < c->width / 2; x++) {//frame->data[0][y * frame->linesize[0] + 2*x  ] = yuyv[y*frame->linesize[0]*4+4*x];//frame->data[0][y * frame->linesize[0] + 2*x+1] = yuyv[y*frame->linesize[0]*4+4*x+2];frame->data[1][y * frame->linesize[1] + x] = yuyv[y* frame->linesize[1] * 4 + 4 * x + 1];frame->data[2][y * frame->linesize[2] + x] = yuyv[y* frame->linesize[2] * 4 + 4 * x + 3];}}
#endifframe->pts = i;/* encode the image */ret = avcodec_encode_video2(c, &pkt, frame, &got_output);if (ret < 0) {fprintf(stderr, "Error encoding frame\n");exit(1);}if (got_output) {printf("Write frame %3d (size=%5d)\n", i, pkt.size);fwrite(pkt.data, 1, pkt.size, f);av_free_packet(&pkt);}//编码}/* get the delayed frames */for (got_output = 1; got_output; i++) {fflush(stdout);ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);if (ret < 0) {fprintf(stderr, "Error encoding frame\n");exit(1);}if (got_output) {printf("Write frame %3d (size=%5d)\n", i, pkt.size);fwrite(pkt.data, 1, pkt.size, f);av_free_packet(&pkt);}}timep = time(NULL);printf("%s\n", asctime(gmtime(&timep)));/* add sequence end code to have a real mpeg file */fwrite(endcode, 1, sizeof(endcode), f);fclose(f);avcodec_close(c);av_free(c);av_freep(&frame->data[0]);av_frame_free(&frame);printf("111\n");free(videoIn);
}

想运行代码的朋友可以通过这个文章:

http://blog.csdn.net/xyyangkun/article/details/20456725

编译用到的libav库

在通过改工程中的makefile:

LIBAVDIR=/home/xy/mywork/av/libav-2014-03-02

指定libav库的位置就可以了。

使用的读摄像头数据的代码出处:

http://staticwave.ca/source/uvccapture/uvccapture-0.5.tar.bz2

库的工程在代码在:

http://download.csdn.net/detail/xyyangkun/6990791

所在工程已上传到github:

https://github.com/xyyangkun/read_encoder_sender

提交版本:2e60986a438e731aa53ca7d54bc492c521e7b5bc

读取笔记本的摄像头的原始yuv数据,通过libav(ffmpeg编码)相关推荐

  1. FFmpeg4.1 视频解码,保存原始YUV数据

    FFmpeg4.1 视频解码,保存原始YUV数据 原文:https://blog.csdn.net/qq_38421080/article/details/86520612 网上文章都太老,本文基于F ...

  2. ffmpeg 采集摄像头yuv数据

    本文讲述在linux下,如何使用ffmpeg采集摄像头yuv数据,并保存为文件. 分为4个部分进行讲解 需要的软硬件环境 使用ffmpeg命令采集yuv数据. 使用ffmpeg代码采集yuv数据. 查 ...

  3. 通过ffmpeg实时读取宇视摄像头的高清帧流数据,并保存4张图片进行4合一照片的生成。

    通过ffmpeg实时读取宇视摄像头的高清帧流数据,并保存4张图片进行4合一照片的生成. FFmpeg视频解码过程 通常来说,FFmpeg的视频解码过程有以下几个步骤: 注册所支持的所有的文件(容器)格 ...

  4. 网络摄像头转usb接口_同时读取多个摄像头数据(包括海康网络摄像头和USB摄像头)...

    一.功能 1.实现多个摄像头同时获取图像,并保存到个各自目录 2.摄像头类别包括海康RSTP协议网络摄像头和普通USB摄像头 3.可自动和手动保存图片 二.注意事项 1.python可以使用multi ...

  5. php调用linux摄像头,Linux_在Linux操作系统上使用摄像头,我的公家笔记本的摄像头一直 - phpStudy...

    我的公家笔记本的摄像头一直没啥用,偶尔用 vmware player 2.0模拟个 msn 用(其实到目前一次都没用过).搞过安全对这东西严重不信任通常都不驱动,忽然想起重案6组那个警察兄弟说搞高科技 ...

  6. 调用笔记本的摄像头实现基于opencv的视频人脸识别(中文显示和英文显示)以及 index 480 is out of bounds for axis 0 with size 480错误的解决

    @人脸识别代码和一些常见错误 基于opencv的视频人脸识别(中文显示)以及 index 480 is out of bounds for axis 0 with size 480错误的解决 参考了 ...

  7. Android用surface直接显示yuv数据(三)

    本文用Java创建UI并联合JNI层操作surface来直接显示yuv数据(yv12),开发环境为Android 4.4,全志A23平台. package com.example.myyuvviewe ...

  8. Android音视频学习系列(六) — 掌握视频基础知识并使用OpenGL ES 2.0渲染YUV数据

    系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...

  9. Unity 渲染YUV数据 ---- 以Unity渲染Android Camera数据为例子

    1 背景 一般Unity都是RGB直接渲染的,但是总有特殊情况下,需要渲染YUV数据.比如,Unity读取Android的Camera YUV数据,并渲染.本文就基于这种情况,来展开讨论. Unity ...

最新文章

  1. 复现经典:《统计学习方法》第13章 无监督学习概论
  2. Js/Jquery获取iframe中的元素 在Iframe中获取父窗体的元素方法
  3. OpenTelemetry-可观察性的新时代
  4. Silverlight 出现“无法加载 URI 的内容。URI 可能无效”错误的解决方案
  5. PHP给后台管理系统加安全防护机制的一些方案
  6. html单击出现下拉菜单,*OnClick实现点击主菜单时出现下拉菜单,已实现但是有问题,求助!*...
  7. Win10中的IIS10安装php manager和IIS URL Rewrite
  8. BootStrap中Affix控件的使用方法及如何保持布局的美观
  9. C++---list(列表)模板
  10. 如果伦敦地铁图是数据科学家画的……
  11. 7-10 数组循环左移 (20 分)
  12. IIS的状态代码(微软文档)
  13. python--Django从创建一个项目说起
  14. 基于Django+链家+Bootstrap真实数据的房源推荐/可视化系统
  15. RubyOnRails终极部署
  16. 西安大略大学计算机专业排名,加拿大大学计算机专业排名一览
  17. 计算机网络专助理工程师考试时间,软考高级工程师职称考试时间
  18. 商品进销差价_零售企业商品进销差价的核算
  19. 内容页的链接设置seo技巧
  20. tensorflow聊天机器人python实现_代码详解|tensorflow实现 聊天AI--PigPig养成记(1)

热门文章

  1. Hadoop学习(source方式安装篇)
  2. JavaScript基础总结
  3. 离线地图显示连接服务器未打开,如何在uwp中使用OSM离线地图?没有可用的互联网连接时出现问题...
  4. r型聚类分析怎么做_营销型网站怎么做?
  5. vue + element-ui 聊天_推荐6款Vue管理后台框架,收藏好,留备用
  6. 多伦多计算机科学大学,加拿大计算机科学专业 - 加拿大多伦多大学的计算机专业...
  7. linux怎么运行ofstream,ofstream和ifstream详细用法---转
  8. 深入理解javascript原型和闭包(3)——prototype原型
  9. Python-csvkit:强大的CSV文件命令行工具
  10. 用 Python 将微信热文转换成Word文档 | 神级操作