什么是 H.264 SEI ?
H264 SEI 是 H.264/AVC 视频编码标准中的一种扩展信息(Supplemental Enhancement Information),用于向视频码流中添加一些额外的辅助信息。
SEI 可以用来传输一些与视频内容相关的元数据,比如时间戳、场景信息、色彩空间信息等。SEI 的使用可以提供更多的功能和优化视频的质量,例如在视频传输过程中实现更好的同步和错误恢复。
SEI 属于码流范畴,它提供了向视频码流中加入额外信息的方法,是 H.264 标准的特性之一。SEI的基本特征如下:
- 并非解码过程的必须选项;
- 可能对解码过程(容错、纠错)有帮助;
- 集成在视频码流中。
H.264/AVC 中 SEI 的情况
H.264 SEI 编码
enum sei_payload_type_e
{
/* libx264 raw enum */
SEI_BUFFERING_PERIOD = 0,
SEI_PIC_TIMING = 1,
SEI_PAN_SCAN_RECT = 2,
SEI_FILLER = 3,
SEI_USER_DATA_REGISTERED = 4,
SEI_USER_DATA_UNREGISTERED = 5,
SEI_RECOVERY_POINT = 6,
SEI_DEC_REF_PIC_MARKING = 7,
SEI_FRAME_PACKING = 45,
SEI_MASTERING_DISPLAY = 137,
SEI_CONTENT_LIGHT_LEVEL = 144,
SEI_ALTERNATIVE_TRANSFER = 147,
/* self define */
SEI_SELF_DEFINE_LAYOUT = 200,
};
static int
h264_sei_pack_internal(uint8_t* sei, uint8_t* payload, int payload_size, int payload_type)
{
static unsigned char start_code[] = { 0x00, 0x00, 0x00, 0x01 };
int i, index = 0;
/* start code */
memcpy(sei + index, start_code, 4);
index += 4;
/* nalu type */
sei[index++] = 6;
/* sei payload type */
for (i = 0; i <= payload_type - 255; i += 255) {
sei[index++] = 255;
}
sei[index++] = payload_type - i;
/* sei payload size */
for (i = 0; i <= payload_size - 255; i += 255) {
sei[index++] = 255;
}
sei[index++] = payload_size - i;
/* sei content */
for (i = 0; i < payload_size; i++) {
sei[index++] = payload[i];
}
/* sei rbsp_trailing */
sei[index++] = 0x80;
return index;
}
int fill_h264sei_packet(uint8_t* sei, char* opts, bool uu)
{
static const uint8_t uuid[16] =
{
0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7,
0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef
};
int length;
char payload[1024] = { 0 };
enum sei_payload_type_e type = SEI_USER_DATA_UNREGISTERED;
if (uu) {
memcpy(payload, uuid, 16);
sprintf(payload + 16, "%s", opts);
}
else {
type = SEI_SELF_DEFINE_LAYOUT;
sprintf(payload, "%s", opts);
}
length = strlen(payload) + 1;
return h264_sei_pack_internal(sei, (uint8_t*)payload, length, type);
}
H.264 SEI 获取
while (av_read_frame(format_ctx, &packet) >= 0) {
if (packet.stream_index == video_stream_index) {
AVFrame *frame = av_frame_alloc();
int ret;
int got_frame = 0;
ret = avcodec_decode_video2(codec_ctx, frame, &got_frame, &packet);
if (ret >= 0 && got_frame) {
// 使用 frame->side_data 来获取 SEI 数据
AVFrameSideData *sei_data = av_frame_get_side_data(frame, AV_FRAME_DATA_SEI_UNREGISTERED);
if (sei_data) {
// 处理 SEI 数据
// sei_data->data 指向 SEI 数据的字节流
// sei_data->size 是 SEI 数据的大小
// 进行相应的处理
}
}
av_frame_free(&frame);
}
av_packet_unref(&packet);
}
调用demo:
unsigned char sei_packet[1024] = { 0 };
int len;
char user_data[] = { 'a', 'l', 'i', 'v', 'e', 'y', 'u', 'n' };
len= fill_h264sei_packet(sei_packet, (char*)user_data, true);
注:sei不能独立一帧发送,要与I帧或者p帧一起发送
参考资料:https://mp.weixin.qq.com/s/nG2OstBdGirxcOBavKErrg 作者:Aliveyun
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。