当前位置:编程学习 > wap >>

遇到一个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解析 编码
补充:移动开发 ,  移动开发其他问题
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,