lame解码mp3时兼容性问题

阅读: 评论:0

lame解码mp3时兼容性问题

lame解码mp3时兼容性问题

    解决了lame-3.100交叉编译问题后,照着API文档实现了mp3编码,解码部分lame也有实现,使用的是mpg123的老版本库,通过hip这个接口实现,在lame.h中就hip_decode_init , hip_decode_exit, hip_decode , hip_decode_headers 这么几个函数体现。

    通过下面这个循环解析出帧格式,发现有很多mp3解析不对,兼容性不好。

while (!mp3data.header_parsed) {len = fread(buf, 1, sizeof(buf), inputFile);if (len != sizeof(buf))return -1;ret = hip_decode1_headers(hip, buf, len, pcm_l, pcm_r, &mp3data);if (-1 == ret){break;}}

    但是,在shell中使用指令lame --decode可以把mp3转换为wav格式,解析不对的mp3都使用正常,发现lame  decode并不是使用上面的调用方法。把lame库代码添加到source insight工程,然后查找main函数,跳转到lame_main,发现指令解析mp3时主要调用的get_audio.h中的 int     init_infile(lame_t gfp, char const * inPath); 函数。然后顺藤摸瓜,找到了函数int
lame_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding)

    显然,要从库里调用这个函数不太现实,把frontend里的文件移植到工程中也比较麻烦,好在我只需要播放mp3,不太关注帧格式的信息,就从lame_decode_initfile提取部分代码到自己的函数中。

hip_decode_init();
memset(mp3data, 0, sizeof(mp3data_struct));len = 4;if (fread(buf, 1, len, fd) != len)return -1;      /* failed */while (buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') {len = 6;if (fread(&buf[4], 1, len, fd) != len)return -1;  /* failed */len = lenOfId3v2Tag(&buf[6]);if (global.in_id3v2_size < 1) {global.in_id3v2_size = 10 + len;global.in_id3v2_tag = malloc(global.in_id3v2_size);if (global.in_id3v2_tag) {memcpy(global.in_id3v2_tag, buf, 10);if (fread(&global.in_id3v2_tag[10], 1, len, fd) != len)return -1;  /* failed */len = 0; /* copied, nothing to skip */}else {global.in_id3v2_size = 0;}}fseek(fd, (long) len, SEEK_CUR);len = 4;if (fread(&buf, 1, len, fd) != len)return -1;  /* failed */}aid_header = check_aid(buf);if (aid_header) {if (fread(&buf, 1, 2, fd) != 2)return -1;  /* failed */aid_header = (unsigned char) buf[0] + 256 * (unsigned char) buf[1];if (global_ui_config.silent < 9) {console_printf("Album ID found.  length=%i n", aid_header);}/* skip rest of AID, except for 6 bytes we have already read */fseek(fd, aid_header - 6, SEEK_CUR);/* read 4 more bytes to set up buffer for MP3 header check */if (fread(&buf, 1, len, fd) != len)return -1;  /* failed */}len = 4;while (!is_syncword_mp123(buf)) {unsigned int i;for (i = 0; i < len - 1; i++)buf[i] = buf[i + 1];if (fread(buf + len - 1, 1, 1, fd) != 1)return -1;  /* failed */}if ((buf[2] & 0xf0) == 0) {freeformat = 1;}/* now parse the current buffer looking for MP3 headers.    *//* (as of 11/00: mpglib modified so that for the first frame where  *//* headers are parsed, no data will be decoded.   *//* However, for freeformat, we need to decode an entire frame, *//* so mp3data->bitrate will be 0 until we have decoded the first *//* frame.  Cannot decode first frame here because we are not *//* yet prepared to handle the output. */ret = hip_decode1_headersB(global.hip, buf, len, pcm_l, pcm_r, mp3data, enc_delay, enc_padding);if (-1 == ret)return -1;/* repeat until we decode a valid mp3 header.  */while (!mp3data->header_parsed) {len = fread(buf, 1, sizeof(buf), fd);if (len != sizeof(buf))return -1;ret =hip_decode1_headersB(global.hip, buf, len, pcm_l, pcm_r, mp3data, enc_delay,enc_padding);if (-1 == ret)return -1;}if (mp3data->bitrate == 0 && !freeformat) {return lame_decode_initfile(fd, mp3data, enc_delay, enc_padding);}if (mp3data->totalframes > 0) {/* mpglib found a Xing VBR header and computed nsamp & totalframes */}else {/* set as unknown.  Later, we will take a guess based on file size* ant bitrate */mp3data->nsamp = MAX_U_32_NUM;}

    再把调用的几个小函数也copy过来,fskip直接用fseek替换了, is_syncword_mp123中不是sf_mp3就直接return 0。

    大致解读下这段函数意思,就是根据mp3的格式依次读取内容,首先识别ID3V2内容,然后是唱片集信息,然后是VBR帧头,注意vbr帧头的前4字节和mp3帧头的4字节格式相同,但总处在layer I层,就是这点害了我最上边那段解析的代码,读出来是不对的采样率和比特率,vbr帧头4字节后面是“Xing”火灾“lame”, 跳过vbr帧头才是mp3音频帧.

    解码的时候计算一下帧长度

// = 每帧采样率 / 8 × 比特率 / 采样频率 + 填充
    framesize = mp3data.framesize / 8 * mp3data.bitrate * 1000 / mp3data.samplerate + 1;

    vbr的时候帧长可变,好在hip会记录缓冲区上一次解码的地址,就默认每次都喂 framesize 个字节就能播放了,

使用的是hip_decode1,只解一帧或者不够一帧就返回0。

    MP3帧格式可搜索一下,有很多文章讲的很详细了。

本文发布于:2024-01-27 23:08:28,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063681093198.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:android编译lame
标签:兼容性问题   lame
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23