H264视频压缩主要步骤

  1. 压缩前的一些初始化
  2. 压缩帧再写入文件
  3. 压缩完成后资源的一些清理
/* encode.h */
#ifndef ENCODE_H
#define ENCODE_Hint EncodeStart(const char* pFilename);int EncodeStop(void);#endif
/* encode.c */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <pthread.h>
#include <x264.h>
#include <pthread.h>
#include "config.h"
#include "encode.h"
#include "queue.h"#define CONFIG_CSP X264_CSP_I422typedef enum {ENCODE_STATE_STOP,ENCODE_STATE_START
} eEncodeState;struct {x264_nal_t* pNals;x264_t* pHandle;x264_picture_t* pPicIn;x264_param_t* pParam;eEncodeState State;pthread_t EncodeThreadId;FILE* pFile;sQueue QueuePrivateData;
} sEncodePrivateData;static int H264FrameEncodeBegin(uint32_t Width, uint32_t Height)
{QueueInit(&sEncodePrivateData.QueuePrivateData);sEncodePrivateData.pPicIn = (x264_picture_t*)malloc(sizeof(x264_picture_t));sEncodePrivateData.pParam = (x264_param_t*)malloc(sizeof(x264_param_t));x264_param_default(sEncodePrivateData.pParam);x264_param_default_preset(sEncodePrivateData.pParam, "fast" , "zerolatency" );/* 设置参数 */sEncodePrivateData.pParam->i_csp = CONFIG_CSP;sEncodePrivateData.pParam->i_width = Width;sEncodePrivateData.pParam->i_height = Height; sEncodePrivateData.pParam->i_fps_num = CONFIG_CAPTURE_FPS;sEncodePrivateData.pParam->i_fps_den = 1;sEncodePrivateData.pParam->i_threads  = X264_SYNC_LOOKAHEAD_AUTO;sEncodePrivateData.pParam->i_keyint_max = 10;sEncodePrivateData.pParam->rc.i_bitrate = CONFIG_ENCODE_BITRATE;sEncodePrivateData.pParam->rc.i_rc_method = X264_RC_ABR;x264_param_apply_profile(sEncodePrivateData.pParam, "high422");sEncodePrivateData.pHandle = x264_encoder_open(sEncodePrivateData.pParam);x264_picture_alloc(sEncodePrivateData.pPicIn, CONFIG_CSP, sEncodePrivateData.pParam->i_width, sEncodePrivateData.pParam->i_height);return 0;
}static int H264FrameEncodeEnd(void)
{printf("Encode end, now clear resource\n");if (sEncodePrivateData.pHandle) {x264_encoder_close(sEncodePrivateData.pHandle);}if (sEncodePrivateData.pPicIn) {x264_picture_clean(sEncodePrivateData.pPicIn);free(sEncodePrivateData.pPicIn);sEncodePrivateData.pPicIn = NULL;}if (sEncodePrivateData.pParam) {free(sEncodePrivateData.pParam);sEncodePrivateData.pParam = NULL;}if(sEncodePrivateData.pFile) {fclose(sEncodePrivateData.pFile);sEncodePrivateData.pFile = NULL;}return 0;
}static int H264FrameEncode(const uint8_t* pData, uint32_t Width, uint32_t Height, uint32_t Length)
{x264_picture_t* pPicOut = (x264_picture_t*)malloc(sizeof(x264_picture_t));if(!pPicOut) {perror("Malloc failed");return -1;}x264_picture_init(pPicOut);int IndexY, IndexU, IndexV;int YuyvLength = Width * Height * 2 - 4;int NalCnt = 0;int Result = 0;static long int pts = 0;// uint8_t* pOut = pDataOut;uint8_t* pY = sEncodePrivateData.pPicIn->img.plane[0];uint8_t* pU = sEncodePrivateData.pPicIn->img.plane[1];uint8_t* pV = sEncodePrivateData.pPicIn->img.plane[2];// if(YuyvLength != Length) {//  printf("Param invalid, Length not match\n");//  return -1;// }IndexY = 0;IndexU = 0;IndexV = 0;for(int i = 0; i < YuyvLength; i += 4) {*(pY + (IndexY++)) = *(pData + i);*(pU + (IndexU++)) = *(pData + i + 1);*(pY + (IndexY++)) = *(pData + i + 2);*(pV + (IndexV++)) = *(pData + i + 3);}sEncodePrivateData.pPicIn->i_type = X264_TYPE_AUTO;sEncodePrivateData.pPicIn->i_pts = pts++;if (x264_encoder_encode(sEncodePrivateData.pHandle, &(sEncodePrivateData.pNals), &NalCnt, sEncodePrivateData.pPicIn, pPicOut) < 0) {free(pPicOut);return -1;}for (int i = 0; i < NalCnt; i++) {// memcpy(pOut, sEncodePrivateData.pNals[i].p_payload, sEncodePrivateData.pNals[i].i_payload);// pOut += sEncodePrivateData.pNals[i].i_payload;fwrite(sEncodePrivateData.pNals[i].p_payload, 1, sEncodePrivateData.pNals[i].i_payload, sEncodePrivateData.pFile);Result += sEncodePrivateData.pNals[i].i_payload;}free(pPicOut);return Result;
}static void* H264EncodeThread(void* pParam)
{int Ret = -1;while(sEncodePrivateData.State == ENCODE_STATE_START) {sQueueData QueueData;Ret = QueuePopData(&sEncodePrivateData.QueuePrivateData, &QueueData);if(Ret) {continue;}H264FrameEncode(QueueData.pData, CONFIG_CAPTURE_WIDTH, CONFIG_CAPTURE_HEIGHT, QueueData.Length);QueueCallback(&QueueData);}H264FrameEncodeEnd();return NULL;
}int EncodeStart(const char* pFilename)
{H264FrameEncodeBegin(CONFIG_CAPTURE_WIDTH, CONFIG_CAPTURE_HEIGHT);if(sEncodePrivateData.State) {printf("Encode thread already start\n");return -1;}sEncodePrivateData.State = ENCODE_STATE_START;sEncodePrivateData.pFile = fopen(pFilename, "w+");if(!sEncodePrivateData.pFile) {perror("Create h264 file failed");return -1;}pthread_create(&sEncodePrivateData.EncodeThreadId, NULL, H264EncodeThread, (void *)NULL);return 0;
}int EncodeStop(void)
{sEncodePrivateData.State = ENCODE_STATE_STOP;pthread_join(sEncodePrivateData.EncodeThreadId, NULL);printf("Encode thread stop\n");return 0;
}

转载于:https://www.cnblogs.com/rootming/p/10853982.html

Linux下V4L2捕捉画面+H264压缩视频+帧缓冲显示视频————H264压缩视频相关推荐

  1. linux v4l2 反操作,Linux下V4L2编程小结--吴老师

    作者:武汉华嵌-嵌入式培训中心  吴老师 Linux下V4L2编程小结 一.设置采集方式,格式 常用命令标志 打开视频设备后,可以设置该视频设备的属性,例如裁剪.缩放等.这一步是可选的.在Linux编 ...

  2. Linux下V4L2框架基于SDL库本地USB摄像头监控

    Linux下V4L2框架基于SDL库本地USB摄像头监控 1.摄像头框架编程步骤 (1)打开摄像头设备(/dev/video0 ./dev/video1 ) (2)设置图像格式:VIDIOC_S_FM ...

  3. Linux下V4L2编程小结

    http://www.360doc.com/content/12/0318/16/532901_195392228.shtml :davind dm365linux移植 http://www.embe ...

  4. Linux 驱动 – Frame Buffer (帧缓冲)显示驱动

    Linux 驱动 – Frame Buffer (帧缓冲)显示驱动 一.Frame Buffer Frame Buffer 翻译过来是帧缓冲的意思,帧指的是一帧图像,缓冲是暂时存放的意思,连起来就是暂 ...

  5. C语言高级应用---操作linux下V4L2摄像头应用程序

    目录(?)[-]采集方式V4L2操作流程点击这个网址说得很详细了这里不多说httpbaikebaiducomview5494174htm我们都知道,想要驱动Linux下的摄像头,其实很简单,照着V4L ...

  6. moviepy处理视频帧和遍历的方式处理视频帧速度对比。

    文章目录 摘要 下载与安装 工作原理 基本概念 速度对比 测试遍历的方式 测试moviepy方式处理图片的帧 结论 摘要 MoviePy是一个用于视频编辑的Python模块,它可被用于一些基本操作(如 ...

  7. Linux下C/C++实现以十六进制的形式显示命令(xxd)

    如果你需要在linux文本文件的十六进制转储?且正在寻找可以执行此操作的命令行实用程序,xxd的命令可以为你做这件事.xxd命令将文件显示为十六进制值和ASCII表示,并允许对其进行编辑. xxd - ...

  8. Qt应用程序开发五:QMediaPlayer播放视频,提取视频帧,多窗口播放同一视频

    效果图: 方法一:QMediaPlayer+QVideoWidget (如果其他格式视频播放不出来,安装一个视频解码器可以解决) #include "QMutPlayer.h" # ...

  9. Linux下Qt5: QMediaRecorder的问题,以及使用QCamera相关类进行摄像头视频采集

    版本信息: Qt 5.8.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 5.3.1 20160406 (Red ...

最新文章

  1. Openstack组件部署 — Nova overview
  2. modelsim读取文件中的数据_modelsim中的文件操作—— 大数据测试
  3. 接入amazon avs_每日新闻综述:亚马逊将互联网接入推向全球的宏伟计划
  4. 前端之 JavaScript 常用数据类型和操作
  5. 红帽yum安装httpd出现错误(This system is not registered to Red Hat Subscription Management. You can use subs)
  6. hiho_100_八数码
  7. Qt Creator 自动补齐变慢的解决
  8. geotrellis使用(七)记录一次惨痛的bug调试经历以及求DEM坡度实践
  9. java连接数据库实现一个简单的登陆界面
  10. 浅析机关单位人力资源内部控制
  11. 无法启动此程序因为计算机中丢失adapt,【完美解决】Wi7中NVIDIA GT540M安装程序无法找到和你现有硬件兼容的任何驱动程序,安装程序将会退出.doc...
  12. 河南大学大计算机考研复试分数线预测,2017年河南大学考研复试分数线以及复试通知...
  13. CSS拓展选择器 组合选择器 后代选择器 交集选择器 伪类选择器
  14. 【毕设基础教学】OLED屏幕使用详解 - 单片机 物联网
  15. html怎么设置左侧内边距,CSS 内边距(Padding)
  16. 【DDOS 防御小建议】
  17. NSDI'17-论文阅读[CherryPick:Adaptively Unearthing the Best Cloud Configurations for Big Data Analytics]
  18. int *p=malloc(100); 求 sizeof(p)
  19. 铁损分离-磁滞回线面积-离散点的面积
  20. Android系统proc下查看cpuinfo的参数信息

热门文章

  1. 四篇关于恶意软件对抗方面的paper要点
  2. 无人机飞控开发平台培训理论课程——MSP430最小系统
  3. Linux基础 —— Linux终端命令格式
  4. Spring Boot(三) 将war文件部署到tomcat 、 Thymeleaf示例
  5. 【ARM】Tiny4412裸机编程之GPIO简介
  6. 【Linux系统编程】POSIX有名信号量
  7. 【Android】Activity的task相关
  8. 程序运行依赖的重要文件版本不对_Deno核心模块:灵活依赖amp;安全沙箱
  9. java(5)——数据类型中的字符型和布尔类型
  10. 二叉树的右视图—leetcode199