unsigned buf_skip(struct bs_buffer *stream, unsigned data_size) { const buf_size_t to_read = MIN(data_size, buf_window_size(stream)); stream->window_start += to_read; return to_read; }
unsigned buf_read(struct bs_buffer *stream, uint8_t *data, unsigned data_size) { const buf_size_t to_read = MIN(data_size, buf_window_size(stream)); memcpy(data, buf_window_start(stream), to_read); stream->window_start += to_read; return to_read; }
void buf_resize(struct bs_buffer *stream, unsigned additional_bytes) { /*only perform resize if space actually needed*/ if (additional_bytes > buf_unused_size(stream)) { if (stream->window_start > 0) { /*shift window down before extending buffer to add more space*/ if (buf_window_size(stream)) { memmove(stream->data, buf_window_start(stream), buf_window_size(stream)); } stream->window_end -= stream->window_start; stream->window_start = 0; } while (additional_bytes > buf_unused_size(stream)) { stream->data_size *= 2; } stream->data = realloc(stream->data, stream->data_size); } }
static int read_audio_packet(DVDA_Packet_Reader* packets, DVDA_Packet* packet, struct bs_buffer* packet_data) { if (packets->total_sectors) { BitstreamReader* reader = packets->reader; struct bs_buffer* buffer = reader->input.substream; buf_reset(buffer); if (!read_sector(packets->sectors, buffer)) { if (buf_window_size(buffer) == 0) { return 0; } if (!setjmp(*br_try(reader))) { unsigned sync_bytes; unsigned pad[6]; unsigned PTS_high; unsigned PTS_mid; unsigned PTS_low; unsigned SCR_extension; unsigned bitrate; unsigned stuffing_count; int audio_packet_found = 0; /*read pack header*/ reader->parse(reader, "32u 2u 3u 1u 15u 1u 15u 1u 9u 1u 22u 2u 5p 3u", &sync_bytes, &(pad[0]), &PTS_high, &(pad[1]), &PTS_mid, &(pad[2]), &PTS_low, &(pad[3]), &SCR_extension, &(pad[4]), &bitrate, &(pad[5]), &stuffing_count); if (sync_bytes != 0x000001BA) { br_etry(reader); return 1; } if ((pad[0] != 1) || (pad[1] != 1) || (pad[2] != 1) || (pad[3] != 1) || (pad[4] != 1) || (pad[5] != 3)) { br_etry(reader); return 1; } for (; stuffing_count; stuffing_count--) { reader->skip(reader, 8); } /*read packets from sector until sector is empty*/ while (buf_window_size(buffer) > 0) { unsigned start_code; unsigned stream_id; unsigned packet_length; reader->parse(reader, "24u 8u 16u", &start_code, &stream_id, &packet_length); if (start_code != 0x000001) { br_etry(reader); return 1; } if (stream_id == 0xBD) { /*audio packets are forwarded to packet*/ unsigned pad1_size; unsigned pad2_size; reader->parse(reader, "16p 8u", &pad1_size); reader->skip_bytes(reader, pad1_size); reader->parse(reader, "8u 8u 8p 8u", &(packet->codec_ID), &(packet->CRC), &pad2_size); if (packet->codec_ID == 0xA0) { /*PCM*/ reader->parse(reader, "16u 8p 4u 4u 4u 4u 8p 8u 8p 8u", &(packet->PCM.first_audio_frame), &(packet->PCM.group_1_bps), &(packet->PCM.group_2_bps), &(packet->PCM.group_1_rate), &(packet->PCM.group_2_rate), &(packet->PCM.channel_assignment), &(packet->PCM.CRC)); reader->skip_bytes(reader, pad2_size - 9); } else { /*probably MLP*/ reader->skip_bytes(reader, pad2_size); } packet_length -= 3 + pad1_size + 4 + pad2_size; buf_reset(packet_data); while (packet_length) { static uint8_t buffer[4096]; const unsigned to_read = MIN(packet_length, 4096); reader->read_bytes(reader, buffer, to_read); buf_write(packet_data, buffer, to_read); packet_length -= to_read; } audio_packet_found = 1; } else { /*other packets are ignored*/ reader->skip_bytes(reader, packet_length); } } /*return success if an audio packet was read*/ br_etry(reader); if (audio_packet_found) { return 0; } else { return 1; } } else { /*error reading sector*/ br_etry(reader); return 1; } } else { /*error reading sector*/ return 1; } } else { /*no more sectors, so return EOF*/ return 0; } }