遇到一个MP3解析奇怪的问题,请格式老怪or高手进来瞧一瞧
有一首特殊的音乐,在智能机(安卓)上显示专辑图片是OK的,如图1。早MTK6257上是不正常的。
有个解析MP3的函数比较可疑。
static BOOL mmi_audply_parse_id3_cover(kal_char* filepath)
{
FS_HANDLE handle;
U8* temp_buf_pool = NULL;
const U32 temp_buf_pool_size = 1024;
U32 read_size = 0;
U32 read_offset = 0;
S32 buf_offset = -1;
U32 id3v2_header_offset = 0;
S32 id3v2_header_size = 0;
U32 id_offset = 0;
U32 frame_offset = 0;
S32 frame_size = 0;
S8* frame_data = NULL;
S8* frame_ptr = NULL;
S32 len = 0;
U8* frame_size_p = NULL;
U8 text_encoding = 0;
//const U8 frame_id[] = ID3TAG_APIC_ID;
//const S8 frame_id_length = ID3TAG_APIC_ID_LEN;
S8 img_type_string[AUDPLY_COVER_TYPE_MAX_LENGTH];
/* reset the cover status */
audply_cover.exist = ID3_COVER_DEFAULT;
if ((temp_buf_pool = (U8 *)mmi_mply_malloc(temp_buf_pool_size)) == NULL)
{
return FALSE;
}
if ((handle = FS_Open((PU16) g_audply.item.MusicPath.Path, FS_READ_ONLY)) < FS_NO_ERROR)
{
mmi_mply_free((void*)temp_buf_pool);
return FALSE;
}
/* find "ID3" header first */
FS_Seek(handle, 0, FS_FILE_BEGIN);
FS_Read(handle, temp_buf_pool, 3, &read_size);
if (read_size < 3)
{
FS_Close(handle);
mmi_mply_free((void*)temp_buf_pool);
return FALSE;
}
if ((temp_buf_pool[0] == 'I') &&
(temp_buf_pool[1] == 'D') &&
(temp_buf_pool[2] == '3') )
{
id3v2_header_offset = 0;
}
/* if ID3 V2 header not found */
else
{
FS_Close(handle);
mmi_mply_free((void*)temp_buf_pool);
return FALSE;
}
/* get ID3 V2 size */
FS_Seek(handle, id3v2_header_offset+6, FS_FILE_BEGIN);
FS_Read(handle, temp_buf_pool, sizeof(S32), &read_size);
frame_size_p = (U8*)&id3v2_header_size;
frame_size_p[0] = temp_buf_pool[3];
frame_size_p[1] = temp_buf_pool[2];
frame_size_p[2] = temp_buf_pool[1];
frame_size_p[3] = temp_buf_pool[0];
/* find APIC frame then */
read_size = temp_buf_pool_size;
read_offset = id3v2_header_offset;
do
{
FS_Seek(handle, read_offset, FS_FILE_BEGIN);
FS_Read(handle, temp_buf_pool, temp_buf_pool_size, &read_size);
buf_offset = match_apic_id(temp_buf_pool, read_size);
if(buf_offset >= 0)
{
id_offset = read_offset + buf_offset;
break;
}
read_offset += temp_buf_pool_size - ID3TAG_APIC_ID_LEN;
if(read_offset > id3v2_header_offset + id3v2_header_size)
{
break;
}
} while(read_size > 0);
/* if APIC frame not found */
if (id_offset == 0)
{
FS_Close(handle);
mmi_mply_free((void*)temp_buf_pool);
return FALSE;
}
/* Get APIC frame data */
frame_offset = id_offset + 10; /* Header size is 10 bytes */
/* Get frame size */
FS_Seek(handle, id_offset+4, FS_FILE_BEGIN);
FS_Read(handle, temp_buf_pool, sizeof(S32), &read_size);
frame_size_p = (U8*)&frame_size;
frame_size_p[0] = temp_buf_pool[3];
frame_size_p[1] = temp_buf_pool[2];
frame_size_p[2] = temp_buf_pool[1];
frame_size_p[3] = temp_buf_pool[0];
/* in case of too large size causing access violation */
if (frame_size >= AP_MAX_COVER_LEN)
{
FS_Close(handle);
mmi_mply_free((void*)temp_buf_pool);
return FALSE;
}
if ((frame_data = (S8 *)mmi_mply_malloc(frame_size)) == NULL)
{
FS_Close(handle);
mmi_mply_free((void*)temp_buf_pool);
return FALSE;
}
FS_Seek(handle, frame_offset, FS_FILE_BEGIN);
FS_Read(handle, frame_data, frame_size, &read_size);
if(read_size == 0)
{
FS_Close(handle);
mmi_mply_free((void*)temp_buf_pool);
mmi_mply_free((void*)frame_data);
return FALSE;
}
/* Get picture MIME type and data offset */
text_encoding = frame_data[0];
strcpy(img_type_string, frame_data+1);
frame_ptr = frame_data + strlen(img_type_string) + 2; /* Now point to 'Description' filed */
/* Process the 'Description' text */
switch(text_encoding)
{
case 1: /* UTF16 */
case 2: /* UTF16_BE */
{
len = mmi_ucs2strlen(frame_ptr);
frame_ptr = frame_ptr + len + 2;
}
break;
case 0: /* ISO_8859_1 */
case 3: /* UTF8 */
default:
{
if (0 == *frame_ptr)
{
*frame_ptr = 0x03;
}
len = strlen(frame_ptr);
frame_ptr = frame_ptr + len + 1;
}
break;
}
audply_cover.size = frame_size - ((U32)frame_ptr - (U32)frame_data);
if (audply_cover.size >= AP_MAX_COVER_LEN)
{
FS_Close(handle);
mmi_mply_free((void*)temp_buf_pool);
mmi_mply_free((void*)frame_data);
return FALSE;
}
if (!strcmp(img_type_string, "image/jpeg"))
{
audply_cover.type = GDI_IMAGE_TYPE_JPG;
}
else if (!strcmp(img_type_string, "image/png"))
{
audply_cover.type = GDI_IMAGE_TYPE_PNG;
}
//added by zhangfuping for PR 17056 begin
else if (!strcmp(img_type_string, "image/gif"))
{
audply_cover.type = GDI_IMAGE_TYPE_GIF;
}
//added by zhangfuping for PR 17056 end
else
{
FS_Close(handle);
mmi_mply_free((void*)temp_buf_pool);
mmi_mply_free((void*)frame_data);
return FALSE;
}
if (audply_cover.data)
{
mmi_mply_free((void *)audply_cover.data);
audply_cover.data = NULL;
}
audply_cover.data = (U8 *)mmi_mply_malloc(audply_cover.size + 1);
if (audply_cover.data)
{
memset((void *)audply_cover.data, 0, (audply_cover.size + 1));
memcpy(audply_cover.data, frame_ptr, audply_cover.size);
audply_cover.exist = ID3_COVER_PARSED;
}
FS_Close(handle);
mmi_mply_free((void*)temp_buf_pool);
mmi_mply_free((void*)frame_data);
return TRUE;
}
此歌曲的属性title是乱码,若改为正常的字串,在audio player的Song info的模式下,是可以正常显示出背景图片的,而在show lyric模式下则显示出错。 MP3解析 编码
补充:移动开发 , 移动开发其他问题