国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

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

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

3天內不再提示

基于OpenHarmony 3.2 Beta1版本的媒體能力

OpenAtom OpenHarmony ? 來源:OpenAtom OpenHarmony ? 作者:OpenAtom OpenHarmony ? 2022-07-01 10:58 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、背景

全民直播時代,人們每天刷著五花八門的短視頻,每分每秒都有無數的視頻文件被生成、播放。但你可曾想過這些電視劇、電影、視頻廣告、短視頻等影音是以怎樣的數據形式在我們的顯示設備中播放出來的?本文將基于 OpenHarmony 3.2 Beta1 版本的媒體能力,為你詳細解讀一個視頻文件(本文以 MP4 封裝格式、H264 壓縮格式的視頻文件為例)是怎么在基于 OpenHarmony 標準系統的設備上播放出來的。同時也帶你一窺“播放一個視頻文件”這件對 OpenHarmony 3.2 Beta1 版本系統能力很輕松的事,是由多少服務層、功能接口、工具、插件、命令行及代碼等共同協作完成的。

二、OpenHarmony 3.2媒體能力全景

OpenHarmony 技術架構如下圖所示,完成視頻文件播放功能的是多媒體子系統。

7b5704ea-f875-11ec-ba43-dac502259ad0.png

下圖所示為多媒體子系統框架圖

7b6c7064-f875-11ec-ba43-dac502259ad0.png

如圖所示,OpenHarmony 多媒體子系統拉起了一個叫 mediaserver 的服務來處理媒體事務,并且封裝了接口層包括JS接口、native 接口提供給 APP 調用,mediaserver 的核心則是引入了 gstreamer(以下簡稱 gst)框架來完成媒體功能(注:gstreamer 是一套功能強大、兼容性好、結構清晰的開源媒體框架,這里不做贅述,后面有專文解析)。OpenHarmony 也在 gst 的基礎上開發了 player engine 來實現播放,同時也利用 gst 豐富的插件資源實現幾乎所有的媒體功能。截至目前,已移植進來的開源插件包括 file source、demuxer、video decoder、libav 插件等,當然也包括 OpenHarmony 自研的 video sink、memsink、codec hdi 插件等。

三、把大象裝冰箱(H264視頻播放)總共分幾步?

視頻播放流程圖如下:

7b9cdb1e-f875-11ec-ba43-dac502259ad0.png

如圖所示,播放一個視頻大致分為 4 步:

解協議->解封裝->解壓縮->送顯

播放pipeline

根據視頻播放的步驟,我們在 OpenHarmony 上每一個環節都能找到對應的插件來完成,同時參考 media_standard 代碼倉的代碼目錄,相關的代碼都可以找到對應的實現邏輯。

7bc0cef2-f875-11ec-ba43-dac502259ad0.png

1、對于一個本地視頻文件(比如/data/h264-640x480.mp4),對應的 filesrc 插件來完成文件的解析,拿到MP4文件流;

OpenHarmony 處理本地視頻文件 URI 的 SetSource 邏輯代碼如下:

int32_t PlayerEngineGstImpl::SetSource(const std::string &url){ std::unique_lock lock(mutex_); CHECK_AND_RETURN_RET_LOG(!url.empty(), MSERR_INVALID_VAL, "input url is empty!"); CHECK_AND_RETURN_RET_LOG(url.length() <= MAX_URI_SIZE, MSERR_INVALID_VAL, "input url length is invalid!"); std::string realUriPath; int32_t ret = MSERR_OK; if (IsFileUrl(url)) { ret = GetRealPath(url, realUriPath); if (ret != MSERR_OK) { return ret; } url_ = "file://" + realUriPath; } else { url_ = url; } MEDIA_LOGD("set player source: %{public}s", url_.c_str()); return ret;}?

這樣就會得到一個 URI:file:///data/h264-640x480.mp4,gst 正是通過 URI 前綴來判斷是否是本地視頻文件,然后獲取文件內容。

2、拿到 MP4 文件流后,對應的 qtdemux 插件來解封裝,完成音視頻分流,輸出 H264 裸碼流和音頻流;

3、拿到 H264 碼流后,h264parse 插件開始切片,輸出 H264 幀數據;

4、處理 H264 幀數據,就由 avdec_h264 插件來完成,一般情況會輸出 NV12 的像素數據,當然這個解碼器是基于 ffmpeg 的軟解插件,相信不久各個芯片廠商的硬件加速解碼器都會加進來;

可以使用 gst-inspect 工具查看 avdec_h264 解碼插件,使用 ffmpeg 的解碼能力,支持的格式非常豐富。

7bf6923a-f875-11ec-ba43-dac502259ad0.png

5、至此解碼的工作已經完成,后面就要根據顯示的像素格式、size 來對解碼輸出數據進行后處理(轉換、縮放、裁剪等),會由 Converter、Scaler、Clip 插件來完成;

6、滿足顯示要求后就會使用 surfacesink 插件完成合成送顯。

送顯需要先申請顯示 surface buffer,申請邏輯代碼如下:

GstSurfaceMemory *gst_surface_allocator_alloc(GstSurfaceAllocator *allocator, GstSurfaceAllocParam param){ g_return_val_if_fail(allocator != nullptr && allocator->surface != nullptr, nullptr); static constexpr int32_t stride_alignment = 8; int32_t wait_time = param.dont_wait ? 0 : INT_MAX; // wait forever or no wait. OHOS::BufferRequestConfig request_config = { param.width, param.height, stride_alignment, param.format, static_cast(param.usage) | HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, wait_time }; int32_t release_fence = -1; OHOS::sptr surface_buffer = nullptr; OHOS::SurfaceError ret = allocator->surface->RequestBuffer(surface_buffer, release_fence, request_config); if (ret == OHOS::SURFACE_ERROR_NO_BUFFER) { GST_INFO("there is no more buffers"); } if (ret != OHOS::SURFACE_ERROR_OK || surface_buffer == nullptr) { return nullptr; } ret = surface_buffer->Map(); if (ret != OHOS::SURFACE_ERROR_OK) { GST_ERROR("surface_buffer Map failed"); return nullptr; } OHOS::sptr autoFence = new(std::nothrow) OHOS::SyncFence(release_fence); if (autoFence != nullptr) { autoFence->Wait(100); // 100ms } GstSurfaceMemory *memory = reinterpret_cast(g_slice_alloc0(sizeof(GstSurfaceMemory))); if (memory == nullptr) { GST_ERROR("alloc GstSurfaceMemory slice failed"); allocator->surface->CancelBuffer(surface_buffer); return nullptr; } gst_memory_init(GST_MEMORY_CAST(memory), (GstMemoryFlags)0, GST_ALLOCATOR_CAST(allocator), nullptr, surface_buffer->GetSize(), 0, 0, surface_buffer->GetSize()); memory->buf = surface_buffer; memory->fence = -1; memory->need_render = FALSE; GST_DEBUG("alloc surface buffer for width: %d, height: %d, format: %d, size: %u", param.width, param.height, param.format, surface_buffer->GetSize()); return memory;}

申請好的 buffer 會放入 buffer pool,形成一個 buffer 隊列。

解碼器解完一幀會將數據放入 buffer pool,sink 插件會從 buffer pool 中拿到數據送顯,代碼邏輯如下:

static GstFlowReturn gst_surface_mem_sink_do_app_render(GstMemSink *memsink, GstBuffer *buffer, bool is_preroll){ g_return_val_if_fail(memsink != nullptr && buffer != nullptr, GST_FLOW_ERROR); GstSurfaceMemSink *surface_sink = GST_SURFACE_MEM_SINK_CAST(memsink); g_return_val_if_fail(surface_sink != nullptr, GST_FLOW_ERROR); GstSurfaceMemSinkPrivate *priv = surface_sink->priv; GST_OBJECT_LOCK(surface_sink); if (gst_surface_mem_sink_drop_frame_check(surface_sink) == FALSE) { GST_OBJECT_UNLOCK(surface_sink); GST_DEBUG_OBJECT(surface_sink, "user set rate, drop same frame"); return GST_FLOW_OK; } if (surface_sink->firstRenderFrame) { GST_WARNING_OBJECT(surface_sink, "KPI-TRACE: first render frame"); surface_sink->firstRenderFrame = FALSE; } for (guint i = 0; i < gst_buffer_n_memory(buffer); i++) { GstMemory *memory = gst_buffer_peek_memory(buffer, i); if (!gst_is_surface_memory(memory)) { GST_WARNING_OBJECT(surface_sink, "not surface buffer !, 0x%06" PRIXPTR, FAKE_POINTER(memory)); continue; } GstSurfaceMemory *surface_mem = reinterpret_cast(memory); surface_mem->need_render = TRUE; gboolean needFlush = TRUE; if (is_preroll) { surface_sink->prerollBuffer = buffer; } else { if (surface_sink->prerollBuffer == buffer) { // if it's paused, then play, this buffer is render by preroll surface_sink->prerollBuffer = nullptr; needFlush = FALSE; } } if (needFlush) { OHOS::BufferFlushConfig flushConfig = { { 0, 0, surface_mem->buf->GetWidth(), surface_mem->buf->GetHeight() }, }; gst_surface_mem_sink_dump_buffer(surface_sink, buffer); OHOS::SurfaceError ret = priv->surface->FlushBuffer(surface_mem->buf, surface_mem->fence, flushConfig); if (ret != OHOS::SURFACE_ERROR_OK) { surface_mem->need_render = FALSE; GST_ERROR_OBJECT(surface_sink, "flush buffer to surface failed, %d", ret); } } } GST_OBJECT_UNLOCK(surface_sink); GST_DEBUG_OBJECT(surface_sink, "End gst_surface_mem_sink_do_app_render"); return GST_FLOW_OK;}

再加上 audio 的插件解碼出音頻數據,OpenHarmony 的 player 會完成音視頻同步,至此一個視頻文件就會播放顯示在屏幕上。

OpenHarmony 為了實現更好的用戶體驗,同時也引入了一些解決性能問題的插件,比如 multiqueue 插件來實現 buffer 隊列,也使用 decodebin 高級插件來完成解碼 element 的選擇。

通過梳理,我們最終可以得到一條播放的 pipeline:

7c148362-f875-11ec-ba43-dac502259ad0.png

而通過播放 OpenHarmony 自帶的圖庫播放本地 H264 視頻,抓取 log,搜索 OnElementSetupCb 關鍵字也可以得到播放的 pipeline,這也進一步驗證了本文的分析。

7c2e4784-f875-11ec-ba43-dac502259ad0.png

另外,我們也可以使用 gst-launch 手動創建 pipeline 來驗證:

gst-launch--gst-plugin-path=/system/lib/media/pluginsfilesrclocation=/data/media/h264.mp4!qtdemux!h264parse!avdec_h264!videoconvert!videoscale!video/x-raw,width=640,height=480!surfacememsink

附錄:

OpenHarmony標準系統media組件介紹

https://gitee.com/openharmony/multimedia_media_standardhttps://gitee.com/openharmony/multimedia_media_standard

MP4封裝格式介紹

https://wenku.baidu.com/view/b4f52a376ddb6f1aff00bed5b9f3f90f76c64dbd.htmlhttps://wenku.baidu.com/view/b4f52a376ddb6f1aff00bed5b9f3f90f76c64dbd.html

gst介紹

https://gstreamer.freedesktop.org/documentation/tutorials/index.html?gi-language=chttps://gstreamer.freedesktop.org/documentation/tutorials/index.html?gi-language=c

https://blog.csdn.net/qq_45662588/article/details/120763198https://blog.csdn.net/qq_45662588/article/details/120763198

OpenHarmony 3.2 Beta1 版本路書

https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-v3.2-beta1.md

OpenHarmony媒體子系統框架介紹

https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E5%AA%92%E4%BD%93%E5%AD%90%E7%B3%BB%E7%BB%9F.mdhttps://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E5%AA%92%E4%BD%93%E5%AD%90%E7%B3%BB%E7%BB%9F.md

OpenHarmony視頻播放應用開發指導

https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/media/video-playback.md

審核編輯 :李倩

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 視頻
    +關注

    關注

    6

    文章

    2005

    瀏覽量

    74964
  • OpenHarmony
    +關注

    關注

    33

    文章

    3952

    瀏覽量

    21103

原文標題:基于OpenHarmony 3.2 Beta1版本的H264視頻播放之路詳解

文章出處:【微信號:gh_e4f28cfa3159,微信公眾號:OpenAtom OpenHarmony】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    RK3568適配OpenHarmony全指南:從編譯到落地的可行性與實操方案

    + 1T 算力 NPU 的硬件配置,成為邊緣計算、智能終端的優選;而 OpenHarmony 3.2 及以上版本的分布式能力與輕量化特性,
    的頭像 發表于 02-09 16:59 ?1074次閱讀
    RK3568適配<b class='flag-5'>OpenHarmony</b>全指南:從編譯到落地的可行性與實操方案

    IvorySQL開源社區正式發布IvorySQL 5.0版本

    近日,IvorySQL開源社區正式發布IvorySQL 5.0版本。該版本基于PostgreSQL 18.0進行全面迭代升級,在Oracle兼容性上實現新突破,生態組件集成能力持續進階,同時深度適配云原生場景,同步提供全平臺安裝
    的頭像 發表于 12-04 10:06 ?759次閱讀
    IvorySQL開源社區正式發布IvorySQL 5.0<b class='flag-5'>版本</b>

    開源鴻蒙6.1和8.1版本定為LTS建議版本,最新OpenHarmony路標發布

    在開源項目生態建設中,版本生命周期管理是保障社區項目穩定演進、助力生態伙伴提前規劃產品路線、降低開發者適配成本的核心環節。為進一步規范開源鴻蒙版本的發布流程與維護標準,明確技術支持周期預期,2025
    的頭像 發表于 10-30 09:29 ?988次閱讀
    開源鴻蒙6.1和8.1<b class='flag-5'>版本</b>定為LTS建議<b class='flag-5'>版本</b>,最新<b class='flag-5'>OpenHarmony</b>路標發布

    貝啟科技BQ3588HM主板通過 OpenHarmony 5.0.3 Release 版本兼容性測評

    廈門貝啟科技有限公司基于RockchipRK3588SoC的貝啟BQ3588HM主板模組/開發板,已通過OpenHarmony5.0.3Release版本兼容性測評,獲頒
    的頭像 發表于 10-21 15:33 ?1096次閱讀
    貝啟科技BQ3588HM主板通過 <b class='flag-5'>OpenHarmony</b> 5.0.3 Release <b class='flag-5'>版本</b>兼容性測評

    Quartus Prime Pro 25.1版本的安裝和使用

    如果用戶開發板是基于Agilex 3、Agilex 5等高階器件,則需要安裝高版本的Quartus軟件比如Quartus Prime Pro 25.1版本,這個版本在安裝包和license獲取(免費)等方面跟以往的Quartus
    的頭像 發表于 10-07 13:06 ?2674次閱讀
    Quartus Prime Pro 25.1<b class='flag-5'>版本</b>的安裝和使用

    HarmonyOSAI編程智慧調優

    Beta1版本開始支持。 注意 當前支持對Launch冷啟動問題和Frame卡頓丟幀問題進行智慧調優分析。 Profiler工具中已集成智慧調優能力,首次使用請先根據界面提示完成CodeGenie授權登陸
    發表于 09-01 15:15

    HarmonyOS AI輔助編程工具(CodeGenie)智慧調優

    Beta1版本開始支持。 注意 當前支持對Launch冷啟動問題和Frame卡頓丟幀問題進行智慧調優分析。 Profiler工具中已集成智慧調優能力,首次使用請先根據界面提示完成CodeGenie授權登陸
    發表于 08-14 11:12

    HarmonyOS AI輔助編程工具(CodeGenie)頁面生成

    支持通過自然語言對話,生成應用/元服務可用的頁面代碼,生成結果支持實時預覽,幫助開發者快速完成頁面搭建。該功能從DevEco Studio 6.0.0 Beta1版本開始支持。 點擊頁面右側菜單欄
    發表于 08-13 10:38

    【潤開鴻HH-SCDAYU800A開發板試用體驗】開箱評測報告

    hdc連接和調試。 **** 開發板 簡介:作為國產RISC-V+OpenHarmony+星閃技術的融合之作,支持DeepSeek,填補了高性能邊緣計算開發板的市場空白。其4TOPs算力、4K多媒體能力
    發表于 07-23 09:21

    嘗鮮開源鴻蒙6.0?試試明星開發板Purple Pi OH

    6月19日,開源鴻蒙官方發布了OpenHarmony6.0Beta1版本,觸覺智能緊隨其后,率先在PurplePiOH開發板進行適配
    的頭像 發表于 07-11 18:42 ?1572次閱讀
    嘗鮮開源鴻蒙6.0?試試明星開發板Purple Pi OH

    針對“您的應用使用了HarmonyOS beta版本的API”的解決方法##HarmonyOS應用上架##

    ? 今天我更新了項目的一些UI,然后按照之前的流程正常的進行打包、提審,結果在預審階段就收到了駁回的郵件,其中的內容包括: 未通過原因:經檢測發現,您的應用使用了HarmonyOS beta版本
    發表于 06-30 17:30

    桃芯科技獲得OpenHarmony生態產品兼容性證書

    近日,由INGCHIPS自主研發的模組/開發板DB870CC1A順利通過OpenHarmony 5.0.2 Release版本兼容性測評,并獲得OpenHarmony生態產品兼容性證書
    的頭像 發表于 06-25 14:30 ?1131次閱讀

    開源鴻蒙6.0Beta1版本發布!觸覺智能將率先適配RK3566/RK3568/RK3576等芯片平臺芯片

    開放原子開源鴻蒙(OpenAtomOpenHarmony,簡稱“開源鴻蒙”或“OpenHarmony”)6.0Beta1版本正式發布。相比5.1.0Release
    的頭像 發表于 06-20 14:05 ?1574次閱讀
    開源鴻蒙6.0<b class='flag-5'>Beta1</b><b class='flag-5'>版本</b>發布!觸覺智能將率先適配RK3566/RK3568/RK3576等芯片平臺芯片

    deepin 25 Beta版本成功適配Radxa ROCK 5系列開發板

    近日,deepin(深度)社區宣布,deepin 25 Beta 版本已正式適配 Radxa ROCK 5 系列開發板,包括 ROCK 5B、ROCK 5B+ 和 ROCK 5 ITX 等型號。
    的頭像 發表于 06-06 17:25 ?1620次閱讀

    迅為RK3568多個系統版本并流暢運行Android12和11版本

    、Xenomai實時系統AMP雙系統,助力高可靠領域研發。流暢運行Android12和11版本、Ubuntu22.04、20.04版本Debian10、Yocto、buildroot+OT、OpenHarmonyv4.1等系統。
    發表于 04-14 16:20