目錄前言一、如何實現1、計算邊框大小2、計算縮放大小3、逆運算視頻寬高二、完整代碼三、使用示例總結前言一般情況下播放視頻時不需要旋轉,但是如果是移動端錄制的視頻有時會出現參數,且視頻寬高也...
目錄二、完整代碼三、使用示例總結
前言
一般情況下播放視頻時不需要旋轉,但是如果是移動端錄制的視頻有時會出現參數,且視頻寬高也是互換的可以旋轉視頻的播放器,如果直接渲染則會出現視頻90度倒轉的問題。所以渲染視頻時需要獲取包的中的參數,計算出旋轉角度,按照旋轉角度渲染視頻才能顯示正常的畫面。
一、如何實現
sdl支持旋轉渲染使用設置旋轉角度即可旋轉畫面,但是直接設置之后顯示的畫面位置是異常的,尤其時旋轉非直角角度后畫面大小會大一些,所以需要對旋轉后的畫面的位置以及大小進行一些處理。
1、計算邊框大小
計算旋轉后的邊框大小。知道視頻畫面寬高和旋轉角度,根據三角函數即可計算出邊框大小,這里就沒必要具體說明了。
邊框寬=視頻高?sinθ+視頻寬?cosθ
邊框高=視頻高?cosθ+視頻寬?sinθ
示例代碼:
//srcRect為視頻區域,angle為旋轉角度 const double PI = 3.1415926535897935384626; //角度轉弧度,用于三角php函數計算。 double theta = PI / 180.0 * angle; //計算旋轉后的邊框大小,+0.5四舍五入 int width = srcRect->h * fabs(sin(theta) )+ srcRect->w * fabs(cos(theta)) + 0.5; int height = srcRect->h * fabs(cos(theta)) + srcRect->w * fabs(sin(theta)) + 0.5;
2、計算縮放大小
邊框寬=邊框寬&;縮放比
邊框高=邊框高?縮放比
代碼示例:
//邊框的寬高比 double srcBorderRatio = (double)width / height; //目標區域的寬高比 double dstRatio = (double)dstRect->w / dstRect->h; //計算邊框縮放到目標區域的大小 int zoomWidth; int zoomHeight; if (srcBorderRatio > dstRatio) { zoomWidth = dstRect->w; zoomHeight = dstRect->w / srcBorderRatio; } else { zoomWidth = dstRect->h * srcBorderRatio; zoomHeight = dstRect->h; }
3、逆運算視頻寬高
視頻高=邊框寬/(sinθ+視頻寬高比?cosθ)
視頻寬=視頻高?視頻寬高比
代碼示例:
//視頻的寬高比 double srcRatio = (double)srcRect->w / srcRect->h; //通過縮放后的邊框計算還原的圖像大小 targetRect.h = (double)zoomWidth / (fabs(sin(theta) )+ srcRatio * fabs(cos(theta))); targetRect.w = targetRect.h * srcRatio; targetRect.x = (dstRect->w- targetRect.w ) / 2; targetRect.y = (dstRect->h- targetRect.h ) / 2;
二、完整代碼
////// 計算旋轉的矩形大小 /// /// 原圖像區域 /// 目標區域 /// 旋轉角度 ///static SDL_Rect getRotateRect(SDL_Rect *srcRect, SDL_Rect* dstRect,double angle) { SDL_Rect targetRect; const double PI = 3.1415926535897935384626; double theta = PI / 180.0 * angle; //計算旋轉后的邊框大小 int width = srcRect->h * fabs(sin(theta) )+ srcRect->w * fabs(cos(theta)) + 0.5; int height = srcRect->h * fabs(cos(theta)) + srcRect->w * fabs(sin(theta)) + 0.5; double srcRatio = (double)srcRect->w / srcRect->h; double srcBorderRatio = (double)width / height; double dstRatio = (double)dstRect->w / dstRect->h; //計算邊框縮放到目標區域的大小 int zoomWidth; int zoomHeight; if (srcBorderRatio > dstRatio) { zoomWidth = dstRect->w; zoomHeight = dstRect->w / srcBorderRatio; } else { zoomWidth = dstRect->h * srcBorderRatio; zoomHeight = dstRect->h; } //通過縮放后的邊框計算還原的圖像大小 targetRect.h = (double)zoomWidth / (fabs(sin(theta) )+ srcRatio * fabs(cos(theta)));
targetRect.w = targetRect.h * srcRatio; targetRect.x = (dstRect->w- targetRect.w ) / 2; targetRect.y = (dstRect->h- targetRect.h ) / 2; return targetRect; }
三、使用示例
只展示渲染部分,初始化及獲取視頻略。
//窗口區域 sdlRect.x = 0; sdlRect.y = 0; sdlRect.w = video->screen_w; sdlRect.h = video->screen_h; //視頻區域 sdlRect2python.x = 0; sdlRect2.y = 0; sdlRect2.w = video->decoder.codecContext->width; sdlRechttp://www.cppcns.comt2.h = video->decoder.codecContext->height; //渲染到sdl窗口 SDL_RenderClear(video->sdlRenderer); SDL_UpdateYUVTexture(video->sdlTexture, &sdlRect2, dst_data[0], dst_linesize[0], dst_data[1], dst_linesize[http://www.cppcns.com1], dst_data[2], dst_linesize[2]); if (video->angle == 0)SDL_RenderCopy(video->sdlRenderer, video->sdlTexture, NULL, &sdlRect); else //當旋轉角度不為0時使用SDL_RenderCopyEx渲染 { SDL_Rect sdlRect3; //計算旋轉后的目標區域 sdlRect3= getRotateRect(&sdlRect2,&sdlRect,video->angle); SDL_RenderCopyEx(video->sdlRenderer, video->sdlTexture, NULL , &sdlRect3, video->angle, 0, SDL_FLIP_NONE); } SDL_RenderPresent(video->sdlRenderer);
效果預覽:
1、mp4 -為270,未處理旋轉的情況:
2、旋轉270度后
3、自定義旋轉角度
總結
以上就是今天要講的內容可以旋轉視頻的播放器,做音視頻開發過程中還是比較少遇到需要旋轉視頻的場景的,筆者也是測試播放器的時候,無意中發現自己手機的視頻播放時畫面倒轉了,經過一番探究才了解到播放視頻時需要處理信息,于是實現了sdl渲染帶旋轉參數的視頻,順帶也支持任意角度旋轉。
到此這篇關于C++ sdl實現渲染旋轉視頻的方法分享的文章就介紹到這了,更多相關sdl渲染旋轉視頻內容請搜索我們以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持我們!
本文標題: C++ sdl實現渲染旋轉視頻的方法分享