日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

直播流??內(nèi)存優(yōu)化?案

來源: 責(zé)編: 時間:2023-10-13 14:36:55 287觀看
導(dǎo)讀01項目背景介紹項目中直播流每場直播由一張直播圖片作為展示入口,用于提示用戶此直播的概要。如下圖: 圖片然而直播圖片和容器的寬高比例出現(xiàn)不一致的情況。針對此情況,采取背景圖 contentmode展示為 aspectFill 且高斯

01項目背景介紹

項目中直播流每場直播由一張直播圖片作為展示入口,用于提示用戶此直播的概要。如下圖: ODm28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ODm28資訊網(wǎng)——每日最新資訊28at.com

然而直播圖片和容器的寬高比例出現(xiàn)不一致的情況。針對此情況,采取背景圖 contentmode展示為 aspectFill 且高斯模糊,上層高清圖為 aspectfit,給用戶一種圖片填滿且能清除獲取信息的視覺體驗。如下圖:ODm28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ODm28資訊網(wǎng)——每日最新資訊28at.com

然而服務(wù)端下發(fā)直播的圖片分辨率在1000 * 2000byte左右,占用內(nèi)存大小為1000 * 2000 * 4,約為 2M 大小。資深直播用戶最多有一千場直播。使用 sd_webImage 下載圖片并緩存在內(nèi)存中,查看足夠多的直播封面時,在iPhone 13機型,iOS15的手機,滑動到400場直播時,就會產(chǎn)生內(nèi)存不足崩潰。且崩潰堆棧展示在進行高斯模糊的方法中。ODm28資訊網(wǎng)——每日最新資訊28at.com

02分析問題

經(jīng)過初步分析,得出影響內(nèi)存的原因有以下幾方面。ODm28資訊網(wǎng)——每日最新資訊28at.com

  • 圖片分辨率高,高斯模糊占用的內(nèi)存越高。因為需要對進行大量模糊計算;
  • 用戶快速滑動直播流,正常的下載圖片速度會展示所有劃過的圖片,高斯模糊在圖片下載完成 block 中執(zhí)行,即使劃過的直播圖,也會繼續(xù)高斯模糊直至返回。這樣會導(dǎo)致用戶大量無意義圖片占用大量內(nèi)存;
  • 兩張 ImageView 需要在內(nèi)存中加載兩張一樣的圖片,是一種內(nèi)存浪費;
  • 為了用戶查看圖片的及時性和流暢性,項目中沒有設(shè)置存儲高斯模糊圖片最大占用內(nèi)存。這會導(dǎo)致圖片內(nèi)存只會在內(nèi)存警告時被清除。導(dǎo)致高斯模糊不能獲取足夠的內(nèi)存而崩潰;
  • 高斯模糊采用 vImage 方案,占用 CPU 進行高斯模糊計算,CPU 繁忙不能及時釋放內(nèi)存,進一步加劇內(nèi)存緊張。

03針對問題,采取措施

降低圖片分辨率

  • 通?降低分辨率?式為采用圖片云開發(fā)系統(tǒng)提供的服務(wù)。在圖片 url 中加入分辨率的參數(shù), 直接下載相應(yīng)分辨率的圖?。分辨率的設(shè)置,以圖片清晰為標(biāo)準(zhǔn),?般設(shè)置為展 示 ImageView 的大小。這樣不消耗客戶端的資源,不會給 CPU 帶來額外的工作。

ODm28資訊網(wǎng)——每日最新資訊28at.com

避免下載快速劃過的圖片


ODm28資訊網(wǎng)——每日最新資訊28at.com

  • ODm28資訊網(wǎng)——每日最新資訊28at.com

    判斷用戶是否快速劃過,無需下載圖片。scrollViewDidScroll 的回調(diào)頻率是小于 CADisplayLink 回調(diào)頻率的,在滾動緩慢的狀態(tài)下,離散取整可能導(dǎo)致 contentOffset 在某次刷新中不發(fā)生變化,也就是說 didScroll 的兩次打點間隔有一定可能大于0.0167s,是2個或者3個刷新周期。低速狀態(tài)下本身差值的差別就不大,所以使用 didScroll 打點,默認間隔是0.0167s即可。在 scrollviewDidScroll 中記錄兩次 scrollview 移動的差值,經(jīng)實驗證明,速速大于60pt,流視圖圖片視覺上呈模糊狀態(tài),故以60pt作為暴力滑動的臨界點;ODm28資訊網(wǎng)——每日最新資訊28at.com

    ODm28資訊網(wǎng)——每日最新資訊28at.com

  • ODm28資訊網(wǎng)——每日最新資訊28at.com

    下一步,暴力滾動停止劃過圖片的下載。創(chuàng)建全局變量標(biāo)記是否暴力滾動,在系統(tǒng)調(diào)用 cellForItem 方法時,判斷標(biāo)記為是則不進行下載。非暴力滾動下,標(biāo)記為否, cell 根據(jù)標(biāo)記開啟下載當(dāng)前的圖片;ODm28資訊網(wǎng)——每日最新資訊28at.com

    ODm28資訊網(wǎng)——每日最新資訊28at.com

  • ODm28資訊網(wǎng)——每日最新資訊28at.com

    以上適用于自然減速停止的滑動。然而暴力滾動之后用戶手動突然停止,此時標(biāo)記雖已及時改為否,但展示在屏幕上的圖片都處于不下載的狀態(tài)。我們在 scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate: 代理表示停止拖拽,在此時機,將展示在屏幕上的 cell 重新下載圖片。具體代碼如下:ODm28資訊網(wǎng)——每日最新資訊28at.com

    [self.collectionView.visibleCells  enumerateObjectsUsingBlock:^(__kindof UICollectionViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {          SVPGCLiveCollectionViewCell *cell = obj;          if (!cell.yesToLoad) {              cell.yesToLoad = YES;          }  }];

    自定義 cell ,setYesToLoad方法中下載圖片,設(shè)置 yesToLoad為 Yes ,即可開啟下載當(dāng)屏的圖片這種情況;ODm28資訊網(wǎng)——每日最新資訊28at.com

    ODm28資訊網(wǎng)——每日最新資訊28at.com

  • ODm28資訊網(wǎng)——每日最新資訊28at.com

    其他的滑動情況:滾動到流頂部,手動設(shè)置 contenOffset:animated:經(jīng)測試,滾動的速度屬于暴力滾動。需要在 scrollViewDidScrollToTop 和 scrollViewDidEndScrollingAnimation 中設(shè)置當(dāng)屏圖片重新下載;ODm28資訊網(wǎng)——每日最新資訊28at.com

    ODm28資訊網(wǎng)——每日最新資訊28at.com

  • ODm28資訊網(wǎng)——每日最新資訊28at.com

    內(nèi)存存儲高斯模糊的容器為 NSCache ,NSCache 提供最大儲存值。根據(jù)直播 tab 業(yè)務(wù)需要,每屏展示的數(shù)量大約為15張左右。存儲的數(shù)值需比15張略大,保證頁面的流暢度。初設(shè)值為20,每張占用的內(nèi)存在5M左右,20張存儲在100M,可接收范圍內(nèi);ODm28資訊網(wǎng)——每日最新資訊28at.com

    ODm28資訊網(wǎng)——每日最新資訊28at.com

  • ODm28資訊網(wǎng)——每日最新資訊28at.com

    高斯模糊由 vImage 方式修改為 GPUImage 方式,使用 CPU 處理圖像, GPUImage 在 GPU 上處理 filter ,經(jīng)統(tǒng)計,在 iOS13 上,處理圖片濾鏡時間比快約2倍。GPU 處理 filter 圖片需要運行大量 openGL 代碼,GPUImage 封裝了 openGL,只需要調(diào)用接口就可以實現(xiàn) filter 。GPUImage 沒有現(xiàn)成的合成一張底部高斯,上層高清的圖片濾鏡。GPUImage 支持自定義頂點著色器和片元著色器實現(xiàn)濾鏡。整體思路為,使用混合濾鏡將高斯濾鏡的紋理和原圖紋理按照坐標(biāo)計算生成新的輸出。紋理鏈條如圖:ODm28資訊網(wǎng)——每日最新資訊28at.com

    ODm28資訊網(wǎng)——每日最新資訊28at.com


    ODm28資訊網(wǎng)——每日最新資訊28at.com

a. 初始化高斯濾鏡,并設(shè)置參數(shù)。ODm28資訊網(wǎng)——每日最新資訊28at.com

GPUImageGaussianBlurFilter *gaussionfilter =     [[GPUImageGaussianBlurFilter alloc] init];        gaussionfilter.blurRadiusInPixels = 9;//數(shù)值越高,越糊。        [gaussionfilter forceProcessingAtSize:highDefiniImage.size];

說明:blurRadiusInPixels 決定高斯的卷積數(shù)。卷積數(shù)越高,模糊效果越明顯。forceProcessingAtSize:設(shè)置高斯過濾器的目標(biāo)輸出分辨率ODm28資訊網(wǎng)——每日最新資訊28at.com

b. 初始始化原始圖?。GPUImage中靜態(tài)圖?的源對象為 GPUImagePicture類ODm28資訊網(wǎng)——每日最新資訊28at.com

GPUImagePicture *highImage = [[GPUImagePicture alloc] initWithImage:highDefiniImage];

通過傳?原圖的 image 對象?成 GPUImagePicture 。ODm28資訊網(wǎng)——每日最新資訊28at.com

c. 自定義頂點著色器和片元著色器創(chuàng)建自定義混合濾鏡。頂點著色器,是對頂點進行一系列操作的著色器,頂點除了有最基本的位置屬性,還包含其他屬性,比如紋理,法線等。通過頂點著色器,顯卡就知道頂點應(yīng)該繪制在具體什么位置。針對每個頂點,頂點著色器都會執(zhí)行一次。首先收到系統(tǒng)傳給他的數(shù)據(jù)(位置坐標(biāo)),將數(shù)據(jù)處理成后續(xù)我們需要的數(shù)據(jù)。系統(tǒng)對頂點著色器輸出的頂點數(shù)據(jù)進行插值,并將插值結(jié)果傳遞給片段著色器。片段著色器根據(jù)插值結(jié)果計算最后屏幕上的像素顏色。 GPUImageTwoInputFilter 提供頂點著色器的代碼滿足需求,直接使用即可。頂點著色器的代碼如下所示:ODm28資訊網(wǎng)——每日最新資訊28at.com

NSString *const kGPUImageTwoInputTextureVertexShaderString = SHADER_STRING( attribute vec4 position; attribute vec4 inputTextureCoordinate; //attribute  標(biāo)注屬性為輸入變量,inputTextureCoordinate為第一個輸入對象的坐標(biāo) attribute vec4 inputTextureCoordinate2; //inputTextureCoordinate2 為第二個輸入變量的坐標(biāo) varying vec2 textureCoordinate; // varying 標(biāo)注屬性為在vertex shader和fragment shader之間傳遞數(shù)據(jù),表示將第一個輸入對象的坐標(biāo)傳遞給片段著色器 varying vec2 textureCoordinate2; //表示將第二個輸入對象的坐標(biāo)傳遞給片段著色器 void main() {     gl_Position = position;     textureCoordinate = inputTextureCoordinate.xy;     textureCoordinate2 = inputTextureCoordinate2.xy; });

GPUImage 包裝頂點著色器為 string,便于加載。每一行代碼的作用標(biāo)注在注釋里。片元著色器,是接收頂點著色器傳過來的數(shù)據(jù),進行像素顏色計算。首先,需要傳入畫布和原圖的大小,用于計算畫布從原圖采點的坐標(biāo)。其次,計算變量,我們需要確定上層高清圖在畫布上的leftX 和 rightX ,topY 和 bottomY,高度 targetH,寬度 targetW 。以及底部高斯背景圖片設(shè)置為 aspectFill 的高度和寬度。以上數(shù)值的計算涉及高清圖橫圖和豎圖。見下圖,左圖為豎圖,右圖為橫圖:ODm28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ODm28資訊網(wǎng)——每日最新資訊28at.com

相應(yīng)代碼如下:ODm28資訊網(wǎng)——每日最新資訊28at.com

if (drawableW/drawableH > imageW/imageH ){//豎版          targetW = imageW * (drawableH/imageH);          lowp  float  left = (drawableW - targetW)/float(2);          leftX = left/drawableW;          rightX = (left+targetW)/drawableW;          targetH = drawableH;          bottomY = 1.0;          targetHFill = imageHFill * drawableW / imageWFill;          targetWFill = drawableW;      }else{//橫版          targetH = imageH * (drawableW/imageW);          lowp float top = (drawableH - targetH)/float(2);          topY = top/drawableH;          bottomY = (top+targetH)/drawableH;          targetW  = drawableW;          rightX = 1.0;          targetWFill = imageWFill * drawableH / imageHFill;          targetHFill = drawableH;      }

片元著色器通過 gl_FragColor = texture2D ( 參數(shù)1:輸?對象的紋理,參數(shù)2:輸入對象的坐標(biāo)) 得到當(dāng)前坐標(biāo)的紋理。參數(shù)1由直接取值,參數(shù)2需要計算。坐標(biāo)的計算分2種情況,?清圖和?斯背景,當(dāng)畫布坐標(biāo)處于 leftX 和 rightX , topY 和 bottomY 之間,則繪制?清圖,應(yīng)取?清圖的相應(yīng)坐標(biāo)。相應(yīng)坐標(biāo)的計算為繪制的 點從畫布坐標(biāo)換算到在?清圖上的坐標(biāo)(坐標(biāo)都為0-1區(qū)間值)如圖:ODm28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ODm28資訊網(wǎng)——每日最新資訊28at.com

目標(biāo)為計算出高清圖的0.2,0.1。換算代碼如下:ODm28資訊網(wǎng)——每日最新資訊28at.com

if (textureCoordinate2.x >= leftX   && textureCoordinate2.x <= rightX && textureCoordinate2.y >= topY && textureCoordinate2.y <= bottomY) {lowp  float offsetX = textureCoordinate2.x - leftX; //offsetx為圖中X的間距在畫布的占比。lowp  float x = (offsetX * drawableW)/targetW; //X的距離在深灰高清圖中距離。lowp  float offsetY = textureCoordinate2.y - topY;lowp  float y = (offsetY * drawableH)/targetH;}

由公式 offX* drawableW = x *targetW 左右兩邊都是 X 線段的實際距離,從而得出 x 的值。同理得出 Y 的值。當(dāng)畫布的坐標(biāo)落在上圖淺灰色區(qū)域,采點高斯。高斯展示方式為 aspectFill. 如下圖:ODm28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ODm28資訊網(wǎng)——每日最新資訊28at.com

ODm28資訊網(wǎng)——每日最新資訊28at.com

粉色部分為高斯圖片的布局。高寬都會溢出被剪切一部分。圖中三角形為畫布中要繪制的點,此點在高斯圖中的位置為 targetY/targetHfill。targetY = (textureCoordinate2.y * drawableH + (targetHFill - drawableH )/float(2)) 為高斯圖被剪裁的上高度+畫布繪制點據(jù)畫布頂部的距離。具體代碼如下:ODm28資訊網(wǎng)——每日最新資訊28at.com

lowp   float  y = (textureCoordinate2.y * drawableH + (targetHFill - drawableH )/float(2))/ targetHFill;lowp  float x = (textureCoordinate2.x * drawableW + (targetWFill - drawableW )/float(2))/ targetWFill;gl_FragColor = texture2D(inputImageTexture, vec2(x, y));

x 的計算方式和 y 值相同。到此,片元著色器的工作完成。ODm28資訊網(wǎng)——每日最新資訊28at.com

d. GPUImage加載著色器,并返回 UIImage 對象。自此,一張高斯背景疊加高清的圖片生成了。在直播流中,不止有一張需要合成,且合成是較耗時操作,需將合成操作放在子線程異步執(zhí)行。執(zhí)行完成后同步回到主線程展示。ODm28資訊網(wǎng)——每日最新資訊28at.com

e. 在使用 GPUImage 時,有?個需要注意的地?。GPUImage 底層使?的 是 openGL , openGL 在后臺進行渲染會導(dǎo)致 app 崩潰。所以需要我們退出后臺時,停止 openGl 渲染。采取的方式有三種,第?種,將合成隊列在退出后臺前設(shè) 置 suspend = yes ,還未開始的合成任務(wù)將不再執(zhí)行,直至進入前臺后設(shè) 置 suspend = no 。然而,這種方式不能規(guī)避還在進行中的任務(wù)。于是第?種,?定 義 NSOperation ,執(zhí)? operation 時。系統(tǒng)會調(diào)用 NSOperation 的 main 函數(shù), 在 main 函數(shù)中,寫實現(xiàn)代碼。在每?句實現(xiàn)代碼前都判斷是否 cancled 。如果 cancled ,直接 return 。在系統(tǒng)即將進?后臺時,將在運行的任務(wù) cancle 掉, operation 繼續(xù)執(zhí)行,監(jiān)測到已經(jīng) cancle 了,就會 return 。然而,粒度還是不夠細。如果任務(wù)執(zhí)行到最后一行,且最后一行有 openGL 操作,那么就會攔截不到。第三種, GPUImage 的渲染都是放在??的?個隊列同步執(zhí)?,在接收到系統(tǒng)將進入后臺的通知中,加入渲染隊列?個同步空任務(wù),則系統(tǒng)會執(zhí)行完空任務(wù)前的所有 任務(wù)之后,再進入后臺。從而避免后臺渲染。ODm28資訊網(wǎng)——每日最新資訊28at.com

自此,多張合成圖片的方案就結(jié)束了,結(jié)合線上數(shù)據(jù),本頁內(nèi)存消耗節(jié)約10M左右,每張合成圖片時間節(jié)約8ms左右。ODm28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-13539-0.html直播流??內(nèi)存優(yōu)化?案

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 微軟將在 Windows 中棄用 VBScript

下一篇: Minium-小程序自動化測試框架

標(biāo)簽:
  • 熱門焦點
  • K60至尊版狂暴引擎2.0加持:超177萬跑分斬獲性能第一

    Redmi的后性能時代戰(zhàn)略發(fā)布會今天下午如期舉辦,在本次發(fā)布會上,Redmi公布了多項關(guān)于和聯(lián)發(fā)科的深度合作,以及新機K60 Ultra在軟件和硬件方面的特性,例如:“K60 至尊版,雙芯旗艦
  • 2023年Q2用戶偏好榜:12+256G版本成新主流

    3月份的性能榜、性價比榜和好評榜之后,就要輪到2023年的第二季度偏好榜了,上半年的新機潮已經(jīng)過去,最明顯的肯定就是大內(nèi)存和存儲的機型了,另外部分中端機也取消了屏幕塑料支架
  • 從 Pulsar Client 的原理到它的監(jiān)控面板

    背景前段時間業(yè)務(wù)團隊偶爾會碰到一些 Pulsar 使用的問題,比如消息阻塞不消費了、生產(chǎn)者消息發(fā)送緩慢等各種問題。雖然我們有個監(jiān)控頁面可以根據(jù) topic 維度查看他的發(fā)送狀態(tài),
  • 谷歌KDD'23工作:如何提升推薦系統(tǒng)Ranking模型訓(xùn)練穩(wěn)定性

    谷歌在KDD 2023發(fā)表了一篇工作,探索了推薦系統(tǒng)ranking模型的訓(xùn)練穩(wěn)定性問題,分析了造成訓(xùn)練穩(wěn)定性存在問題的潛在原因,以及現(xiàn)有的一些提升模型穩(wěn)定性方法的不足,并提出了一種新
  • 三分鐘白話RocketMQ系列—— 如何發(fā)送消息

    我們知道RocketMQ主要分為消息 生產(chǎn)、存儲(消息堆積)、消費 三大塊領(lǐng)域。那接下來,我們白話一下,RocketMQ是如何發(fā)送消息的,揭秘消息生產(chǎn)全過程。注意,如果白話中不小心提到相關(guān)代
  • 微博大門常打開,迎接海外畫師漂洋東渡

    作者:互聯(lián)網(wǎng)那些事&ldquo;起猛了,我能看得懂日語了&rdquo;。&ldquo;為什么日本人說話我能聽懂?&rdquo;&ldquo;中文不像中文,日語不像日語,但是我竟然看懂了&rdquo;&hellip;&hell
  • 華為HarmonyOS 4升級計劃公布:首批34款機型今日開啟公測

    8月4日消息,今天下午華為正式發(fā)布了HarmonyOS 4系統(tǒng),在更流暢的前提下,還帶來了不少新功能,UI設(shè)計也有變化,會讓手機煥然一新。華為宣布,首批機型將會在
  • 自研Exynos回歸!三星Galaxy S24系列將提供Exynos和驍龍雙版本

    年初,全新的三星Galaxy S23系列發(fā)布,包含Galaxy S23、Galaxy S23+和Galaxy S23 Ultra三個版本,全系搭載超頻版驍龍8 Gen 2,雖同樣采用臺積電4nm工藝制
  • 滴滴違法違規(guī)被罰80.26億 共存在16項違法事實

    滴滴違法違規(guī)被罰80.26億 存在16項違法事實開始于2121年7月,歷經(jīng)一年時間,網(wǎng)絡(luò)安全審查辦公室對“滴滴出行”網(wǎng)絡(luò)安全審查終于有了一個暫時的結(jié)束。據(jù)“網(wǎng)信
Top 主站蜘蛛池模板: 阜康市| 香格里拉县| 乌鲁木齐县| 上蔡县| 邢台市| 卢龙县| 浑源县| 贵德县| 浦江县| 博客| 普格县| 晋州市| 温州市| 黑水县| 鄂伦春自治旗| 德江县| 班戈县| 吉木萨尔县| 紫金县| 钦州市| 越西县| 临高县| 郸城县| 永安市| 农安县| 额济纳旗| 扬中市| 塔城市| 永胜县| 济阳县| 仙游县| 德惠市| 陆良县| 松江区| 乐至县| 台中县| 桂平市| 潼关县| 西乌珠穆沁旗| 东兴市| 喜德县|