先看使用场景:
https://blog.csdn.net/lsheevyfg/article/details/80951415
https://www.jianshu.com/p/4d9120dfcd69
参考文章:
https://blog.csdn.net/ab7936573/article/details/74135909

FFMPEG使用版本为3.2.2
直接上代码:
EvHeade.h

#ifdef __cplusplus
extern "C"
{#endif#include "libavcodec\avcodec.h"
#include "libavformat\avformat.h"
#include "libavutil\avutil.h"#ifdef __cplusplus
}
#endif#ifdef _WIN32#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avdevice.lib")
#pragma comment(lib,"avfilter.lib")
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"postproc.lib")
#pragma comment(lib,"swresample.lib")
#pragma comment(lib,"swscale.lib")#endif

sei_packet.h

#ifndef SEI_PACKET_H
#define SEI_PACKET_H#include <stdint.h>uint32_t reversebytes(uint32_t value);
uint32_t get_sei_packet_size(uint32_t size);
int fill_sei_packet(unsigned char * packet, bool isAnnexb, const char * content, uint32_t size);
int get_sei_content(unsigned char * packet, uint32_t size, char * buffer, int *count);
#pragma once#endif

sei_packet.cpp

#include "sei_packet.h"
#include <stdio.h>
#include <string.h>#define min(X,Y) ((X) < (Y) ? (X) : (Y))#define UUID_SIZE 16//FFMPEG uuid
//static unsigned char uuid[] = { 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef };
//self UUID
static unsigned char uuid[] = { 0x54, 0x80, 0x83, 0x97, 0xf0, 0x23, 0x47, 0x4b, 0xb7, 0xf7, 0x4f, 0x32, 0xb5, 0x4e, 0x06, 0xac };//开始码
static unsigned char start_code[] = {0x00,0x00,0x00,0x01};uint32_t reversebytes(uint32_t value) {return (value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 |(value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24;
}uint32_t get_sei_nalu_size(uint32_t content)
{//SEI payload sizeuint32_t sei_payload_size = content + UUID_SIZE;//NALU + payload类型 + 数据长度 + 数据uint32_t sei_size = 1 + 1 + (sei_payload_size / 0xFF + (sei_payload_size % 0xFF != 0 ? 1 : 0)) + sei_payload_size;//截止码uint32_t tail_size = 2;if (sei_size % 2 == 1){tail_size -= 1;}sei_size += tail_size;return sei_size;
}uint32_t get_sei_packet_size(uint32_t size)
{return get_sei_nalu_size(size) + 4;
}int fill_sei_packet(unsigned char * packet,bool isAnnexb, const char * content, uint32_t size)
{unsigned char * data = (unsigned char*)packet;unsigned int nalu_size = (unsigned int)get_sei_nalu_size(size);uint32_t sei_size = nalu_size;//大端转小端nalu_size = reversebytes(nalu_size);//NALU开始码unsigned int * size_ptr = &nalu_size;if (isAnnexb){memcpy(data, start_code, sizeof(unsigned int));}else{memcpy(data, size_ptr, sizeof(unsigned int));}data += sizeof(unsigned int);unsigned char * sei = data;//NAL header*data++ = 6; //SEI//sei payload type*data++ = 5; //unregistersize_t sei_payload_size = size + UUID_SIZE;//数据长度while (true){*data++ = (sei_payload_size >= 0xFF ? 0xFF : (char)sei_payload_size);if (sei_payload_size < 0xFF) break;sei_payload_size -= 0xFF;}//UUIDmemcpy(data, uuid, UUID_SIZE);data += UUID_SIZE;//数据memcpy(data, content, size);data += size;//tail 截止对齐码if (sei + sei_size - data == 1){*data = 0x80;}else if (sei + sei_size - data == 2){*data++ = 0x00;*data++ = 0x80;}return true;
}int get_sei_buffer(unsigned char * data, uint32_t size, char * buffer, int *count)
{unsigned char * sei = data;int sei_type = 0;unsigned sei_size = 0;//payload typedo {sei_type += *sei;} while (*sei++ == 255);//数据长度do {sei_size += *sei;} while (*sei++ == 255);//检查UUIDif (sei_size >= UUID_SIZE && sei_size <= (data + size - sei) &&sei_type == 5 && memcmp(sei, uuid, UUID_SIZE) == 0){sei += UUID_SIZE;sei_size -= UUID_SIZE;if (buffer != NULL && count != NULL){if (*count > (int)sei_size){memcpy(buffer, sei, sei_size);}}if (count != NULL){*count = sei_size;}return sei_size;}return -1;
}int get_sei_content(unsigned char * packet, uint32_t size,char * buffer,int *count)
{unsigned char ANNEXB_CODE_LOW[] = { 0x00,0x00,0x00,0x01 };unsigned char ANNEXB_CODE[] = { 0x00,0x00,0x00,0x01 };unsigned char *data = packet;bool isAnnexb = false;if ((size > 3 && memcmp(data, ANNEXB_CODE_LOW,3) == 0) ||(size > 4 && memcmp(data, ANNEXB_CODE,4) == 0)){isAnnexb = true;}//暂时只处理MP4封装,annexb暂为处理if (isAnnexb){while (data < packet + size) {if ((packet + size - data) > 4 && data[0] == 0x00 && data[1] == 0x00){int startCodeSize = 2;if (data[2] == 0x01){startCodeSize = 3;}else if(data[2] == 0x00 && data[3] == 0x01){startCodeSize = 4;}if (startCodeSize == 3 || startCodeSize == 4){if ((packet + size - data) > (startCodeSize + 1) && (data[startCodeSize] & 0x1F) == 6){//SEIunsigned char * sei = data + startCodeSize + 1;int ret = get_sei_buffer(sei, (packet + size - sei), buffer, count);if (ret != -1){return ret;}}data += startCodeSize + 1;}else{data += startCodeSize + 1;}}else{data++;}}}else{//当前NALUwhile (data < packet + size) {//MP4格式起始码/长度unsigned int *length = (unsigned int *)data;int nalu_size = (int)reversebytes(*length);//NALU headerif ((*(data + 4) & 0x1F) == 6){//SEIunsigned char * sei = data + 4 + 1;int ret = get_sei_buffer(sei, min(nalu_size,(packet + size - sei)),buffer,count);if (ret != -1){return ret;}}data += 4 + nalu_size;}}return -1;
}

FFmpeg H264增加SEI相关推荐

  1. ffmpeg H264 编解码配置

    ffmpeg H264编解码前面有文章介绍下,本文主要介绍一些参数配置. 编码: int InitEncoderCodec( int iWidth, int iHeight) {AVCodec * p ...

  2. ffmpeg h264解码器分析sps(二)

    ffmpeg h264解码器解析sps下半部分 sps->mb_width = get_ue_golomb(gb) + 1; /*以宏块为单位的宽度*/ sps->mb_height = ...

  3. FFMPEG h264 ACC 合成 mkv ts;h264 mp3 合成 MP4 avi flv

    FFMPEG h264 ACC 合成 mkv ts:h264 mp3 合成 MP4 avi flv #include <stdio.h>#include <cstdio>#in ...

  4. ffmpeg h264解码, 屏蔽因为网络丢包等各种原因导致的花屏帧

     ffmpeg h264解码, 屏蔽因为网络丢包等各种原因导致的花屏帧  ---->看来问题只能这样解决了,现在还要多测测,防止产生新的问题.目前来看,对现有代码没有影响,花屏的帧直接屏蔽掉了. ...

  5. Java 视频直播JavaCV(ffmpeg h264)+RTSP实现低延时1秒推流

    上一篇文章介绍了通用协议onvif获取到rtsp地址Java onvif协议通用协议获取rtsp地址 当然也有很多其他的方式获取rtsp地址 首先还是引入包: <!--javacv-->& ...

  6. android ffmpeg 编码h264,Mac系统下ffmpeg+h264+flv编码的android录制屏幕实现2

    接上一篇. activity_flv.xml xmlns:tools="http://schemas.android.com/tools" android:layout_width ...

  7. FFMPEG H264/H265 编码延迟问题

    参考:http://blog.csdn.net/aoshilang2249/article/details/40397199?utm_source=tuicool&utm_medium=ref ...

  8. ffmpeg h264+ts +udp传输

    http://bbs.csdn.net/topics/370246456 http://1229363.blog.163.com/blog/static/19743427201001244711137 ...

  9. ffmpeg h264 解码 转

    原作者博客 http://blog.csdn.net/taixinlfx/article/details/7531631 项目需要,要做PC端的解码器,解H264. 一直郁闷,终于今天搞定了.记录如下 ...

最新文章

  1. 数组-合并两个有序数组(双指针,从后往前)
  2. ee可以有js吗 jvaa_DOTA每日节奏—EE乱选英雄被举报封号,这真的合理吗
  3. 体素科技:2018年,算法驱动下的医学影像分析进展
  4. [NewLife.XCode]增量累加
  5. html插入图片和文字,HTML第三课文字图片插入
  6. JAVA springboot ssm b2b2c多用户商城系统源码(三):服务提供与调用
  7. Hibernate 中Property中的formula属性的使用
  8. 中文编程汉语编程实例
  9. 文本比较算法Ⅸ——Primal-Dual算法
  10. spyder替换_Spyder快捷键
  11. windowsxp下载python下载视频_Python 实现视频下载
  12. 中国车牌号的识别大全
  13. HTML中如何将字体加粗-前端入门
  14. java统计图表代码_java swing下用jfreechart开发图表统计情况
  15. SpringBoot整合Elasticsearch,应届毕业生java面试准备材料
  16. 关键词排名提升(提升关键词排名的方法)
  17. 灰度差分统计法计算图像的对比度
  18. 【EM算法】期望最大化算法
  19. Gradient descent拙见
  20. c语言 文件存在,c语言 判断文件是否存在

热门文章

  1. 最新美团代付源码+支持多模板/多支付通道/全开源
  2. 直播预约|FFA 2022 主会场,11月26日正式上线
  3. android 百度转码,自适应网站移动端被百度转码解决方案
  4. 最高检发布破坏计算机信息系统案等六大指导性案例
  5. Cartographer源码阅读
  6. 排队打水(排序不等式)
  7. C语言高墙高,院子里有两棵树。因为有高墙庇护,一棵树长得高大挺直。而另一棵...
  8. (2021-08-09)空气质量指数计算例题练习(一)
  9. 7-85 根据输入的空气污染指数,输出相应的信息。7-86 分支结构——大小写字母判断7-87 A±B
  10. 21. 理解CNI和CNI插件