在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

全志R128基礎組件開發指南—RTOS多媒體解碼

冬至子 ? 來源:丨budboool ? 作者:丨budboool ? 2023-10-10 16:28 ? 次閱讀

RTOS 多媒體解碼

介紹 FreeRTOS 下如何使用 rtplayer 的接口來開發播放器應用程序,方便播放器開發人員快速正確地開發,以及播放器測試人員如何根據該文檔對 rtplayer 播放器進行驗證測試。

RTPLAYER 狀態圖

這張狀態轉換圖清晰地描述了 rtlayer 的各個狀態,也列舉了主要的方法的調用時序,每種方法只能在一些特定的狀態下使用,否則會出錯。另外,只有在 Prepared、Started、Paused、Play?backCompleted 這四種狀態下可以進行 seekTo() 操作,并且 seekTo() 之后,狀態不變。

image-20230512165957929.png

Idle 狀態

Idle 狀態:當調用 player_init() 創建一個 rtplayer 或者調用了其 reset() 方法時,rtplayer 處于 idle狀態。

Initialized 狀態

這個狀態比較簡單,調用 setDateSource_url() 方法就進入 Initialized 狀態,表示此時要播放的文件已經設置好了

Preparing 狀態

調用 prepare() 函數還沒返回或者是調用 prepareAsync() 并且還沒收到 RTPLAYER_NOTIFY_PREPARED 這個回調消息的時候就處于 Preparing 狀態

Prepared 狀態

調用 prepare() 函數已經返回或者是調用 prepareAsync() 并且已經收到 RTPLAYER_NOTIFY_PREPARED 這個回調消息之后的狀態就處于 Prepared 狀態。在這個狀態下說明所有的資源都已經就緒了,調用 start() 函數就可以播放了。

Started 狀態

rtplayer 一旦 prepare 完成,就可以調用 start() 方法,這樣 rtplayer 就處于 Started 狀態,這表明 rtplayer 正在播放文件過程中。可以使用 XPlayerIsPlaying() 測試 rtplayer 是否處于了 Started 狀態。如果播放完畢,而又設置了循環播放,則 rtplayer 仍然會處于 Started 狀態。

Paused 狀態

Started 狀態下可以調用 pause_l() 方法暫停 rtplayer,從而進入 Paused 狀態,rtplayer 暫停后再次調用 start() 則可以繼續 TPlayer 的播放,轉到 Started 狀態。

Stopped 狀態

Started 或者 Paused 狀態下均可調用 stop() 停止 rtplayer,而處于 Stop 狀態的 rtplayer 要想重新播放,需要通過 prepareAsync() 和 prepare() 回到先前的 Prepared 狀態重新開始才可以。

PlaybackCompleted 狀態

文件正常播放完畢,而又沒有設置循環播放的話就進入該狀態,并且會通過 RTPLAYER_NOTIFY_PLAYBACK_COMPLETE 這個消息回調給應用。此時可以調用 start() 方法重新從頭播放文件,也可以 stop() 停止 rtplayer,或者也可以 seekTo() 來重新定位播放位置。

Error 狀態

由于某種原因 rtplayer 出現了錯誤,就會進入該狀態,并且會通過 RTPLAYER_NOTIFY_MEDIA_ERROR 這個消息回調給應用。如果 rtplayer 進入了 Error 狀態,可以通過調用 reset() 來恢復,使得 rtplayer 重新返回到 Idle 狀態。

End 狀態

通過 plater_deinit() 的方法可以進入 End 狀態,只要 rtplayer 不再被使用,就應當盡快將其 destroy 掉。

rtplayer 層接口

創建一個 RTPLAYER

函數原型

uint32_t player_init(void)

參數:

返回值:

  • 成功返回 rtplayer 的指針,失敗返回 NULL

銷毀一個 RTPLAYER

函數原型

void player_deinit(void* handle)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針

返回值:

設置 RTPLAYER 的消息回調函數

函數原型

void registerCallback(void* handle, void* userData, player_callback_t fn)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針
  • userData: 回調消息處理對象
  • fn: 回調消息處理函數指針,需要由應用實現

返回值:

創建完 rtplayer 播放器之后,就要調用該函數設置回調消息處理函數。

設置播放文件的 URL

可以是本地文件也可以是網絡源

函數原型

status_t setDataSource_url(void* handle,void* userData, const char * url, int id)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針
  • userData: 回調消息處理對象
  • url: 需要播放的文件的 url
  • id: 回調時使用的播放索引, 為 0 即可

返回值:

  • 成功返回 0,失敗返回?1 或錯誤碼

解析文件頭部信息,獲取元數據

函數原型

status_t prepare(void* handle)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針;

返回值:

  • 成功返回 0,失敗返回?1 或錯誤碼

異步解析文件頭部信息,獲取元數據

函數原型

status_t prepareAsync(void* handle)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針;

返回值:

  • 成功返回 0,失敗返回?1

該函數是非阻塞函數,需要等到 RTPLAYER_NOTIFY_P? REPARED 消息回調之后才能調 start() 函數進行播放,而且 start() 函數不能在回調函數中調用

開始播放

函數原型

status_t start(void* handle)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針;

返回值:

  • 成功返回 0,失敗返回?1

暫停播放

函數原型

status_t pause_l(void* handle)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針;

返回值:

  • 成功返回 0,失敗返回?1

停止播放

函數原型

status_t stop(void* handle)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針

返回值:

  • 成功返回 0,失敗返回?1

重置播放器

函數原型

status_t reset(void* handle)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針;

返回值:

  • 成功返回 0,失敗返回?1

在任何狀態下都可以調用該函數,每次播放不同的音頻之前,都需要調用該函數重置播放器,另外,一般收到 RTPLAYER_NOTIFY_MEDIA_ERROR 這個消息的時候,也需要通過調用該函數來重置播放器。但是不能在回調函數中調用該函數,否則會出現死鎖

跳播

函數原型

status_t seekTo(void* handle, int sec)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針
  • sec: 跳播的位置,單位是:s

返回值:

  • 成功返回 0,失敗返回?1

獲取當前播放的位置

函數原型

status_t getCurrentPosition(void* handle, int * sec)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針;
  • sec: 存放當前播放的位置值,單位:s

返回值:

  • 成功返回 0,失敗返回?1

獲取播放的文件總時長

函數原型

status_t getDuration(void* handle, int * sec)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針;
  • sec: 存儲文件總時長,單位:s

返回值:

  • 成功返回 0,失敗返回?1

需要在 prepared 狀態之后才可以調用該函數

獲取播放的文件信息

函數原型

MediaInfo* getMediaInfo(void* handle)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針;

返回值:

  • 成功返回 0,失敗返回?1

需要在 prepared 狀態之后才可以調用該函數

設置循環播放模式

函數原型

status_t setLooping(void* handle, int loop)

參數:

  • handle: 通過 player_init() 函數創建的 rtplayer 指針;
  • loop:1 表示單曲循環,0 表示不會單曲循環

返回值:

  • 成功返回 0,失敗返回?1

XPlayer 層播放接口

創建一個 XPLAYER

函數原型

XPlayer* XPlayerCreate()

參數:

返回值:

  • 成功: XPlayer 指針; 失敗: NULL

設置 XPLAYER 的回調通知

函數原型

int XPlayerSetNotifyCallback(XPlayer* p, XPlayerNotifyCallback notifier, void* pUserData)

參數:

  • P:通過 XPlayerCreate 創建的 Xplayer 指針
  • notifier:回調通知
  • pUserData:應用程序傳下來的自定義數據

返回值:

  • 成功:XPlayer 指針;失敗:NULL

Xplayer 將接收來自下層的回調通知,進行相應的操作

創建指向音頻播放設備管理模塊的指針,用于播放音頻

函數原型

SoundCtrl* RTSoundDeviceCreate(int card)

參數:

  • card:聲卡序號0:default;1:sw:audio1;2:sw:audio2;3:sw:audio3;4:sw:audio4;5:sw:audio5

返回值:

  • 成功:音頻播放設備管理模塊的指針;失敗:NULL

創建指向音頻播放設備管理模塊的指針,用于播放音頻

函數原型

int XPlayerSetDataSourceUrl(XPlayer* p, const char* pUrl, void* httpService, const CdxKeyedVectorT* pHeaders)

參數:

  • pUrl:url 地址
  • httpService:服務器信息
  • pHeaders:頭文件信息

返回值:

  • 返回值: 成功:0;失敗:?1 或線程響應設置數據源命令的返回值或線程響應 xplayer prepare 命令的返回值

調用說明: 發送 SetDataSource 命令,獲取需要播放的音頻數據內容

將 XPLAYER 置為準備狀態, 解析頭部信息,獲取元數據

函數原型

int XPlayerPrepare(XPlayer* p)

參數:

  • p:通過 XPlayerCreate 創建的 Xplayer 指針

返回值:

  • 成功:線程響應異步 Prepare 命令的返回值;失敗:NULL

該函數是阻塞函數,調用完返回之后就進入了 Prepared 狀態,此時可調 XPlayerStart() 函數進行播放

將 XPLAYER 置為異步準備狀態

函數原型

int XPlayerPrepareAsync(XPlayer* p)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針

返回值:

  • 成功:線程響應異步 Prepare 命令的返回值;失敗:NULL

網絡播放源一般采用 PrepareAsync,而不是 Prepare 命令,PrepareAsync 命令的返回值為 0 時說明響應成功,播放器準備工作已經完成可以開始播放,為?1 時說明響應失敗

將 XPLAYER 置為啟動狀態

函數原型

int XPlayerStart(XPlayer* p)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針

返回值:

  • 成功:線程響應 start 命令的返回值;失敗:NULL

Start 命令的返回值為 0 時說明響應成功,為?1 時說明響應失敗

將 XPLAYER 置為暫停狀態

函數原型

int XPlayerPause(XPlayer* p)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針

返回值:

  • 成功:線程響應 pause 命令的返回值;失敗:NULL

在 XPlayer 處于 start 狀態時可調用此接口,Pause 命令的返回值為 0 時說明響應成功,為?1 時說明響應失敗

將 XPLAYER 置為停止狀態

函數原型

int XPlayerStop(XPlayer* p)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針

返回值:

  • 成功:返回 0;失敗:返回?1

重置 XPLAYER

將相關變量復位,并銷毀各模塊,如音頻解碼模塊、音頻解碼數據接收模塊等

函數原型

int XPlayerReset(XPlayer* p)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針

返回值:

  • 成功:線程響應 Reset 命令的返回值;失敗:NULL

Reset 命令的返回值為 0 時說明響應成功,為?1 時說明響應失敗

獲取節目時長

函數原型

int XPlayerGetDuration(XPlayer* p, int *msec)

參數:

  • p:通過 XPlayerCreate 創建的 Xplayer 指針
  • msec:保存節目時長

返回值:

  • 成功:0;失敗:?1

在 XPlayer 處于 PREPARED、STARTED、PAUSED、STOPPED 或 COMPLETE 狀態下才可調用此接口,否則操作無效

SEEK 到給定的時間點

函數原型

int XPlayerSeekTo(XPlayer* p, int nSeekTimeMs)

參數:

  • p:通過 XPlayerCreate 創建的 Xplayer 指針
  • nSeekTimeMs:跳轉的時間點

返回值:

  • 成功:線程響應 Seek 命令的返回值;失敗:NULL

如果跳轉前播放處于暫停狀態,則跳轉后將保持在暫停狀態

獲取媒體文件的總時長

函數原型

int XPlayerGetDuration(XPlayer* p, int *msec)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針
  • msec:保存媒體文件的總時長

返回值:

  • 成功:0;失敗:?1

需要在 prepared 狀態之后才可以調用該函數

獲取當前的播放時間點(即播放位置)

在 XPlayer 處于 PREPARED、STARTED、PAUSED、STOPPED 或 COMPLETE 狀態下才可調用此接口,否則操作無效,在 complete 狀態下,可能會調用 prepare 方法并更改媒體信息,獲取的播放時間以 ms 為單位

函數原型

int XPlayerGetCurrentPosition(XPlayer* p, int* msec)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針
  • msec:保存當前的播放時間

返回值:

  • 成功:0;失敗:?1

獲取媒體信息

函數原型

MediaInfo* XPlayerGetMediaInfo(XPlayer* p)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針

返回值:

  • 成功返回 0,失敗返回?1。如果失敗,則 mediaInfo 指針為 NULL

需要在 prepared 狀態之后才可以調用該函數

設置循環播放模式

函數原型

int XPlayerSetLooping(XPlayer* p, int loop)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針
  • loop: 1: 表示單曲循環模式;0:表示不會循環

返回值:

查詢是否正在播放

函數原型

int XPlayerIsPlaying(XPlayer* p)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針

返回值:

  • 1:正在播放;0:未播放

銷毀一個 XPLAYER

函數原型

void XPlayerDestroy(XPlayer* p)

參數:

  • p:通過 XPlayerCreate 創建的 XPlayer 指針

返回值:

播放器開發示例

  1. player_init() 創建一個播放器

  2. registerCallback() 設置消息回調函數

  3. setDataSource_url() 設置 url

  4. prepare() 或 prepareAsync() 解析頭部信息,獲取元數據,并根據元數據的信息初始化對應的解碼器

  5. start() 播放 (注: 如果是用 prepareAsync() 函數,則需要等到 RTPLAYER_NOTIFY_PREPARED 消息回調之后才可以調用 start() 函數進行播放)

  6. 如果需要跳播,則可以調用 seekTo() 函數

  7. 如果需要暫停,則調用 pause_l() 函數進行暫停

  8. 如果需要停止,則可以調用 stop() 或 reset() 函數進行停止 (注:建議用 reset() 函數進行停止,因為任何狀態下都可以調用 reset() 函數)

  9. 如果需要播放下一個或其他的,則可以先調用 reset() 函數使播放器進入 idle 狀態,然后再重復 (3)(4)(5) 的步驟

    include

    include

    include

    include

    include

    include

    include

    include

    include

    include

    include

    include

    include

    include "FreeRTOS_POSIX/utils.h"

    include "rtplayer.h"

    include "xplayer.h"

    define PAUSE_CMD 'P'

    define PING_CMD 'p'

    define STOP_CMD 'S'

    define SEEK_TO_CMD 's'

    define SEEK_TO_CMD2 'j'

    define BACKGROUND_CMD 'b'

    define SHOW_BUFFER_CMD 'B'

    define QUIT_CMD 'q'

    define LOOP_CMD 'l'

    define GET_DURATION_CMD 'G'

    define GET_POSITION_CMD 'g'

    define HELP_CMD 'h'

    define INFO_CMD 'i'

    define REPLAY_CMD 'r'

    define RETRY_CMD 256

    define USE_PREPARE_ASYNC 0

    define LOGD(msg, arg...) //printf("[PLAYER_DBG] <%s : %d> " msg "n", func , LINE , ##arg)

    define LOGI(msg, arg...) //printf("[PLAYER_INFO] <%s : %d> " msg "n", func , LINE , ##arg)

    define LOGW(msg, arg...) printf("[PLAYER_WRN] <%s : %d> " msg "n", func , LINE , ##arg)

    define LOGE(msg, arg...) printf("[PLAYER_ERR] <%s : %d> " msg "n", func , LINE , ##arg)

    typedef struct DemoPlayerContext
    {

    RTPlayer* mRTplayer;
    sem_t mPreparedSem;
    mqd_t mRTplayerMq;
    pthread_t mThreadId;
    char *pUrl;
    int mSeekable;
    char isPlayingFlag;
    char mError;
    int inputMode;
    int isSetLoop;
    char quitFlag;//no_shell_input mode quitFlag
    int testMode;
    MediaInfo* mMediaInfo;
    int SoundCard;
    

    }DemoPlayerContext;

    typedef struct DemoPlayerMsg
    {

    int msg;
    int data;
    

    }DemoPlayerMsg;

    define INVALID_MQD ( ( mqd_t ) -1 )

    define DEFAULT_MODE 0600

    static const char *pcRTplayerMqName = "/rtplayerMq";
    static volatile mqd_t mRTplayerMq = INVALID_MQD;
    static int mRTplayerUserInput = 0;
    static struct mq_attr xRTplayerMqAttr =

    {
        .mq_flags   =   0,
        .mq_maxmsg  =   3,
        .mq_msgsize =   sizeof(DemoPlayerMsg),
        .mq_curmsgs =   0
    };
    

    static void showHelp(){

    printf("n");
    printf("**************************n");
    printf("* This is a simple audio player, when it is started, you can input commands to telln");
    printf("* what you want it to do.n");
    printf("* Usage: n");
    printf("*   tplayer_demo /data/test.mp3  : this means play test.mp3n");
    printf("*   P  :this will Pause if in playing status,or Play in paused status n");
    printf("*   S  :this means Stop n");
    printf("*   s  :this means seek to 10s n");
    printf("*   B  :show buffer n");
    printf("*   b  :this means player will run in the background n");
    printf("*   q  :this means quit the player n");
    printf("*   l  :this means loop play n");
    printf("*   G :this means Get  duration n");
    printf("*   g :this means get  position n");
    printf("*   i :this means show media info n");
    printf("*   h :this means show the help information n");
    printf("*   r : replay the current audion");
    printf("**************************n");
    

    }
    static int rtplayer_clear_cmd(mqd_t mq){

    struct timespec cur, delay, abstime;
    clock_gettime( CLOCK_REALTIME, &cur );
    delay.tv_sec = 0;
    delay.tv_nsec = 5*1000*1000;
    UTILS_TimespecAdd(&cur, &delay, &abstime);
    DemoPlayerMsg msg;
    while(mq_timedreceive(mq, (char *)&msg, sizeof(msg), NULL, &abstime)!=-1);
    return 0;
    

    }
    static int rtplayer_send_cmd(mqd_t mq, int msg, int data){

    DemoPlayerMsg pmsg = {msg, data};
    struct timespec tsn, ts;
    clock_gettime(CLOCK_REALTIME, &tsn);
    UTILS_TimespecAddNanoseconds(&tsn, 20*1000*1000, &ts);
    int status = mq_timedsend(mq, (char *)&pmsg, sizeof(pmsg), 0, &ts);
    if(status)
        LOGE("send cmd %c,%d failed!", pmsg.msg, pmsg.data);
    return status;
    

    }

    static int rtplayer_send_cmd_force(mqd_t mq, int msg, int data){

    int try_times = 0;
    DemoPlayerMsg pmsg = {msg, data};
    struct timespec tsn, ts;
    int status;
    

    try_send:

    clock_gettime(CLOCK_REALTIME, &tsn);
    UTILS_TimespecAddNanoseconds(&tsn, 20*1000*1000, &ts);
    status = mq_timedsend(mq, (char *)&pmsg, sizeof(pmsg), 0, &ts);
    if(status){
        try_times++;
        if(try_times< 5){
            LOGE("send cmd %c,%d failed, retry...", pmsg.msg, pmsg.data);
            goto try_send;
        }
        else if(try_times< 10){
            DemoPlayerMsg tmp;
            LOGE("send cmd %c,%d failed, retry...", pmsg.msg, pmsg.data);
            clock_gettime(CLOCK_REALTIME, &tsn);
            UTILS_TimespecAddNanoseconds(&tsn, 20*1000*1000, &ts);
            status = mq_timedreceive(mq, (char *)&tmp, sizeof(tmp), NULL, &ts);
            if(status< 0){
                LOGE("mq_receive fail %d", status);
                goto fail_exit;
            }
            LOGW("drop: %c, %d", tmp.msg, tmp.data);
            goto try_send;
        }
        goto fail_exit;
    }
    return status;
    

    fail_exit:

    LOGE("send cmd %c,%d failed!n", pmsg.msg, pmsg.data);
    return status;
    

    }

    static void callbackFromRTplayer(void* userData,int msg, int id, int ext1, int ext2);
    static void* RTplayerThread(void* arg){

    DemoPlayerContext* demoPlayer = (DemoPlayerContext*)arg;
    char quitFlag = 0;
    
    if(demoPlayer- >inputMode)
    {
    while(1)
    {
         if(demoPlayer- >quitFlag)
         {
        if(demoPlayer- >mRTplayer != NULL)
        {
            printf("player finsh, quit the rtplayern");
            mRTplayerMq = INVALID_MQD;
    

    if USE_PREPARE_ASYNC

    sem_destroy(&demoPlayer- >mPreparedSem);
    

    endif

    player_deinit(demoPlayer- >mRTplayer);
            free(demoPlayer- >pUrl);
            free(demoPlayer);
        }
        break;
         }
        usleep(50*1000);
    }
    return NULL;
    
    }
    while(!quitFlag){
        int cRxed = 0;
        int data = 0;
        DemoPlayerMsg msg;
        ssize_t status;
        if(demoPlayer- >mRTplayerMq!=INVALID_MQD){
            usleep(50*1000);
            ssize_t status = mq_receive(demoPlayer- >mRTplayerMq, (char *)&msg, sizeof(msg), NULL);
            if(status<=-1){
                LOGE("mq_receive fail %d", status);
                usleep(1*1000*1000);
                continue;
            }
            printf("receive %c,%dn", msg.msg, msg.data);
            cRxed = msg.msg;
            data = msg.data;
        }
        else{
            cRxed = QUIT_CMD;
        }
        switch(cRxed){
            case PAUSE_CMD:
            {
                if(demoPlayer- >isPlayingFlag){
                    printf("pause the rtplayern");
                    pause_l(demoPlayer- >mRTplayer);
                    demoPlayer- >isPlayingFlag = 0;
                }else{
                    printf("play the rtplayern");
                    start(demoPlayer- >mRTplayer);
                    demoPlayer- >isPlayingFlag = 1;
                }
                break;
            }
            case STOP_CMD:
            {
                printf("stop the rtplayern");
                stop(demoPlayer- >mRTplayer);
                demoPlayer- >isPlayingFlag = 0;
                break;
            }
            case SEEK_TO_CMD:
            {
                printf("rtplayer seek to 10 secondn");
                seekTo(demoPlayer- >mRTplayer,10);
                break;
            }
            case SEEK_TO_CMD2:
            {
                printf("rtplayer seek to %d secondn", data);
                seekTo(demoPlayer- >mRTplayer,data);
                break;
            }
            case QUIT_CMD:
            {
                printf("quit the rtplayern");
                mRTplayerMq = INVALID_MQD;
                //mq_close(demoPlayer- >mRTplayerMq);
    

    if USE_PREPARE_ASYNC

    sem_destroy(&demoPlayer- >mPreparedSem);
    

    endif

    player_deinit(demoPlayer- >mRTplayer);
                free(demoPlayer- >pUrl);
                free(demoPlayer);
                quitFlag = 1;
                break;
            }
            case LOOP_CMD:
            {
                printf("let the rtplayer loop playn");
                demoPlayer- >isSetLoop = 1;
                setLooping(demoPlayer- >mRTplayer,1);
                break;
            }
            case GET_DURATION_CMD:
            {
                printf("get the audio durationn");
                int duration;
                getDuration(demoPlayer- >mRTplayer,&duration);
                printf("duration:%d sn",duration);
                break;
            }
            case GET_POSITION_CMD:
            {
                printf("get the current positionn");
                int position;
                getCurrentPosition(demoPlayer- >mRTplayer,&position);
                printf("current position:%d sn",position);
                break;
            }
            case HELP_CMD:
            {
                printf("show the help informationn");
                showHelp();
                break;
            }
        case INFO_CMD:
        {
        printf("**************************n");
        printf("* show media information:n");
        MediaInfo* mi = NULL;
        demoPlayer- >mMediaInfo = getMediaInfo(demoPlayer- >mRTplayer);
        if(demoPlayer- >mMediaInfo != NULL){
                        mi = demoPlayer- >mMediaInfo;
                        printf("* file size = %lld KBn",mi- >nFileSize/1024);
                        printf("* duration = %lld msn",mi- >nDurationMs);
                        printf("* bitrate = %d Kbpsn",mi- >nBitrate/1024);
                        printf("* container type = %dn",mi- >eContainerType);
                        printf("* audio stream num = %dn",mi- >nAudioStreamNum);
                        if(mi- >pAudioStreamInfo != NULL){
                            printf("* audio codec tpye = %dn",mi- >pAudioStreamInfo- >eCodecFormat);
                            printf("* audio channel num = %dn",mi- >pAudioStreamInfo- >nChannelNum);
                            printf("* audio BitsPerSample = %dn",mi- >pAudioStreamInfo- >nBitsPerSample);
                            printf("* audio sample rate  = %dn",mi- >pAudioStreamInfo- >nSampleRate);
                        }
        printf("**************************n");
                    }
                    break;
    
        }
        case SHOW_BUFFER_CMD:
        {
        printf("**************************n");
        printf("* show buffer information:n");
        player_show_buffer();
        printf("**************************n");
        break;
    
        }
            case REPLAY_CMD:
            {
                printf("replay %sn", demoPlayer- >pUrl);
                int ret;
                if(demoPlayer- >testMode){
                    printf("test mode: destroy & create instead of resetn");
                    player_deinit(demoPlayer- >mRTplayer);
                    usleep(50*1000);
                    demoPlayer- >mRTplayer = (RTPlayer*)(uintptr_t)player_init();
                    printf("demoPlayer.mRTplayer = %pn",demoPlayer- >mRTplayer);
                    if(!demoPlayer- >mRTplayer){
                        printf("init rtplayer failn");
                        free(demoPlayer- >pUrl);
                        free(demoPlayer);
                        quitFlag = 1;
                        continue;
                    }
                    registerCallback(demoPlayer- >mRTplayer, demoPlayer, callbackFromRTplayer);
                }
                else
                    reset(demoPlayer- >mRTplayer);
                ret = setDataSource_url(demoPlayer- >mRTplayer, demoPlayer, demoPlayer- >pUrl, 0);
                if(ret){
                    printf("setDataSource_url failedn");
                    break;
                }
                ret = prepare(demoPlayer- >mRTplayer);
                if(ret){
                    printf("prepare failedn");
                    break;
                }
                start(demoPlayer- >mRTplayer);
                demoPlayer- >isPlayingFlag = 1;
        if(demoPlayer- >isSetLoop)
        {
                    setLooping(demoPlayer- >mRTplayer,1);
        }
                break;
            }
            case RETRY_CMD:
            {
                int position = data;
                if(data==-1)
                    getCurrentPosition(demoPlayer- >mRTplayer,&position);
                printf("retry %sn", demoPlayer- >pUrl);
                int ret;
                if(demoPlayer- >testMode){
                    printf("test mode: destroy & create instead of resetn");
                    player_deinit(demoPlayer- >mRTplayer);
                    usleep(50*1000);
                    demoPlayer- >mRTplayer = (RTPlayer*)(uintptr_t)player_init();
                    printf("demoPlayer.mRTplayer = %pn",demoPlayer- >mRTplayer);
                    if(!demoPlayer- >mRTplayer){
                        LOGE("init rtplayer fail");
                        free(demoPlayer- >pUrl);
                        free(demoPlayer);
                        quitFlag = 1;
                        continue;
                    }
                    registerCallback(demoPlayer- >mRTplayer, demoPlayer, callbackFromRTplayer);
                }
                else
                    reset(demoPlayer- >mRTplayer);
                ret = setDataSource_url(demoPlayer- >mRTplayer, demoPlayer, demoPlayer- >pUrl, 0);
                if(ret){
                    LOGE("setDataSource_url failed");
                    rtplayer_send_cmd_force(demoPlayer- >mRTplayerMq, RETRY_CMD, position);
                    usleep(500*1000);
                    break;
                }
                ret = prepare(demoPlayer- >mRTplayer);
                if(ret){
                    LOGE("prepare failed");
                    rtplayer_send_cmd_force(demoPlayer- >mRTplayerMq, RETRY_CMD, position);
                    usleep(500*1000);
                    break;
                }
                start(demoPlayer- >mRTplayer);
                demoPlayer- >isPlayingFlag = 1;
                //seekTo(demoPlayer- >mRTplayer, position);
                if(demoPlayer- >isSetLoop)
                    setLooping(demoPlayer- >mRTplayer,1);
                break;
            }
            default:
            {
                LOGW("warning: unknown command,cmd = %d",cRxed);
                break;
            }
        }
        if(quitFlag){
            return NULL;
        }
    }
    return NULL;
    

    }
    static void callbackFromRTplayer(void* userData,int msg, int id, int ext1, int ext2){

    LOGI("call back from RTplayer,msg = %d,id = %d,ext1 = %d,ext2 = %dn",msg,id,ext1,ext2);
    
    DemoPlayerContext* pDemoPlayer = (DemoPlayerContext*)userData;
    switch(msg)
    {
        case RTPLAYER_NOTIFY_PREPARED:
        {
            printf("RTPLAYER_NOTIFY_PREPARED:has prepared.n");
    

    #if USE_PREPARE_ASYNC

    sem_post(&pDemoPlayer- >mPreparedSem);
            pDemoPlayer- >mPreparedFlag = 1;
    

    #endif

    break;
        }
        case RTPLAYER_NOTIFY_PLAYBACK_COMPLETE:
        {
            printf("RTPLAYER_NOTIFY_PLAYBACK_COMPLETE:play completen");
            pDemoPlayer- >isPlayingFlag = 0;
        if(pDemoPlayer- >inputMode)
        {
        pDemoPlayer- >quitFlag = 1;
        }
            break;
        }
        case RTPLAYER_NOTIFY_SEEK_COMPLETE:
        {
            printf("RTPLAYER_NOTIFY_SEEK_COMPLETE:seek okn");
            break;
        }
        case RTPLAYER_NOTIFY_MEDIA_ERROR:
        {
            switch (ext1)
            {
                case RTPLAYER_MEDIA_ERROR_UNKNOWN:
                {
                    printf("erro type:TPLAYER_MEDIA_ERROR_UNKNOWNn");
                    break;
                }
                case RTPLAYER_MEDIA_ERROR_UNSUPPORTED:
                {
                    printf("erro type:TPLAYER_MEDIA_ERROR_UNSUPPORTEDn");
                    break;
                }
                case RTPLAYER_MEDIA_ERROR_IO:
                {
                    printf("erro type:TPLAYER_MEDIA_ERROR_IOn");
                    break;
                }
            }
            printf("RTPLAYER_NOTIFY_MEDIA_ERRORn");
            pDemoPlayer- >mError = 1;
    

    if USE_PREPARE_ASYNC

    if(pDemoPlayer- >mPreparedFlag == 0){
                printf("recive err when preparingn");
                sem_post(&pDemoPlayer- >mPreparedSem);
            }
    

    endif

    if( pDemoPlayer- >mRTplayerMq!=INVALID_MQD ){
                rtplayer_send_cmd_force(pDemoPlayer- >mRTplayerMq, RETRY_CMD, -1);
            }
            else{
                printf("io error, mqueue not existn");
            }
            break;
        }
        case RTPLAYER_NOTIFY_NOT_SEEKABLE:
        {
            pDemoPlayer- >mSeekable = 0;
            printf("info: media source is unseekable.n");
            break;
        }
        case RTPLAYER_NOTIFY_DETAIL_INFO:
        {
            int flag = *(int *)(uintptr_t)ext2;
            //printf("detail info: %dn", flag);
            break;
        }
        default:
        {
            printf("warning: unknown callback from RTplayer.n");
            break;
        }
    }
    

    }
    int cmd_rtplayer_test(int argc, char ** argv)
    {

    int inputMode = 0;
    int testMode = 0;
    /*
    printf("argc = %dn",argc);
    for(int i=0; i < argc;i++){
        printf("argv[%d]=%sn",i,argv[i]);
    }
    */
    printf("rtplayer source:%sn", argv[1]);
    
    if(argc == 3){
        if( !strncmp("no_shell_input", argv[2], sizeof("no_shell_input")-1) ){
            argc--;
            inputMode = 1;
        }
        else if( !strncmp("test_mode", argv[2], sizeof("test_mode")-1) ){
            argc--;
            testMode = 1;
        }
    }
    if(argc != 2){
        LOGW("the parameter is error,usage is as following:");
        showHelp();
        goto rtp_failed;
    }
    

    if USE_PREPARE_ASYNC

    int waitErr = 0;
    

    endif

    DemoPlayerContext* demoPlayer = (DemoPlayerContext*)malloc(sizeof(DemoPlayerContext));
    if(demoPlayer == NULL){
        LOGE("malloc DemoPlayerContext fail");
        goto rtp_failed;
    }
    memset(demoPlayer, 0, sizeof(DemoPlayerContext));
    demoPlayer- >mSeekable = 1;
    demoPlayer- >mRTplayerMq = INVALID_MQD;
    demoPlayer- >inputMode = inputMode;
    demoPlayer- >testMode = testMode;
    demoPlayer- >quitFlag = 0;
    demoPlayer- >mMediaInfo = NULL;
    if(strlen(argv[1])<=0){
        LOGE("url error");
        goto rtp_url_failed;
    }
    demoPlayer- >pUrl = malloc(strlen(argv[1])+1);
    if(!demoPlayer- >pUrl){
        LOGE("pUrl malloc fail");
        goto rtp_url_failed;
    }
    memset(demoPlayer- >pUrl, 0, strlen(argv[1]));
    strcpy(demoPlayer- >pUrl, argv[1]);
    

    if USE_PREPARE_ASYNC

    sem_init(&demoPlayer- >mPreparedSem, 0, 0);
    

    endif

    demoPlayer- >mRTplayer = (RTPlayer*)(uintptr_t)player_init();
    LOGI("demoPlayer.mRTplayer = %p",demoPlayer- >mRTplayer);
    if(!demoPlayer- >mRTplayer){
        LOGE("init rtplayer fail");
        goto rtp_init_failed;
    }
    
    registerCallback(demoPlayer- >mRTplayer, demoPlayer, callbackFromRTplayer);
    status_t ret = setDataSource_url(demoPlayer- >mRTplayer,demoPlayer,demoPlayer- >pUrl, 0);
    if(ret){
        LOGE("set DataSource url fail");
        goto rtp_prepare_failed;
    }
    

    if USE_PREPARE_ASYNC

    demoPlayer- >mPreparedFlag = 0;
    if(prepareAsync(demoPlayer- >mRTplayer) != 0)
    {
        printf("TPlayerPrepareAsync() return fail.n");
    }else{
        printf("preparing...n");
    }
    struct timespec t;
    t.tv_nsec = 0;
    t.tv_sec = 30;
    waitErr = sem_timedwait(&demoPlayer- >mPreparedSem, &t);
    if(waitErr == -1){
        printf("prepare timeout,has wait %d sn",t.tv_sec);
        sem_destroy(&demoPlayer- >mPreparedSem);
        goto rtp_prepare_failed;
    }else if(demoPlayer.mError == 1){
        printf("prepare failn");
        sem_destroy(&demoPlayer- >mPreparedSem);
        goto rtp_prepare_failed;
    }
    printf("prepared okn");
    

    else

    ret = prepare(demoPlayer- >mRTplayer);
    if(ret){
        LOGE("prepare fail");
        goto rtp_prepare_failed;
    }
    

    endif

    start(demoPlayer- >mRTplayer);
    demoPlayer- >isPlayingFlag = 1;
    
    if( mRTplayerMq==INVALID_MQD ){
        mRTplayerMq = mq_open( pcRTplayerMqName, O_CREAT | O_RDWR, DEFAULT_MODE, &xRTplayerMqAttr );
        if(mRTplayerMq==INVALID_MQD){
            LOGE("mq_open fail");
        }
    }
    demoPlayer- >mRTplayerMq = mRTplayerMq;
    rtplayer_clear_cmd(demoPlayer- >mRTplayerMq);
    
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    struct sched_param sched;
    sched.sched_priority = 4;
    pthread_attr_setschedparam(&attr, &sched);
    pthread_attr_setstacksize(&attr, 32768);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    
    if( pthread_create(&demoPlayer- >mThreadId, &attr, RTplayerThread, demoPlayer) ){
        LOGE("pthread_create failed, quit the rtplayer");
        mRTplayerMq = INVALID_MQD;
        //mq_close(demoPlayer- >mRTplayerMq);
    

    if USE_PREPARE_ASYNC

    sem_destroy(&demoPlayer- >mPreparedSem);
    

    endif

    goto rtp_prepare_failed;
    }
    pthread_setname_np(demoPlayer- >mThreadId, "RTplayerThread");
    
    if(demoPlayer- >inputMode)
        goto rtp_succeed;
    while(1){
        char cRxed = getchar();
        if(cRxed==BACKGROUND_CMD){
            printf("shell input exit, rtplayer will run in the backgroundn");
            break;
        }
        rtplayer_send_cmd(demoPlayer- >mRTplayerMq, cRxed, 0);
        if(cRxed==QUIT_CMD)
            break;
        usleep(50*1000);
    }
    

    rtp_succeed:

    return 0;
    

    rtp_prepare_failed:

    player_deinit(demoPlayer- >mRTplayer);
    

    rtp_init_failed:

    free(demoPlayer- >pUrl);
    

    rtp_url_failed:

    free(demoPlayer);
    

    rtp_failed:

    return -1;
    

    }
    FINSH_FUNCTION_EXPORT_CMD(cmd_rtplayer_test, rtplayer_test, test the rtplayer);

    static int cmd_rtplayer_controller(int argc, char ** argv){

    if(mRTplayerMq==INVALID_MQD){
        printf("mRTplayerMq = INVALID_MQD!n");
        return -1;
    }
    if( (argc!=2) && (argc!=3) ){
        printf("usage:rtpc < cmd > [data]n");
        return -1;
    }
    int data = 0;
    
    if(argc==3)
        data = atoi(argv[2]);
    rtplayer_send_cmd(mRTplayerMq, argv[1][0], data);
    
    return 0;
    

    }
    FINSH_FUNCTION_EXPORT_CMD(cmd_rtplayer_controller, rtpc, control the rtplayer);

注意事項

  • 目前 rtplayer/xplayer 僅支持音頻解碼,且不支持對視頻文件進行解封裝,因此 rtplayer 播放器應用只支持音頻文件的播放。
  • void registerCallback(void* handle, void* userData, player_callback_t fn) 函數必須要調用,而且 fn 不能為 NULL。
  • 回調函數中不能調用 rtplayer 的任何一個接口,如:reset、stop、start 等這些接口不能在回調函數中調用。
  • 播放本地文件的情況下,set url 時,XPlayer 會進行一次同步 prepare,用于提前獲取信息給 parser,因此異步 prepare 前,應對 XPlayerSetDataSourceUrl 的返回值進行判斷。
  • 改變播放器的狀態,應滿足狀態圖中的對應的函數調用流程,如播放結束后需要播放下一首歌,應調用 reset 清空信息,進入 idle 狀態,再調用 setDataSource_Url 進行填充下一首歌到播放器中
  • 采取異步 prepare 時(prepareAsync),應注意添加信號量進行同步。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 播放器
    +關注

    關注

    5

    文章

    409

    瀏覽量

    37813
  • URL
    URL
    +關注

    關注

    0

    文章

    139

    瀏覽量

    15726
  • FreeRTOS
    +關注

    關注

    12

    文章

    485

    瀏覽量

    63298
  • 狀態機
    +關注

    關注

    2

    文章

    493

    瀏覽量

    27936
  • 音頻解碼器
    +關注

    關注

    0

    文章

    33

    瀏覽量

    22430
  • R128
    +關注

    關注

    0

    文章

    41

    瀏覽量

    210
收藏 人收藏

    評論

    相關推薦

    R128芯片基礎組件開發指南RTOS多媒體編碼

    介紹 FreeRTOS 下如何使用 xrecorder 的接口來開發錄制應用程序,方便錄制應用開發人員快速正確地開發,以及錄制應用測試人員如何根據該文檔對基于 xrecord 的錄制應用進行驗證測試。
    的頭像 發表于 10-11 14:54 ?1498次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b>芯片基礎<b class='flag-5'>組件</b><b class='flag-5'>開發指南</b>—<b class='flag-5'>RTOS</b><b class='flag-5'>多媒體</b>編碼

    R128 BLE最高吞吐量測試正確配置測試方法

    R128使用前我們需要了解BLE的最高吞吐量,以方便評估相關功能的開發
    的頭像 發表于 10-27 17:17 ?1636次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b> BLE最高吞吐量測試正確配置測試方法

    R128內存泄漏調試案例分享

    硬件:R128 軟件:FreeRTOS + rtplayer\_test(Cedarx)+ AudioSystem
    的頭像 發表于 11-20 17:27 ?1208次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b>內存泄漏調試案例分享

    詳解R128 RTOS安全方案功能

    介紹 R128 下安全方案的功能。安全完整的方案基于標準方案擴展,覆蓋硬件安全、硬件加解密引擎、安全啟動、安全系統、安全存儲等方面。 配置文件相關本文涉及到一些配置文件,在此進行說明。 env
    發表于 12-28 15:59

    R128 DSP開發工具安裝教程

    下的 dsp_raw.bin 拷貝到 R128 根SDK 下的 board/r128s/xxx/bin/ 下,并重命名為rtos_dsp_sun20iw2p1.fex。 R128 SD
    發表于 12-28 17:21

    R128入門編寫HelloWorld

    本文將介紹使用 R128 開發板從串口輸出 HelloWorld 的方式介紹 SDK 軟件開發流程。 載入方案我們使用的開發板是 R128-
    發表于 12-29 09:39

    R128硬件設計指南

    硬件系統框圖R128是一顆專為“音視頻解碼”而打造的全新高集成度 SoC,主要應用于智能物聯和專用語音交互處理解決方案。 單片集成 MCU+RISCV+DSP+CODEC+WIFI/BT+PMU
    發表于 01-04 09:23

    R128 SDK架構與目錄結構

    HSPSRAM 以及 16M NORFLASH。本文檔作為 R128 FreeRTOS SDK 開發指南,旨在幫助軟件開發工程師、技術支持工程師快速上手,熟悉 R128 FreeRT
    發表于 01-05 10:05

    R128 Devkit開發板原理圖模塊介紹及使用說明

    :CH341SER.EXE 購買鏈接 百問科技淘寶店 - R128 DevKit 原理圖模塊介紹R128 模組R128 模組使用 SMT
    發表于 01-17 09:45

    R128芯片 基礎組件開發指南——RTOS 多媒體解碼

    RTOS 多媒體解碼 介紹 FreeRTOS 下如何使用 rtplayer 的接口來開發播放器應用程序,方便播放器開發人員快速正確地
    發表于 10-10 13:52

    R128芯片 基礎組件開發指南——RTOS 多媒體編碼

    RTOS 多媒體編碼 介紹 FreeRTOS 下如何使用 xrecorder 的接口來開發錄制應用程序,方便錄制應用開發人員快速正確地開發
    發表于 10-11 09:52

    R128芯片 基礎組件開發指南——RTOS 多媒體編碼

    RTOS 多媒體編碼 介紹 FreeRTOS 下如何使用 xrecorder 的接口來開發錄制應用程序,方便錄制應用開發人員快速正確地開發
    發表于 10-12 15:49

    R128啟用USB ADB以及無線ADB配置方法

    首先在FreeRTOS的環境下,選擇r128\_c906\_pro
    的頭像 發表于 11-01 11:43 ?1452次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b>啟用USB ADB以及無線ADB配置方法

    DshanMCU-R128s2 R128 EVT 開發套件

    針對 R128 模組,百問科技推出了 R128 EVT 開發套件作為快速開發評估工具。
    的頭像 發表于 12-22 15:16 ?1031次閱讀
    DshanMCU-<b class='flag-5'>R128</b>s2 <b class='flag-5'>R128</b> EVT <b class='flag-5'>開發</b>套件

    DshanMCU-R128s2 SDK 架構與目錄結構

    HSPSRAM 以及 16M NORFLASH。 本文檔作為 R128 FreeRTOS SDK 開發指南,旨在幫助軟件開發工程師、技術支持工程師快速上手,熟悉 R128 FreeR
    的頭像 發表于 12-22 15:57 ?979次閱讀
    DshanMCU-<b class='flag-5'>R128</b>s2 SDK 架構與目錄結構
    主站蜘蛛池模板: 特级中国aaa毛片 | 男人的天堂久久精品激情 | 狠狠色噜噜狠狠狠狠999米奇 | 四虎精品永久在线网址 | 久久精品人人做人人看 | 久久精品国产精品亚洲人人 | 欧美三级黄 | 精品精品国产高清a毛片牛牛 | 国内自拍露脸普通话对白在线 | 丁香婷婷影院 | 大尺度在线 | 欧美一区二区三区在线观看免费 | 最色网在线观看 | 丁香婷婷激情五月 | 午夜秒播 | 狠狠五月深爱婷婷网免费 | 免费视频色 | 午夜国产精品免费观看 | 女人精aaaa片一级毛片女女 | 色视频日本 | 深深激情网 | 丁香婷婷激情综合 | 婷婷色爱区综合五月激情韩国 | 欧美成人a | 国产三级在线播放 | 西西人体大胆高清啪啪欧洲 | 在线视频黄色 | 狠狠干夜夜操 | 久久婷婷人人澡人人爱91 | 免费视频国产 | 成年人网站免费观看 | aaa亚洲 | 国产一区二区三区欧美精品 | 最刺激黄a大片免费网站 | 国模私拍在线视频 | 九九热精品在线视频 | 一区视频在线 | 特级毛片免费视频观看 | 色婷婷影院在线视频免费播放 | 奇米一区二区三区四区久久 | 伊人婷婷色香五月综合缴激情 |