什么是 H.264 SEI?H.264 SEI 的编码和获取

什么是 H.264 SEI ?

H264 SEI 是 H.264/AVC 视频编码标准中的一种扩展信息(Supplemental Enhancement Information),用于向视频码流中添加一些额外的辅助信息。

SEI 可以用来传输一些与视频内容相关的元数据,比如时间戳、场景信息、色彩空间信息等。SEI 的使用可以提供更多的功能和优化视频的质量,例如在视频传输过程中实现更好的同步和错误恢复。

SEI 属于码流范畴,它提供了向视频码流中加入额外信息的方法,是 H.264 标准的特性之一。SEI的基本特征如下:

  • 并非解码过程的必须选项;
  • 可能对解码过程(容错、纠错)有帮助;
  • 集成在视频码流中。

H.264/AVC 中 SEI 的情况

什么是 H.264 SEI?H.264 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

推荐阅读:如何理解和使用 SEI(媒体补充增强信息)?

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论