我正在尝试使用SEI用户数据消息编写NAL单元。我的代码如下:
typedef struct {
unsigned char type_code;
unsigned char countryCode;
unsigned char countryCodeExtension[2];
unsigned char user_identifier[4];
unsigned char payloadBytes[20];
unsigned char marker_bits;
} userdata_reg_t35;
unsigned char begin[5] = {0x00, 0x00, 0x00, 0x01, 0x06};
unsigned char end[3] = {0x00, sizeof(userdata_reg_t35), 0x80};
userdata_reg_t35 m_userSEIData;
m_userSEIData.countryCode = 0xB5;
m_userSEIData.countryCodeExtension[0] = 0x31;
m_userSEIData.countryCodeExtension[1] = 0x00;
m_userSEIData.user_identifier[0] = 0x34;
m_userSEIData.user_identifier[1] = 0x39;
m_userSEIData.user_identifier[2] = 0x41;
m_userSEIData.user_identifier[3] = 0x47;
m_userSEIData.type_code = 0x03;
m_userSEIData.marker_bits = 0xFF;
sprintf((char*)m_userSEIData.payloadBytes, "%s", "My Payload");
memcpy(target, begin, 5);
memcpy(target + 5, &m_userSEIData, sizeof(userdata_reg_t35));
memcpy(target + 5 + sizeof(userdata_reg_t35), end, 3);
当我在mplayer或vlc中播放文件时,收到错误:
[h264 @ 0x7f5860c20720] SEI type 3 truncated at 216
我做错了什么?
** 编辑 **
我在阅读http://git.videolan.org/?p=x264.git;a=blob;f=encoder/set.c#l563
后修改了代码static const uint8_t uuid[16] = {0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7,
0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef};
unsigned char begin[7] = {0x00, 0x00, 0x00, 0x01, 0x06, 0x05, 16 + 20};
char szPayload[20];
memset(szPayload, 0, 20);
sprintf(szPayload, "%s", "My payload");
memcpy(target, begin, 7);
memcpy(target + 7, uuid, 16);
memcpy(target + 7 + 16, szPayload, 20);
但我仍然收到libav错误:https://ffmpeg.org/doxygen/2.6/h264__sei_8c_source.html,第306行。我还在做什么错?
答案 0 :(得分:0)
这看起来不太好,并且在H.264附录D规范中没有很好地映射。
您正在添加SEI NAL类型,然后您需要添加payloadType,payloadSize值 - 您没有它们。然后你声明你想要未注册的SEI消息(类型5),你的内容更像是有效载荷类型4(显然你正在添加字幕)。所以你需要包含它并排除type_code,然后它会看起来正确。
也就是说,你不需要的type_code 3取代了预期值5/4,然后没有长度。 VLC正好绊倒了......
有关详细信息,请参阅H.264 D.1 SEI有效负载语法。
更新。由于其他原因,您的更新代码[也]不正确。您正在使用起始代码执行附件B字节流,同时包含20个零字节的有效负载,在正常情况下应使用仿真预防字节进行更新。
要比较你得到的x264产生的结果,只需使用二进制编辑器打开x264输出并检查SEI NAL,然后与你的比较。