一. 簡(jiǎn)介
[RK3588從入門到精通] 專欄總目錄
本篇文章進(jìn)行RK3588-MPP解碼的詳細(xì)解析
二. 環(huán)境介紹
硬件環(huán)境: ArmSoM-W3 RK3588開發(fā)板
軟件版本: OS:ArmSoM-W3 Debian11
三. 解碼器數(shù)據(jù)流接口
3.1 decode_put_packet
輸入碼流的形式:分幀與不分幀 MPP 的輸入都是沒有封裝信息的裸碼流,裸碼流輸入有兩種形式:
不分幀 這種方式是已經(jīng)按幀分段的數(shù)據(jù),即每一包輸入給 decode_put_packet 函數(shù)的 MppPacket 數(shù)據(jù)都已經(jīng)包含完整的一幀,不多也不少。在這種情況下,MPP 可以直接按包處理碼流,是 MPP 的默認(rèn)運(yùn)行情況。
分幀 按長(zhǎng)度讀取的數(shù)據(jù),這樣的數(shù)據(jù)無(wú)法判斷一包 MppPacket 數(shù)據(jù)是否是完整的一幀,需要 MPP 內(nèi)部進(jìn)行分幀處理。MPP 也可以支持這種形式的輸入,但需要在 mpp_init 之前,通過 control 接口的 MPP_DEC_SET_PARSER_SPLIT_MODE 命令,MPP 內(nèi)的 need_split 標(biāo)志打開。
// NOTE: decoder split mode need to be set before init // 按幀輸入碼流 RK_U32 need_split = 1; mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE; param = &need_split; ret = mpi->control(ctx, mpi_cmd, param); if (MPP_OK != ret) { mpp_err("mpi->control failed\n"); deInit(&packet, &frame, ctx, buf, data); }
這樣,調(diào)用 decode_put_packet 輸入的 MppPacket 就會(huì)被 MPP 重新分幀,進(jìn)入到情況一的處理。
如果這兩種情況出現(xiàn)了混用,會(huì)出現(xiàn)碼流解碼出錯(cuò)的問題。
分幀方式處理效率高,但需要輸入碼流之前先進(jìn)行解析與分幀;
不分幀方式使用簡(jiǎn)單,但效率會(huì)受影響。
在 mpi_dec_test 的測(cè)試用例中,使用的是方式不分幀的方式。在瑞芯微的 Android SDK 中,使用的是分幀的方式。用戶可以根據(jù)自己的應(yīng)用場(chǎng)景和平臺(tái)條件進(jìn)行選擇
3.2 decode_get_frame
3.3 給解碼器提供足夠大小的保存像素?cái)?shù)據(jù)的內(nèi)存空間
解碼器在解碼時(shí),需要為輸出圖像獲取保存像素?cái)?shù)據(jù)的內(nèi)存空間,用戶需要給解碼器提供足夠大小,這個(gè)空間大小的需求,會(huì)在 MPP 解碼器內(nèi)部根據(jù)不同的芯片平臺(tái)以及不同的視頻格式需求進(jìn)行計(jì)算,計(jì)算后的內(nèi)存空間需求會(huì)通過MppFrame 的成員變量 buf_size 提供給用戶。用戶需要按 buf_size的大小進(jìn)行內(nèi)存分配,即可滿足解碼器的要求。
RK_U32 buf_size = mpp_frame_get_buf_size(frame); ret = mpp_buffer_group_limit_config(data->frm_grp, buf_size, 24); if (ret) { mpp_err("%p limit buffer group failed ret %d\n", ctx, ret); break; }
3.4 輸出圖像的變寬高信息(Info change)
當(dāng)碼流的寬高,格式,像素位深等信息發(fā)生變化時(shí),需要反饋給用戶,用戶需要更新解碼器使用的 內(nèi)存池,把新的內(nèi)存更新給解碼器。這里涉及到解碼內(nèi)存分配與使用模式。 圖像內(nèi)存分配以及交互模式:
模式一:純內(nèi)部分配模式 模式二:半內(nèi)部分配模式 模式三:純外部分配模式: 直接使用外部顯示用的內(nèi)存,容易實(shí)現(xiàn)零拷貝。
模式一:純內(nèi)部分配模式
圖像內(nèi)存直接從 MPP 解碼器內(nèi)部分配,內(nèi)存由解碼器直接分配,用戶得到解碼器輸出圖像,在使用 完成之后直接釋放。 在這種方式下,用戶不需要調(diào)用解碼器 control 接口的 MPP_DEC_SET_EXT_BUF_GROUP 命令,只 需要在解碼器上報(bào) info change 時(shí)直接調(diào)用 control 接口的 MPP_DEC_SET_INFO_CHANGE_READY 命令即可。解碼器會(huì)自動(dòng)在內(nèi)部進(jìn)行內(nèi)存分配,用戶需要把獲取到的每幀數(shù)據(jù)直接釋放。
模式二:半內(nèi)部分配模式
用戶需要根據(jù)get_frame返回的MppFrame的buf_size 來(lái)創(chuàng)建 MppBufferGroup,并通過 control 接口的 MPP_DEC_SET_EXT_BUF_GROUP 配置給解碼器。用戶可以通過 mpp_buffer_group_limit_config 接口來(lái)限制解碼器的內(nèi)存使用量。
模式三:純外部分配模式
這種模式通過創(chuàng)建空的 external 模式的 MppBufferGroup,從用戶那里導(dǎo)入外部分配器分析的內(nèi)存塊 文件句柄(一般是 dmabuf/ion/drm)。在 Android 平臺(tái)上,Mediaserver 通過 gralloc 從 SurfaceFlinger 獲取顯示用內(nèi)存,把 gralloc 得到的文件句柄提交(commit)到 MppBufferGroup 里,再把 MppBufferGroup 通過 control 接口 MPP_DEC_SET_EXT_BUF_GROUP 命令配置給解碼器,然后 MPP 解碼器將循環(huán)使用 gralloc 得到的內(nèi)存空間。
-
解碼
+關(guān)注
關(guān)注
0文章
181瀏覽量
27407 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5093瀏覽量
97800 -
MPP
+關(guān)注
關(guān)注
0文章
24瀏覽量
10608 -
RK3588
+關(guān)注
關(guān)注
7文章
338瀏覽量
4428
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論