doubao_chat/lib/net/libmpeg/source/mpeg-psd.c

71 lines
3.7 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.

// ITU-T H.222.0(10/2014)
// Information technology – Generic coding of moving pictures and associated audio information: Systems
// 2.5.5 Program stream directory(p84)
#include "mpeg-ps-proto.h"
#include <assert.h>
size_t psd_read(struct psd_t *psd, const uint8_t *data, size_t bytes)
{
int i, j;
uint16_t packet_length;
uint16_t number_of_access_units;
// Table 2-42 – Program stream directory packet(p81)
assert(0x00 == data[0] && 0x00 == data[1] && 0x01 == data[2] && 0xFF == data[3]);
packet_length = (((uint16_t)data[4]) << 8) | data[5];
assert(bytes >= (size_t)packet_length + 6);
assert((0x01 & data[7]) == 0x01); // 'xxxxxxx1'
number_of_access_units = (data[6] << 8) | ((data[7] >> 7) & 0x7F);
assert(number_of_access_units <= N_ACCESS_UNIT);
assert((0x01 & data[9]) == 0x01); // 'xxxxxxx1'
assert((0x01 & data[11]) == 0x01); // 'xxxxxxx1'
assert((0x01 & data[13]) == 0x01); // 'xxxxxxx1'
psd->prev_directory_offset = (uint64_t)(((uint64_t)data[8] << 38) | ((((uint64_t)data[9] >> 7) & 0x7F) << 30) | ((uint64_t)data[10] << 22) | ((((uint64_t)data[11] >> 7) & 0x7F) << 15) | ((uint64_t)data[12] << 7) | (((uint64_t)data[13] >> 7) & 0x7F));
assert((0x01 & data[15]) == 0x01); // 'xxxxxxx1'
assert((0x01 & data[17]) == 0x01); // 'xxxxxxx1'
assert((0x01 & data[19]) == 0x01); // 'xxxxxxx1'
psd->next_directory_offset = (uint64_t)(((uint64_t)data[14] << 38) | ((((uint64_t)data[15] >> 7) & 0x7F) << 30) | ((uint64_t)data[16] << 22) | ((((uint64_t)data[17] >> 7) & 0x7F) << 15) | ((uint64_t)data[18] << 7) | (((uint64_t)data[19] >> 7) & 0x7F));
// access unit
j = 20;
for (i = 0; i < number_of_access_units; i++) {
psd->units[i].packet_stream_id = data[j];
psd->units[i].pes_header_position_offset_sign = (data[j + 1] >> 7) & 0x01;
assert((0x01 & data[j + 2]) == 0x01); // 'xxxxxxx1'
assert((0x01 & data[j + 4]) == 0x01); // 'xxxxxxx1'
assert((0x01 & data[j + 6]) == 0x01); // 'xxxxxxx1'
psd->units[i].pes_header_position_offset = (uint64_t)(((uint64_t)(data[j + 1] & 0x7F) << 38) | ((((uint64_t)data[j + 2] >> 7) & 0x7F) << 30) | ((uint64_t)data[j + 3] << 22) | ((((uint64_t)data[j + 4] >> 7) & 0x7F) << 15) | ((uint64_t)data[j + 5] << 7) | (((uint64_t)data[j + 6] >> 7) & 0x7F));
psd->units[i].reference_offset = (data[j + 7] << 8) | data[j + 8];
assert((0x81 & data[j + 9]) == 0x81); // '1xxxxxx1'
if (psd->units[i].packet_stream_id == 0xFD) {
psd->units[i].packet_stream_id_extension_msbs = (data[j + 9] >> 4) & 0x07;
} else {
assert((0x70 & data[j + 9]) == 0x00); // '1000xxx1'
}
assert((0x01 & data[j + 11]) == 0x01); // 'xxxxxxx1'
assert((0x01 & data[j + 13]) == 0x01); // 'xxxxxxx1'
psd->units[i].PTS = (uint64_t)(((uint64_t)((data[j + 9] >> 1) & 0x07) << 30) | ((uint64_t)data[j + 10] << 22) | ((((uint64_t)data[j + 11] >> 7) & 0x7F) << 15) | ((uint64_t)data[j + 12] << 7) | (((uint64_t)data[j + 13] >> 7) & 0x7F));
assert((0x01 & data[j + 15]) == 0x01); // 'xxxxxxx1'
psd->units[i].bytes_to_read = (uint32_t)(((uint32_t)data[j + 14] << 15) | (((data[j + 15] >> 1) & 0x7F) << 8) | data[j + 16]);
assert((0x80 & data[j + 17]) == 0x80); // '1xxxxxxx'
psd->units[i].intra_coded_indicator = (data[j + 17] >> 6) & 0x01;
psd->units[i].coding_parameters_indicator = (data[j + 17] >> 4) & 0x03;
if (0xFD == psd->units[i].packet_stream_id) {
psd->units[i].packet_stream_id_extension_lsbs = data[j + 17] & 0x0F;
} else {
assert((0x0F & data[j + 17]) == 0x00); // '1xxx0000'
}
j += 18;
}
return j + 1;
}