我需要编写一个简单的编码器,在每个编码帧后添加一个 SEI 单元。
我查看了 BSAnalyzer,它看起来正是我需要的
SEI 在每一帧之后出现。但是当我在 ffmpeg 中播放文件时出现错误:
[NULL @ 000001cd901df1c0] SEI type 5 size 179843 truncated at 179776
[h264 @ 000001cd96eae780] SEI type 5 size 179843 truncated at 179774
[NULL @ 000001cd901df1c0] SEI type 5 size 179843 truncated at 179776
[h264 @ 000001cd970789c0] SEI type 5 size 179843 truncated at 179774
...and more
我写SEI的代码:
static const uint8_t START_MARKER[4] = {0x0, 0x0, 0x0, 0x1};
static const uint8_t UUID[16] = {
0x81, 0x39, 0xe9, 0xbd, 0xa6, 0x09, 0x48, 0xb7,
0x76, 0x2c, 0xc8, 0x20, 0xd9, 0x68, 0xcc, 0xcf};
static const uint8_t SEI_TYPE[1] = {0x06};
static const uint8_t PAYLOAD_TYPE[1] = {0x05};
int calc_sei_size(size_t user_data_size)
{
int new_buffer_size = 0;
new_buffer_size += sizeof(START_MARKER); // NAL marker
new_buffer_size += sizeof(SEI_TYPE); //+NAL type = 0x06
new_buffer_size += sizeof(PAYLOAD_TYPE); //+PayloadType = 0x05
int payload_size = user_data_size + sizeof(UUID); //user_data + uuid
while (payload_size > 0xFF)
{
payload_size -= 0xFF;
new_buffer_size++; // PayloadSize how FF while is more 255
}
new_buffer_size += 0xFF - payload_size; //+PayloadSize diff
new_buffer_size += sizeof(UUID); //+Uuid
new_buffer_size += user_data_size; //+userData
return new_buffer_size;
}
void sei_write(uint8_t *user_data, size_t user_data_size)
{
int newSize = calc_sei_size(user_data_size);
uint8_t *buffer = (uint8_t *)calloc(sizeof(uint8_t), newSize);
int offset = 0;
memcpy(&buffer[offset], START_MARKER, sizeof(START_MARKER)); // copy start marker
offset += sizeof(START_MARKER);
memcpy(&buffer[offset], SEI_TYPE, sizeof(SEI_TYPE)); // copy SEI_TYPE
offset += sizeof(SEI_TYPE);
memcpy(&buffer[offset], PAYLOAD_TYPE, sizeof(PAYLOAD_TYPE)); // copy SEI_TYPE
offset += sizeof(PAYLOAD_TYPE);
int payload_size = user_data_size + sizeof(UUID);
while (payload_size > 0xFF)
{
payload_size -= 0xFF;
buffer[offset++] = 0xFF;
}
buffer[offset++] = 0xFF - payload_size;
memcpy(&buffer[offset], UUID, sizeof(UUID)); // copy UUID
offset += sizeof(UUID);
memcpy(&buffer[offset], user_data, user_data_size); // copy user_data
DoSomeWithBuffer(buffer, newSize)
}
试试这个
int calc_sei_size(size_t user_data_size) {
int new_buffer_size = sizeof(START_MARKER) + sizeof(SEI_TYPE) + sizeof(PAYLOAD_TYPE);
int payload_size = user_data_size + sizeof(UUID); // user_data + uuid
new_buffer_size += payload_size; // Adding user_data and UUID size
new_buffer_size += 1; // For the remaining size byte
while (payload_size > 0xFF) {
payload_size -= 0xFF;
new_buffer_size++; // Adding a byte for each 0xFF byte
}
return new_buffer_size;
}
void sei_write(uint8_t *user_data, size_t user_data_size) {
int newSize = calc_sei_size(user_data_size);
uint8_t *buffer = (uint8_t *)calloc(sizeof(uint8_t), newSize);
int offset = 0;
memcpy(&buffer[offset], START_MARKER, sizeof(START_MARKER)); // copy start marker
offset += sizeof(START_MARKER);
memcpy(&buffer[offset], SEI_TYPE, sizeof(SEI_TYPE)); // copy SEI_TYPE
offset += sizeof(SEI_TYPE);
memcpy(&buffer[offset], PAYLOAD_TYPE, sizeof(PAYLOAD_TYPE)); // copy PAYLOAD_TYPE
offset += sizeof(PAYLOAD_TYPE);
int payload_size = user_data_size + sizeof(UUID);
while (payload_size > 0xFF) {
payload_size -= 0xFF;
buffer[offset++] = 0xFF;
}
buffer[offset++] = payload_size; // Correctly write the remaining size
memcpy(&buffer[offset], UUID, sizeof(UUID)); // copy UUID
offset += sizeof(UUID);
memcpy(&buffer[offset], user_data, user_data_size); // copy user_data
DoSomeWithBuffer(buffer, newSize);
free(buffer); // Don't forget to free the allocated memory
}