MP3文件格式分析
来源:互联网 发布:育知同创官网 编辑:程序博客网 时间:2024/05/22 06:59
#include <stdio.h>#include <time.h>#include <errno.h>#include <unistd.h>#include <ctype.h>#include <inttypes.h>#include <stdlib.h>#define ID3v2_HEADER_SIZE 10#define MAX_BUF_SIZE 100000000//#define MAX_BUF_SIZE 2519178 #define MPA_STEREO 0#define MPA_JSTEREO 1#define MPA_DUAL 2#define MPA_MONO 3#define AV_RB32(x) ((((const uint8_t*)(x))[0] << 24) | \ (((const uint8_t*)(x))[1] << 16) | \ (((const uint8_t*)(x))[2] << 8) | \ ((const uint8_t*)(x))[3])#define FFMAX(a,b) ((a) > (b) ? (a) : (b))#define MPA_DECODE_HEADER \ int frame_size; \ int error_protection; \ int layer; \ int sample_rate; \ int sample_rate_index; /* between 0 and 8 */ \ int bit_rate; \ int nb_channels; \ int mode; \ int mode_ext; \ int lsf;typedef struct MPADecodeHeader { MPA_DECODE_HEADER} MPADecodeHeader;static unsigned char const_buf[MAX_BUF_SIZE];//const char *filename = "/tmp/MrsLeta.mp3";//const char *filename = "/tmp/312178.mp3";const char *filename = "/tmp/test.mp3";const uint16_t ff_mpa_bitrate_tab[2][3][15] = { { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } }, { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} }};const uint16_t ff_mpa_freq_tab[3] = { 44100, 48000, 32000 };int ff_id3v2_tag_len (unsigned char* buf);int ff_int_buf(unsigned char *buf);int ff_mpa_decode_header( uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate);static inline int ff_mpa_check_header(uint32_t header);int ff_id3v2_match(const uint8_t *buf);int main(void){ int size = ff_int_buf(const_buf); int len = ff_id3v2_tag_len(const_buf); unsigned char *buf0,*buf2,*buf,*end; int max_frames = 0, first_frames = 0; int fsize, frames, sample_rate; uint32_t header; buf0 = const_buf ; if(ff_id3v2_match(buf0)) { buf0 += ff_id3v2_tag_len(buf0); } buf = buf0; end = buf + size - sizeof(uint32_t); for(; buf < end; buf= buf2+1) { buf2 = buf; for(frames = 0; buf2 < end; frames++) { header = AV_RB32(buf2); fsize = ff_mpa_decode_header(header, &sample_rate, &sample_rate, &sample_rate, &sample_rate); if(fsize < 0) break; buf2 += fsize; } max_frames = FFMAX(max_frames, frames); } return 0;}int ff_int_buf(unsigned char *buf){ FILE *f; f = fopen(filename, "r"); if (!f) { fprintf(stderr, "Cannot read file '%s' for pass-2 encoding: %s\n", filename, strerror(errno)); return -1; } int size = fread(const_buf, 1, MAX_BUF_SIZE, f); const_buf[size] = '\0'; fclose(f); return size;}int ff_id3v2_tag_len (unsigned char* buf){ int len = ((buf[6] & 0x7f) << 21) + ((buf[7] & 0x7f) << 14) + ((buf[8] & 0x7f) << 7) + (buf[9] & 0x7f) + ID3v2_HEADER_SIZE; if (buf[5] & 0x10) len += ID3v2_HEADER_SIZE; return len;}int ff_mpa_decode_header( uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate){ MPADecodeHeader s1, *s = &s1; if (ff_mpa_check_header(head) != 0) return -1; if (ff_mpegaudio_decode_header(s, head) != 0) { return -1; } switch(s->layer) { case 1: *frame_size = 384; break; case 2: *frame_size = 1152; break; default: case 3: if (s->lsf) *frame_size = 576; else *frame_size = 1152; break; } *sample_rate = s->sample_rate; *channels = s->nb_channels; *bit_rate = s->bit_rate; return s->frame_size;}/* fast header check for resync */static inline int ff_mpa_check_header(uint32_t header){ /* header */ if ((header & 0xffe00000) != 0xffe00000) return -1; /* layer check */ if ((header & (3<<17)) == 0) return -1; /* bit rate */ if ((header & (0xf<<12)) == 0xf<<12) return -1; /* frequency */ if ((header & (3<<10)) == 3<<10) return -1; return 0;}int ff_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header){ int sample_rate, frame_size, mpeg25, padding; int sample_rate_index, bitrate_index; if (header & (1<<20)) { s->lsf = (header & (1<<19)) ? 0 : 1; mpeg25 = 0; } else { s->lsf = 1; mpeg25 = 1; } s->layer = 4 - ((header >> 17) & 3); /* extract frequency */ sample_rate_index = (header >> 10) & 3; sample_rate = ff_mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25); sample_rate_index += 3 * (s->lsf + mpeg25); s->sample_rate_index = sample_rate_index; s->error_protection = ((header >> 16) & 1) ^ 1; s->sample_rate = sample_rate; bitrate_index = (header >> 12) & 0xf; padding = (header >> 9) & 1; //extension = (header >> 8) & 1; s->mode = (header >> 6) & 3; s->mode_ext = (header >> 4) & 3; //copyright = (header >> 3) & 1; //original = (header >> 2) & 1; //emphasis = header & 3;if (s->mode == MPA_MONO) s->nb_channels = 1; else s->nb_channels = 2; if (bitrate_index != 0) { frame_size = ff_mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index]; s->bit_rate = frame_size * 1000; switch(s->layer) { case 1: frame_size = (frame_size * 12000) / sample_rate; frame_size = (frame_size + padding) * 4; break; case 2: frame_size = (frame_size * 144000) / sample_rate; frame_size += padding; break; default: case 3: frame_size = (frame_size * 144000) / (sample_rate << s->lsf); frame_size += padding; break; } s->frame_size = frame_size; } else { /* if no frame size computed, signal it */ return 1; }#if defined(DEBUG) dprintf(s->avctx, "layer%d, %d Hz, %d kbits/s, ", s->layer, s->sample_rate, s->bit_rate); if (s->nb_channels == 2) { if (s->layer == 3) { if (s->mode_ext & MODE_EXT_MS_STEREO) dprintf(s->avctx, "ms-"); if (s->mode_ext & MODE_EXT_I_STEREO) dprintf(s->avctx, "i-"); } dprintf(s->avctx, "stereo"); } else { dprintf(s->avctx, "mono");} dprintf(s->avctx, "\n");#endif return 0;}int ff_id3v2_match(const uint8_t *buf){ return buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3' && buf[3] != 0xff && buf[4] != 0xff && (buf[6] & 0x80) == 0 && (buf[7] & 0x80) == 0 && (buf[8] & 0x80) == 0 && (buf[9] & 0x80) == 0;}代码摘在ffmpeg
文件格式详细说明参考:
http://blog.csdn.net/sunshine1314/article/details/2514322
经验证,MP3文件可以在任意位置切割,切割后的文件是依然可以播放的。
个人认为,通过代码学习文件格式比阅读文档要深刻快速,当然文档的表达能力也不能被忽略。
- MP3文件格式分析
- MP3文件格式分析
- MP3文件格式分析
- MP3文件格式分析
- MP3文件格式分析
- MP3文件格式分析
- MP3文件格式分析详解(实例分析)
- MP3文件格式
- MP3文件格式
- mp3文件格式
- MP3文件格式
- MP3 文件格式
- MP3文件格式
- MP3文件格式
- mp3文件格式
- MP3文件格式
- MP3 文件格式
- MP3文件格式
- HDU What Are You Talking About
- gdb调试android
- 数据库镜像简介
- perl 参数传递
- ios 字符转换
- MP3文件格式分析
- spring 文件上传原理 (在非spring环境中可以使用)
- fstat、stat和lstat 区别
- 正则表达式语法
- SQL Server 2005 镜像构建手册
- 用批处理文件双击直接打开class文件
- 我的“路”
- 分页
- 杭电OJ2087 剪花布条