RM新时代网站-首页

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

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

3天內(nèi)不再提示

全志R128基礎(chǔ)組件開發(fā)指南—RTOS多媒體解碼

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

RTOS 多媒體解碼

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

RTPLAYER 狀態(tài)圖

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

image-20230512165957929.png

Idle 狀態(tài)

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

Initialized 狀態(tài)

這個狀態(tài)比較簡單,調(diào)用 setDateSource_url() 方法就進入 Initialized 狀態(tài),表示此時要播放的文件已經(jīng)設(shè)置好了

Preparing 狀態(tài)

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

Prepared 狀態(tài)

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

Started 狀態(tài)

rtplayer 一旦 prepare 完成,就可以調(diào)用 start() 方法,這樣 rtplayer 就處于 Started 狀態(tài),這表明 rtplayer 正在播放文件過程中??梢允褂?XPlayerIsPlaying() 測試 rtplayer 是否處于了 Started 狀態(tài)。如果播放完畢,而又設(shè)置了循環(huán)播放,則 rtplayer 仍然會處于 Started 狀態(tài)。

Paused 狀態(tài)

Started 狀態(tài)下可以調(diào)用 pause_l() 方法暫停 rtplayer,從而進入 Paused 狀態(tài),rtplayer 暫停后再次調(diào)用 start() 則可以繼續(xù) TPlayer 的播放,轉(zhuǎn)到 Started 狀態(tài)。

Stopped 狀態(tài)

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

PlaybackCompleted 狀態(tài)

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

Error 狀態(tài)

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

End 狀態(tài)

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

rtplayer 層接口

創(chuàng)建一個 RTPLAYER

函數(shù)原型

uint32_t player_init(void)

參數(shù)

返回值:

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

銷毀一個 RTPLAYER

函數(shù)原型

void player_deinit(void* handle)

參數(shù):

  • handle: 通過 player_init() 函數(shù)創(chuàng)建的 rtplayer 指針

返回值:

設(shè)置 RTPLAYER 的消息回調(diào)函數(shù)

函數(shù)原型

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

參數(shù):

  • handle: 通過 player_init() 函數(shù)創(chuàng)建的 rtplayer 指針
  • userData: 回調(diào)消息處理對象
  • fn: 回調(diào)消息處理函數(shù)指針,需要由應(yīng)用實現(xiàn)

返回值:

創(chuàng)建完 rtplayer 播放器之后,就要調(diào)用該函數(shù)設(shè)置回調(diào)消息處理函數(shù)。

設(shè)置播放文件的 URL

可以是本地文件也可以是網(wǎng)絡(luò)

函數(shù)原型

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

參數(shù):

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

返回值:

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

解析文件頭部信息,獲取元數(shù)據(jù)

函數(shù)原型

status_t prepare(void* handle)

參數(shù):

  • handle: 通過 player_init() 函數(shù)創(chuàng)建的 rtplayer 指針;

返回值:

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

異步解析文件頭部信息,獲取元數(shù)據(jù)

函數(shù)原型

status_t prepareAsync(void* handle)

參數(shù):

  • handle: 通過 player_init() 函數(shù)創(chuàng)建的 rtplayer 指針;

返回值:

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

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

開始播放

函數(shù)原型

status_t start(void* handle)

參數(shù):

  • handle: 通過 player_init() 函數(shù)創(chuàng)建的 rtplayer 指針;

返回值:

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

暫停播放

函數(shù)原型

status_t pause_l(void* handle)

參數(shù):

  • handle: 通過 player_init() 函數(shù)創(chuàng)建的 rtplayer 指針;

返回值:

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

停止播放

函數(shù)原型

status_t stop(void* handle)

參數(shù):

  • handle: 通過 player_init() 函數(shù)創(chuàng)建的 rtplayer 指針

返回值:

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

重置播放器

函數(shù)原型

status_t reset(void* handle)

參數(shù):

  • handle: 通過 player_init() 函數(shù)創(chuàng)建的 rtplayer 指針;

返回值:

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

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

跳播

函數(shù)原型

status_t seekTo(void* handle, int sec)

參數(shù):

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

返回值:

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

獲取當前播放的位置

函數(shù)原型

status_t getCurrentPosition(void* handle, int * sec)

參數(shù):

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

返回值:

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

獲取播放的文件總時長

函數(shù)原型

status_t getDuration(void* handle, int * sec)

參數(shù):

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

返回值:

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

需要在 prepared 狀態(tài)之后才可以調(diào)用該函數(shù)

獲取播放的文件信息

函數(shù)原型

MediaInfo* getMediaInfo(void* handle)

參數(shù):

  • handle: 通過 player_init() 函數(shù)創(chuàng)建的 rtplayer 指針;

返回值:

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

需要在 prepared 狀態(tài)之后才可以調(diào)用該函數(shù)

設(shè)置循環(huán)播放模式

函數(shù)原型

status_t setLooping(void* handle, int loop)

參數(shù):

  • handle: 通過 player_init() 函數(shù)創(chuàng)建的 rtplayer 指針;
  • loop:1 表示單曲循環(huán),0 表示不會單曲循環(huán)

返回值:

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

XPlayer 層播放接口

創(chuàng)建一個 XPLAYER

函數(shù)原型

XPlayer* XPlayerCreate()

參數(shù):

返回值:

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

設(shè)置 XPLAYER 的回調(diào)通知

函數(shù)原型

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

參數(shù):

  • P:通過 XPlayerCreate 創(chuàng)建的 Xplayer 指針
  • notifier:回調(diào)通知
  • pUserData:應(yīng)用程序傳下來的自定義數(shù)據(jù)

返回值:

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

Xplayer 將接收來自下層的回調(diào)通知,進行相應(yīng)的操作

創(chuàng)建指向音頻播放設(shè)備管理模塊的指針,用于播放音頻

函數(shù)原型

SoundCtrl* RTSoundDeviceCreate(int card)

參數(shù):

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

返回值:

  • 成功:音頻播放設(shè)備管理模塊的指針;失?。篘ULL

創(chuàng)建指向音頻播放設(shè)備管理模塊的指針,用于播放音頻

函數(shù)原型

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

參數(shù):

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

返回值:

  • 返回值: 成功:0;失?。?1 或線程響應(yīng)設(shè)置數(shù)據(jù)源命令的返回值或線程響應(yīng) xplayer prepare 命令的返回值

調(diào)用說明: 發(fā)送 SetDataSource 命令,獲取需要播放的音頻數(shù)據(jù)內(nèi)容

將 XPLAYER 置為準備狀態(tài), 解析頭部信息,獲取元數(shù)據(jù)

函數(shù)原型

int XPlayerPrepare(XPlayer* p)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 Xplayer 指針

返回值:

  • 成功:線程響應(yīng)異步 Prepare 命令的返回值;失?。篘ULL

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

將 XPLAYER 置為異步準備狀態(tài)

函數(shù)原型

int XPlayerPrepareAsync(XPlayer* p)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 XPlayer 指針

返回值:

  • 成功:線程響應(yīng)異步 Prepare 命令的返回值;失?。篘ULL

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

將 XPLAYER 置為啟動狀態(tài)

函數(shù)原型

int XPlayerStart(XPlayer* p)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 XPlayer 指針

返回值:

  • 成功:線程響應(yīng) start 命令的返回值;失?。篘ULL

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

將 XPLAYER 置為暫停狀態(tài)

函數(shù)原型

int XPlayerPause(XPlayer* p)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 XPlayer 指針

返回值:

  • 成功:線程響應(yīng) pause 命令的返回值;失?。篘ULL

在 XPlayer 處于 start 狀態(tài)時可調(diào)用此接口,Pause 命令的返回值為 0 時說明響應(yīng)成功,為?1 時說明響應(yīng)失敗

將 XPLAYER 置為停止狀態(tài)

函數(shù)原型

int XPlayerStop(XPlayer* p)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 XPlayer 指針

返回值:

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

重置 XPLAYER

將相關(guān)變量復位,并銷毀各模塊,如音頻解碼模塊、音頻解碼數(shù)據(jù)接收模塊等

函數(shù)原型

int XPlayerReset(XPlayer* p)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 XPlayer 指針

返回值:

  • 成功:線程響應(yīng) Reset 命令的返回值;失?。篘ULL

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

獲取節(jié)目時長

函數(shù)原型

int XPlayerGetDuration(XPlayer* p, int *msec)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 Xplayer 指針
  • msec:保存節(jié)目時長

返回值:

  • 成功:0;失?。?1

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

SEEK 到給定的時間點

函數(shù)原型

int XPlayerSeekTo(XPlayer* p, int nSeekTimeMs)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 Xplayer 指針
  • nSeekTimeMs:跳轉(zhuǎn)的時間點

返回值:

  • 成功:線程響應(yīng) Seek 命令的返回值;失?。篘ULL

如果跳轉(zhuǎn)前播放處于暫停狀態(tài),則跳轉(zhuǎn)后將保持在暫停狀態(tài)

獲取媒體文件的總時長

函數(shù)原型

int XPlayerGetDuration(XPlayer* p, int *msec)

參數(shù):

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

返回值:

  • 成功:0;失敗:?1

需要在 prepared 狀態(tài)之后才可以調(diào)用該函數(shù)

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

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

函數(shù)原型

int XPlayerGetCurrentPosition(XPlayer* p, int* msec)

參數(shù):

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

返回值:

  • 成功:0;失?。?1

獲取媒體信息

函數(shù)原型

MediaInfo* XPlayerGetMediaInfo(XPlayer* p)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 XPlayer 指針

返回值:

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

需要在 prepared 狀態(tài)之后才可以調(diào)用該函數(shù)

設(shè)置循環(huán)播放模式

函數(shù)原型

int XPlayerSetLooping(XPlayer* p, int loop)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 XPlayer 指針
  • loop: 1: 表示單曲循環(huán)模式;0:表示不會循環(huán)

返回值:

查詢是否正在播放

函數(shù)原型

int XPlayerIsPlaying(XPlayer* p)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 XPlayer 指針

返回值:

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

銷毀一個 XPLAYER

函數(shù)原型

void XPlayerDestroy(XPlayer* p)

參數(shù):

  • p:通過 XPlayerCreate 創(chuàng)建的 XPlayer 指針

返回值:

播放器開發(fā)示例

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

  2. registerCallback() 設(shè)置消息回調(diào)函數(shù)

  3. setDataSource_url() 設(shè)置 url

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

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

  6. 如果需要跳播,則可以調(diào)用 seekTo() 函數(shù)

  7. 如果需要暫停,則調(diào)用 pause_l() 函數(shù)進行暫停

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

  9. 如果需要播放下一個或其他的,則可以先調(diào)用 reset() 函數(shù)使播放器進入 idle 狀態(tài),然后再重復 (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 播放器應(yīng)用只支持音頻文件的播放。
  • void registerCallback(void* handle, void* userData, player_callback_t fn) 函數(shù)必須要調(diào)用,而且 fn 不能為 NULL。
  • 回調(diào)函數(shù)中不能調(diào)用 rtplayer 的任何一個接口,如:reset、stop、start 等這些接口不能在回調(diào)函數(shù)中調(diào)用。
  • 播放本地文件的情況下,set url 時,XPlayer 會進行一次同步 prepare,用于提前獲取信息給 parser,因此異步 prepare 前,應(yīng)對 XPlayerSetDataSourceUrl 的返回值進行判斷。
  • 改變播放器的狀態(tài),應(yīng)滿足狀態(tài)圖中的對應(yīng)的函數(shù)調(diào)用流程,如播放結(jié)束后需要播放下一首歌,應(yīng)調(diào)用 reset 清空信息,進入 idle 狀態(tài),再調(diào)用 setDataSource_Url 進行填充下一首歌到播放器中
  • 采取異步 prepare 時(prepareAsync),應(yīng)注意添加信號量進行同步。
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 播放器
    +關(guān)注

    關(guān)注

    5

    文章

    397

    瀏覽量

    37409
  • URL
    URL
    +關(guān)注

    關(guān)注

    0

    文章

    139

    瀏覽量

    15328
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    484

    瀏覽量

    62136
  • 狀態(tài)機
    +關(guān)注

    關(guān)注

    2

    文章

    492

    瀏覽量

    27528
  • 音頻解碼器
    +關(guān)注

    關(guān)注

    0

    文章

    31

    瀏覽量

    22241
  • R128
    +關(guān)注

    關(guān)注

    0

    文章

    41

    瀏覽量

    105
收藏 人收藏

    評論

    相關(guān)推薦

    R128芯片基礎(chǔ)組件開發(fā)指南RTOS多媒體編碼

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

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

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

    R128內(nèi)存泄漏調(diào)試案例分享

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

    詳解R128 RTOS安全方案功能

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

    R128 DSP開發(fā)工具安裝教程

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

    R128入門編寫HelloWorld

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

    R128硬件設(shè)計指南

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

    R128 SDK架構(gòu)與目錄結(jié)構(gòu)

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

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

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

    R128芯片 基礎(chǔ)組件開發(fā)指南——RTOS 多媒體解碼

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

    R128芯片 基礎(chǔ)組件開發(fā)指南——RTOS 多媒體編碼

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

    R128芯片 基礎(chǔ)組件開發(fā)指南——RTOS 多媒體編碼

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

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

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

    DshanMCU-R128s2 R128 EVT 開發(fā)套件

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

    DshanMCU-R128s2 SDK 架構(gòu)與目錄結(jié)構(gòu)

    HSPSRAM 以及 16M NORFLASH。 本文檔作為 R128 FreeRTOS SDK 開發(fā)指南,旨在幫助軟件開發(fā)工程師、技術(shù)支持工程師快速上手,熟悉 R128 FreeR
    的頭像 發(fā)表于 12-22 15:57 ?739次閱讀
    DshanMCU-<b class='flag-5'>R128</b>s2 SDK 架構(gòu)與目錄結(jié)構(gòu)
    RM新时代网站-首页