欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ sdl實現渲染旋轉視頻的方法分享

 更新時間:2022年12月16日 10:30:39   作者:CodeOfCC  
一般情況下播放視頻時不需要旋轉,但是如果是移動端錄制的視頻有時會出現rotate參數,且視頻寬高也是互換的。所以本文為大家準備了利用sdl實現渲染旋轉視頻的方法,需要的可以參考一下

前言

一般情況下播放視頻時不需要旋轉,但是如果是移動端錄制的視頻有時會出現rotate參數,且視頻寬高也是互換的,如果直接渲染則會出現視頻90度倒轉的問題。所以渲染視頻時需要獲取包的metadata中的rotate參數,計算出旋轉角度,按照旋轉角度渲染視頻才能顯示正常的畫面。

一、如何實現

sdl支持旋轉渲染使用SDL_RenderCopyEx設置旋轉角度即可旋轉畫面,但是直接設置之后顯示的畫面位置是異常的,尤其時旋轉非直角角度后畫面大小會大一些,所以需要對旋轉后的畫面的位置以及大小進行一些處理。

1、計算邊框大小

計算旋轉后的邊框大小。知道視頻畫面寬高和旋轉角度,根據三角函數即可計算出邊框大小,這里就沒必要具體說明了。

邊框寬=視頻高∗sinθ+視頻寬∗cosθ

邊框高=視頻高∗cosθ+視頻寬∗sinθ

示例代碼:

//srcRect為視頻區(qū)域,angle為旋轉角度
const double PI = 3.1415926535897935384626;
//角度轉弧度,用于三角函數計算。
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;
//目標區(qū)域的寬高比
double dstRatio = (double)dstRect->w / dstRect->h;
//計算邊框縮放到目標區(qū)域的大小
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;

二、完整代碼

/// <summary>
/// 計算旋轉的矩形大小
/// </summary>
/// <param name="src">原圖像區(qū)域</param>
/// <param name="dst">目標區(qū)域</param>
/// <param name="angle">旋轉角度</param>
/// <returns></returns>
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;
	//計算邊框縮放到目標區(qū)域的大小
	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;
}

三、使用示例

只展示渲染部分,初始化及獲取視頻略。

	//窗口區(qū)域
	sdlRect.x = 0;
	sdlRect.y = 0;
	sdlRect.w = video->screen_w;
	sdlRect.h = video->screen_h;
	//視頻區(qū)域
	sdlRect2.x = 0;
	sdlRect2.y = 0;
	sdlRect2.w = video->decoder.codecContext->width;
	sdlRect2.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[1], 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;
		//計算旋轉后的目標區(qū)域
		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 metadata-rotate為270,未處理旋轉的情況:

2、旋轉270度后

3、自定義旋轉角度

總結

以上就是今天要講的內容,做音視頻開發(fā)過程中還是比較少遇到需要旋轉視頻的場景的,筆者也是測試播放器的時候,無意中發(fā)現自己手機的視頻播放時畫面倒轉了,經過一番探究才了解到播放視頻時需要處理rotate信息,于是實現了sdl渲染帶旋轉參數的視頻,順帶也支持任意角度旋轉。

到此這篇關于C++ sdl實現渲染旋轉視頻的方法分享的文章就介紹到這了,更多相關sdl渲染旋轉視頻內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • c語言中scanf的基本用法

    c語言中scanf的基本用法

    這篇文章主要給大家介紹了關于c語言中scanf的基本用法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • C++缺省參數、函數重載與引用深入解析

    C++缺省參數、函數重載與引用深入解析

    缺省參數函數重載以及引用的出現是為了補充C語言語法的不足以及對C語言設計不合理的地方進行優(yōu)化,引用的出現大大降低了我們學習C語言時相對于指針的難度,也便于我們更好的理解和使用,感興趣的朋友一起看看吧
    2024-04-04
  • C++ 位運算的具體實現

    C++ 位運算的具體實現

    位運算直接對內存數據進行操作,不需要轉換成十進制,因此處理速度非???本文主要介紹了C++ 位運算的具體實現,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • c++類的隱式轉換與強制轉換重載詳解

    c++類的隱式轉換與強制轉換重載詳解

    轉換函數的名稱是類型轉換的目標類型,因此,不必再為它指定返回值類型;轉換函數是被用于本類型的數值或變量轉換為其他的類型,也不必帶參數
    2013-09-09
  • 在vs2010中,輸出當前文件路徑與源文件當前行號的解決方法

    在vs2010中,輸出當前文件路徑與源文件當前行號的解決方法

    本篇文章是對在vs2010中,輸出當前文件路徑與源文件當前行號的解決方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 解析OpenSSL1.1.1?centos7安裝編譯aes的c++調用

    解析OpenSSL1.1.1?centos7安裝編譯aes的c++調用

    這篇文章主要介紹了OpenSSL1.1.1?centos7安裝編譯aes的c++調用,實現方法也很簡單,主要是在該文檔內加入openssl的lib路徑,感興趣的朋友跟隨小編一起看看吧
    2022-03-03
  • Cocos2d-x人物動作類實例

    Cocos2d-x人物動作類實例

    這篇文章主要介紹了Cocos2d-x人物動作類實例,本文用大量代碼和圖片講解Cocos2d-x中的動作,代碼中同時包含大量注釋說明,需要的朋友可以參考下
    2014-09-09
  • C語言中的參數傳遞機制詳解

    C語言中的參數傳遞機制詳解

    這篇文章主要介紹了C語言中的參數傳遞機制,C語言中函數參數的傳遞有:值傳遞、地址傳遞、引用傳遞這三種形式。下面我們詳細探討下
    2017-04-04
  • 一篇文章帶你了解C語言的選擇結構

    一篇文章帶你了解C語言的選擇結構

    這篇文章主要為大家介紹了C語言的選擇結構,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • C語言值傳遞和地址傳遞詳解

    C語言值傳遞和地址傳遞詳解

    大家好,本篇文章主要講的是C語言值傳遞和地址傳遞詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01

最新評論