h264增加SEI段信息添加自定义信息
来源:互联网 发布:js中如何定义数组 编辑:程序博客网 时间:2024/06/08 16:44
FFMPEG使用版本为3.2.2
直接上代码:
EvHeade.h
#ifdef __cplusplusextern "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);#endif
#pragma oncesize_t get_sei_packet_size(size_t size);int fill_sei_packet(unsigned char * packet, bool isAnnexb, const char * content, size_t size);int get_sei_content(unsigned char * packet, size_t size, char * buffer, int *count);
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 UUIDstatic 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;}
阅读全文
0 0
- h264增加SEI段信息添加自定义信息
- 在soapheader中添加自定义信息
- MFC 给自定义工具栏添加提示信息
- log4j 配置数据库连接池添加自定义信息
- 为DataGrid自定义分页添加自定义导航和分页信息
- 为DataGrid自定义分页添加自定义导航和分页信息
- 为DataGrid自定义分页添加自定义导航和分页信息
- log4j+数据库连接池添加自定义信息+自定义SQL
- 为DataGrid自定义分页添加自定义导航和分页信息
- VLC直接播放h.264裸流(通过配置SEI信息实现)
- 自动增加附加信息--如版权信息
- 如何在VS中自动添加自定义版权信息
- 删除信息中的小区广播、默认语言、添加自定义铃声
- 在jquery的ajax中添加自定义的header信息
- Oracle查看段信息show_space()
- 查询oracle表字段信息
- mysql查询表字段信息
- SQL 查询表字段信息
- 12_session_基本介绍_获取_放值_取值
- 13_session_使用和创建的时机_删除
- 14_session_补充
- Chapter seventeen 嵌入式Java浅谈(1)
- PAT乙级 1069. 微博转发抽奖(20)
- h264增加SEI段信息添加自定义信息
- 二:hadoop2.x伪分布式集群安装
- 第二章 XML
- 15_cookie(一)
- 常见的字符串复制函数
- 16_cookie(二)
- spring学习笔记2
- Python廖雪峰实战web开发(Day2-编写Web APP骨架) -- 500 Internal Server Error Server got itself in trouble
- 17_cookie(三)