MTK音频播放器案例实现

移动开发
MTK音频播放器案例实现是本文介绍的内容,MTK平台对事件的处理是通过callback function方式, 所以程序的流程不是顺序的,主要是介绍MTK音频播放器的使用,具体内容的实现来看本文详解。

MTK音频播放器案例实现是本文介绍的内容,主要是介绍MTK音频播放器的使用。MTK 6225上的audio player 的结构整体上可以分为三层,最上面的应用程序界面层, 中间的audio 播放api层, 和底层的编解码库及音频驱动. 其结构图大致如下所示:

MTK音频播放器案例实现

由上图可以看出,整个调用层次较深. 我们分别来学习个层.
 
1、MMI Task 层

在该层 audio player 模块实现了播放器程序, 其中主要包括对界面视图的实现, 界面逻辑的处理以及调用MID模块的接口,实现音频操作. 在学习其具体的实现细节上,可以按view 和 model+control的简化MVC模式来看, 包含与显示有关的screen操作显示部分, 处理消息的msghandler部分以及主的程序逻辑及按键处理部分.

MTK平台对事件的处理是通过callback function方式, 所以程序的流程不是顺序的, 事件的发生将导致相应的callback被调用, 从而触发整个audio player的一次响应. 需要注意的是,在每个不同的界面对相同事件的处理callback函数可能有所不同, 这是在创建,进入该界面时设定的. 

该模块的接口比较复杂,为了提供对BT的统一接口, 有两层的播放接口,如mmi_audply_play 和 mmi_audply_do_play_action(). 整个模块的接口不够清晰, 有些庞杂和混乱. 模块的显示部分使用控件实现,较为简单, 可进一步参考控件的实现细节以了解平台的显示子系统, 对播放文件列表的管理是通过文件操作实现的,具体可参见audioplayerplaylist部分.

MDI层和Media接口层,这两个部分可看作一个整体, 是MMI层对媒体操作的封装.它包括了多个部分的接口,在此我们只看audio接口部分,其他模块如video,fm的接口类似. Audio接口包括了播放,暂停,停止,获取播放时间,获取播放频谱等. 这些接口基本上都是按同步处理方式实现的. 比如播放接口:

MDI层接口是

  1. mdi_result mdi_audio_play_file(void *file_name, U8 play_style, void *cache_p, mdi_callback handler); 

调用的Media接口为:

  1. kal_int32 media_aud_play_file(module_type src_mod_id, void *file_param)  
  2. {  
  3.       aud_result = MED_RES_OK;  
  4.     aud_send_play_file_req(src_mod_id, file_param);  
  5.     AUD_WAIT_EVENT(AUD_EVT_PLAY);  
  6.     return aud_result;  

其中的aud_send_play_file_req(src_mod_id, file_param调用msg_send_ext_queue(ilm_ptr);

向media task的external Message queue 发送播放请求消息.其中AUD_WAIT_EVENT(AUD_EVT_PLAY);定义如下:

  1. #define AUD_WAIT_EVENT(evt_) do{                                   
  2.          kal_uint32 retrieved_events;                                    
  3.          kal_retrieve_eg_events(aud_context_p->aud_event, (evt_),            
  4.          KAL_OR_CONSUME, &retrieved_events, KAL_SUSPEND); }while(0) 

等待AUD_EVT_PLAY事件的到达. 通过事件实现了同步.
 
2、Media Task层, media task启动后, med_task_main在获得外部消息后,调用med_main((void*)&current_ilm);进行消息处理, med_main会根据消息类型再进行一次
分发 ,audio消息会被分发给void aud_main(ilm_struct *ilm_ptr)来进行处理. 根据相应的请求消息,aud_main调用相应的handler函数进行处理.如对播放请求消息MSG_ID_L4AUD_MEDIA_PLAY_REQ的处理函数如下:

  1. void aud_media_play_req_hdlr(ilm_struct *ilm_ptr)  
  2. {  
  3. …. // 省略其他分支处理,及错误处理  
  4.    
  5. // step 1::释放冲突资源, 设置播放的参数等  
  6.    
  7. // step 2: 根据格式选择播放函数  
  8. switch (aud_context_p->current_format)  
  9. {      
  10.      ...  
  11.      case MED_TYPE_MMF:  
  12.       result = aud_melody_play_by_name(msg_p->file_name, msg_p->play_style, 0);  
  13.       break;  
  14.     …  
  15.     case MED_TYPE_M4A:  
  16.       aud_context_p->source_type = AUD_FILE;  
  17.       aud_context_p->play_style = msg_p->play_style;  
  18.       result = aud_media_play_file_stream(  
  19.               msg_p->file_name,  
  20.               msg_p->play_style,  
  21.               1,  
  22.               KAL_FALSE,  
  23.               msg_p->cache_p);  
  24.        break;  
  25.            case MED_TYPE_3GP:  
  26.        case MED_TYPE_MP4:  
  27.             aud_context_p->source_type = AUD_FILE;  
  28.             aud_context_p->play_style = msg_p->play_style;  
  29.             result = aud_media_play_audio_track_in_video(  
  30.                         msg_p->file_name,  
  31.                         msg_p->play_style,  
  32.                         KAL_TRUE,  
  33.                         KAL_FALSE);  
  34.             break;  
  35.         default:  
  36.             result = MED_RES_INVALID_FORMAT;  
  37.             break;  
  38. }  
  39.    
  40. // step 3: 开始播放后处理  
  41. aud_set_result((kal_int32) result);        // 设置播放操作返回结果  
  42. AUD_SET_EVENT(AUD_EVT_PLAY); // 设置AUD_EVT_PLAY事件  
  43. if (aud_context_p->src_mod != MOD_MMI) //播放请求是否来自MMI task  
  44. {  
  45.      aud_send_media_play_cnf(result);   //发送播放反馈消息到请求模块  
  46. }  

3、L1Audio module层, 该层包括了底层的解码库和对更底层的驱动程序,及音频硬件的调用和处理. 其中包括了对具体的音频格式的处理接口,如对AAC文件的接口有:

  1. MHdl *AAC_Open(void(*handler)( MHdl *handle, Media_Event event ),  
  2. STFSAL *pstFSAL, void *param)  
  3. Media_Status aacMFPlayFile( MHdl *hdl );  
  4. Media_Status aacMFResumeFile( MHdl *hdl );  
  5. Media_Status aacMFPause( MHdl *hdl );  
  6. Media_Status aacMFStop( MHdl *hdl ); 

....

一整套的接口. 在上面的第二层的讲解中的play请求的处理函数中, 如果待处理的文件格式是AAC, 则实现上它会调用AAC_Open接口来获得与播放操作相关的所有函数接口. 为此后的其他操作提供处理函数.

MTK的task和mod是怎么划分的?

实在搞不清MTK中task与mod,一个task就只加载一个mod么?

在task_init.c 里面void InitApplication()中,

  1. for(i=0;i<TOTAL_TASKS-9;i++)  
  2.  {  
  3.   task_info_g1[i+9].task_ext_qid=OslCreateMsgQ(task_create_tbl[i].task_qname,  
  4.         sizeof(MYQUEUE),  
  5.         task_create_tbl[i].task_ext_qsize);  
  6.   task_info_g1[i+9].task_id = osl_create_task (task_create_tbl[i].task_name,  
  7.         task_create_tbl[i].task_priority,  
  8.         task_create_tbl[i].task_stack_size,  
  9.         task_create_tbl[i].task_entry_func,  
  10.         (void *)(i+9),0);  
  11.    
  12.   task_info_g1[i+9].task_name=task_create_tbl[i].task_name;  
  13.   task_info_g1[i+9].task_priority=task_create_tbl[i].task_priority;  
  14.   task_info_g1[i+9].task_stack_size=task_create_tbl[i].task_stack_size;  
  15.   task_info_g1[i+9].task_entry_func=task_create_tbl[i].task_entry_func;  
  16.  
  17.   task_info_g1[i+9].task_qname=task_create_tbl[i].task_qname;  
  18.   task_info_g1[i+9].task_ext_qsize=task_create_tbl[i].task_ext_qsize;  
  19.  
  20.  } 

这里为什么是task_info_g1[i+9],在0到9的位置上还有 别的什么任务在运行?

这里生成的各个任务,TOTAL_TASKS的定义,我选取了MMItask.c中的一个如下:

  1. #ifdef MMI_ON_WIN32  
  2. #define MOD_MMI MOD_PRT  
  3. typedef enum {  
  4.   MOD_DUM1=0x09,  
  5.   MOD_L4C1,  
  6.   MOD_PRT,  
  7.   MOD_DUM2,  
  8.   TOTAL_TASKS  
  9. }task_indx_type;  
  10. extern osl_task_info   task_info_g1[TOTAL_TASKS];  
  11. #endif 

这一看, 在task生成之时,就把task和mod对上关系了。但是任务通信时,又有很多msg_send_ext_queue 和receive_ext_queue,src_mod_id 和dest_mod_id,分别为不同的mod。

请教除了MMI task与MOD_MMI,别的mod在哪些任务中运行?

不是的。task就像一个进程一样在运行,当从队列中得到消息后就被唤醒。

一个task可以加载N个mod。

小结:MTK音频播放器案例实现的内容介绍完了,希望通过本文的学习能对你有所帮助!

责任编辑:zhaolei 来源: 互联网
相关推荐

2011-09-06 10:46:19

QT播放器

2011-07-20 16:21:20

iPhone 视频 播放器

2012-06-04 13:44:08

2010-06-11 12:53:56

openSUSE播放器

2021-01-19 13:30:52

Linux播放器互联网

2011-06-13 09:33:04

2022-08-16 17:37:06

视频播放器鸿蒙

2015-09-16 16:38:10

QmmpWinampUbuntu

2011-06-27 11:23:21

Qt 音乐播放器

2023-04-06 13:47:47

2011-09-09 11:28:35

Android Mus

2015-05-21 15:25:42

VLC播放器

2010-07-30 09:35:47

Flex播放器

2018-05-25 14:37:58

2009-12-17 15:10:31

Linux音乐播放器

2022-06-21 14:41:38

播放器适配西瓜视频

2014-12-31 16:52:53

音乐播放器源码

2012-05-03 09:51:09

HTML5

2010-07-30 09:50:36

Flex播放器

2013-01-04 09:40:16

点赞
收藏

51CTO技术栈公众号