doubao_chat/lib/net/libmpeg/source/mpeg-system-header.c

100 lines
3.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "mpeg-ps-proto.h"
#include "mpeg-util.h"
#include <assert.h>
// 2.5.3.5 System header (p79)
// Table 2-40 – Program stream system header
size_t system_header_read(struct ps_system_header_t *h, const uint8_t *data, size_t bytes)
{
size_t i, j;
size_t len;
if (bytes < 12) {
return 0;
}
assert(0x00 == data[0] && 0x00 == data[1] && 0x01 == data[2] && PES_SID_SYS == data[3]);
len = (data[4] << 8) | data[5];
assert(len + 6 <= bytes);
assert((0x80 & data[6]) == 0x80); // '1xxxxxxx'
assert((0x01 & data[8]) == 0x01); // 'xxxxxxx1'
h->rate_bound = ((data[6] & 0x7F) << 15) | (data[7] << 7) | ((data[8] >> 1) & 0x7F);
h->audio_bound = (data[9] >> 2) & 0x3F;
h->fixed_flag = (data[9] >> 1) & 0x01;
h->CSPS_flag = (data[9] >> 0) & 0x01;
assert((0x20 & data[10]) == 0x20); // 'xx1xxxxx'
h->system_audio_lock_flag = (data[10] >> 7) & 0x01;
h->system_video_lock_flag = (data[10] >> 6) & 0x01;
h->video_bound = data[10] & 0x1F;
// assert((0x7F & data[11]) == 0x00); // 'x0000000'
h->packet_rate_restriction_flag = (data[11] >> 7) & 0x01;
i = 12;
for (j = 0; (data[i] & 0x80) == 0x80 && j < sizeof(h->streams) / sizeof(h->streams[0]) && i < bytes; j++) {
h->streams[j].stream_id = data[i++];
if (h->streams[j].stream_id == PES_SID_EXTENSION) { // '10110111'
assert(data[i] == 0xC0); // '11000000'
assert((data[i + 1] & 80) == 0); // '1xxxxxxx'
h->streams[j].stream_id = (h->streams[j].stream_id << 7) | (data[i + 1] & 0x7F);
assert(data[i + 2] == 0xB6); // '10110110'
i += 3;
}
assert((data[i] & 0xC0) == 0xC0); // '11xxxxxx'
h->streams[j].buffer_bound_scale = (data[i] >> 5) & 0x01;
h->streams[j].buffer_size_bound = (data[i] & 0x1F) | data[i + 1];
i += 2;
}
return len + 4 + 2;
}
size_t system_header_write(const struct ps_system_header_t *h, uint8_t *data)
{
size_t i, j;
// system_header_start_code
nbo_w32(data, 0x000001BB);
// header length
//put16(data + 4, 6 + h->stream_count*3);
// rate_bound
// 1xxxxxxx xxxxxxxx xxxxxxx1
data[6] = 0x80 | ((h->rate_bound >> 15) & 0x7F);
data[7] = (h->rate_bound >> 7) & 0xFF;
data[8] = 0x01 | ((h->rate_bound & 0x7F) << 1);
// 6-audio_bound + 1-fixed_flag + 1-CSPS_flag
data[9] = ((h->audio_bound & 0x3F) << 2) | ((h->fixed_flag & 0x01) << 1) | (h->CSPS_flag & 0x01);
// 1-system_audio_lock_flag + 1-system_video_lock_flag + 1-maker + 5-video_bound
data[10] = 0x20 | ((h->system_audio_lock_flag & 0x01) << 7) | ((h->system_video_lock_flag & 0x01) << 6) | (h->video_bound & 0x1F);
// 1-packet_rate_restriction_flag + 7-reserved
data[11] = 0x7F | ((h->packet_rate_restriction_flag & 0x01) << 7);
i = 12;
for (j = 0; j < h->stream_count; j++) {
data[i++] = (uint8_t)h->streams[j].stream_id;
if (PES_SID_EXTENSION == h->streams[j].stream_id) { // '10110111'
data[i++] = 0xD0; // '11000000'
data[i++] = h->streams[j].stream_extid & 0x7F; // '0xxxxxxx'
data[i++] = 0xB6; // '10110110'
}
// '11' + 1-P-STD_buffer_bound_scale + 13-P-STD_buffer_size_bound
// '11xxxxxx xxxxxxxx'
data[i++] = 0xC0 | ((h->streams[j].buffer_bound_scale & 0x01) << 5) | ((h->streams[j].buffer_size_bound >> 8) & 0x1F);
data[i++] = h->streams[j].buffer_size_bound & 0xFF;
}
// header length
nbo_w16(data + 4, (uint16_t)(i - 6));
return i;
}