Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // вызов
- while (seek_pos < data_size) {
- read = fread(&buff, 1, buff_size, fp);
- // ...
- for (pos = 0; pos < read; pos++, seek_pos++) {
- // ...
- if (mpeg_parse_frame(buff + pos, &header)) {
- // ... сохраняем значения в индекс
- pos += header.frame_size;
- seek_pos += header.frame_size;
- }
- }
- }
- // реализация
- static unsigned
- mpeg_parse_frame(
- const unsigned char *buff,
- mpeg_header_t *const header
- )
- {
- unsigned header_bitrate;
- unsigned header_samplerate;
- char *xing;
- // check sync
- if (buff[0] != 0xff || buff[1] < 0xe0) {
- return 0;
- }
- // get and check version
- switch (buff[1] >> 3 & 0x03) {
- case 3: // MPEG Version 1
- header->version = 0;
- break;
- case 2: // MPEG Version 2
- header->version = 1;
- break;
- case 0: // MPEG Version 2.5
- header->version = 2;
- break;
- default:
- return 0;
- break;
- }
- // get and check layer
- header->layer = 3 - (buff[1] >> 1 & 0x03);
- if (header->layer == 3) {
- return 0;
- }
- // get and check bitrate
- header_bitrate = buff[2] >> 4;
- if (header_bitrate == 0x0f) {
- return 0;
- }
- // get and check samplerate
- header_samplerate = buff[2] >> 2 & 0x03;
- if (header_samplerate == 0x03) {
- return 0;
- }
- // get bitrate value
- if (header->version == 1) {
- header->bitrate = mpeg_kbps[1][header->layer][header_bitrate];
- } else {
- header->bitrate = mpeg_kbps[0][header->layer][header_bitrate];
- }
- if (!header->bitrate) {
- return 0;
- }
- // get samplerate value
- header->samplerate = mpeg_freq[header->version][header_samplerate];
- // get number of PCM samples
- header->samples = mpeg_pcm_samples[header->version][header->layer];
- // get padding bit
- header->padding_bit = buff[2] >> 1 & 0x01;
- // get channel mode
- header->mode = buff[3] >> 6 & 0x03;
- // get VBR
- header->vbr = 0; // none
- xing = (char *) (buff + (
- !header->version
- ? (header->mode < 3 ? 32 : 17) // MPEG-1
- : (header->mode < 3 ? 17 : 9) // MPEG-2 LSF, MPEG-2.5
- ));
- if (!strncmp(xing, "Xing", 4) || !strncmp(xing, "Info", 4)) {
- header->vbr = 1; // xing
- } else if (!strncmp((char *) (buff + 32), "VBRI", 4)) {
- header->vbr = 2; // vbri
- }
- // TODO frame size for VBR is incorrect
- if (!header->layer) {
- header->frame_size = (size_t) (((12000 * header->bitrate / header->samplerate) + header->padding_bit) * 4);
- } else {
- header->frame_size = (size_t) ((144000 * header->bitrate / header->samplerate) + header->padding_bit);
- }
- if (!header->frame_size) {
- //return 0; TODO free format
- }
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment