人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當(dāng)前位置:蘿卜系統(tǒng) > 硬件軟件教程 > 詳細(xì)頁面

web前端需要播放視頻設(shè)備出來的H265碼流背景

web前端需要播放視頻設(shè)備出來的H265碼流背景

更新時間:2023-07-02 文章作者:未知 信息來源:網(wǎng)絡(luò) 閱讀次數(shù):

顯卡是個人計算機(jī)基礎(chǔ)的組成部分之一,將計算機(jī)系統(tǒng)需要的顯示信息進(jìn)行轉(zhuǎn)換驅(qū)動顯示器,并向顯示器提供逐行或隔行掃描信號,控制顯示器的正確顯示,是連接顯示器和個人計算機(jī)主板的重要組件,是“人機(jī)”的重要設(shè)備之一,其內(nèi)置的并行計算能力現(xiàn)階段也用于深度學(xué)習(xí)等運(yùn)算。

使用FFmpeg調(diào)用NVIDIA GPU以將H265轉(zhuǎn)碼為H264

背景

最近,該項目遇到了一個問題,即Web前端需要播放視頻設(shè)備中的H265流,但是目前僅支持H264流,因此如果我想快速解決此問題,我就來了有兩種解決方案。

方案1:通過RTMP將H265直接封裝到自定義FLV中,然后將其發(fā)布到前端播放中。 Web前端必須支持解析H265回放的控制。如果使用這種解決方案,則目前很難找到適用的開源解決方案,而后端和后端的變化基本上可以說是被推翻了,因此這種方案很難實現(xiàn)。一會兒。

方案2:提供轉(zhuǎn)碼服務(wù)以解碼H265,然后將其編碼為H264。無需對Web前端播放方案進(jìn)行任何更改。有兩種方案,軟件代碼轉(zhuǎn)換和硬件代碼轉(zhuǎn)換,因為軟件代碼轉(zhuǎn)換非常消耗CPU資源,因此可以基本消除這種想法,因此僅考慮硬件代碼轉(zhuǎn)換方案。下面的文章將介紹硬件代碼轉(zhuǎn)換方案。

比較這兩種方案,第二種方案比較合理,可以較快地解決H265播放問題。

H265和H264 1、 H265流nalu標(biāo)頭的一些基本知識

nuh_unit_type的值00 00 00 01 40 01為32,其語義是視頻參數(shù)集VPS

nuh_unit_type的值00 00 00 01 42 01為33,其語義為序列參數(shù)集SPS

nuh_unit_type的值00 00 00 01 44 01為34,其語義是圖像參數(shù)集PPS

nuh_unit_type的值00 00 00 01 4E 01為39,語義為補(bǔ)充增強(qiáng)信息SEI

nuh_unit_type的值00 00 00 01 26 01為19,其語義是可能具有RADL圖像的IDR圖像的SS編碼數(shù)據(jù)IDR。

nuh_unit_type的值00 00 00 01 02 01為1,語義是引用的帖子圖片,以及非TSA,非STSA SS編碼的數(shù)據(jù)

2、 H264流nalu標(biāo)頭

00 00 00 01 06類型的值為06,NALU_TYPE_SEI語義是補(bǔ)充增強(qiáng)信息SEI

00 00 00 01 67 type的值為67,并且NALU_TYPE_SPS的語義是序列參數(shù)集SPS

00 00 00 01 68類型值是68,NALU_TYPE_PPS語義是圖像參數(shù)集PPS

00 00 00 01 65類型值是65,NALU_TYPE_IDR語義是IDR圖像中的IDR

3、補(bǔ)充:IDR幀和I幀之間的關(guān)系

IDR幀是I幀,但I(xiàn)幀不一定是IDR幀。在完整的視頻流單元中,第一圖像幀是IDR幀。 IDR幀為強(qiáng)制刷新幀。在解碼過程中,當(dāng)有IDR幀時,有必要更新sps,pps,原因是為了防止以前的I幀錯誤,導(dǎo)致無法通過參考I幀來校正sps,pps。

另一個流行的概念是GOP。 GOP的全名是“圖片組”,它是兩個I幀之間的距離。 GOP值越大,則I幀速率之間的P和B幀越多。 ,圖像質(zhì)量越好,如果GOP為120,分辨率為720P,幀頻為60,則兩個I幀的時間為120/60 = 2s。

轉(zhuǎn)碼的一些基礎(chǔ)知識1、如何區(qū)分軟編碼和硬編碼

軟編碼:使用CPU進(jìn)行編碼

硬編碼:使用非CPU進(jìn)行編碼,例如圖形卡GPU,專用DSP,F(xiàn)PGA芯片等。

2、軟編碼和硬編碼的比較

軟編碼:實現(xiàn)直接,簡單,參數(shù)調(diào)整方便,升級容易,但CPU負(fù)擔(dān)重,性能低于硬編碼,質(zhì)量通常比硬編碼低比特率。

硬編碼:高性能,在低比特率下質(zhì)量通常低于軟編碼器,但是某些產(chǎn)品已經(jīng)在GPU硬件平臺(例如X26 4))上移植了出色的軟編碼算法,其質(zhì)量基本上相當(dāng)于軟編碼。

3、當(dāng)前的主流GPU加速平臺

NVIDIA、INTEL、AMD等

4、當(dāng)前主流GPU平臺開發(fā)框架

CUDA:NVIDIA的封閉式編程框架,通過它可以調(diào)用GPU計算資源

AMD APP:AMD為自己的GPU提出了一套通用的并行編程框架。該標(biāo)準(zhǔn)是開放的。通過在CPU和GPU上支持OpenCL框架,它可以集成計算能力。

c++ 利用ffmpeg解碼播放h264文件_ffmpeg 解碼h264文件_ffmpeg調(diào)用顯卡編解碼

OpenCL:開放計算語言,一種為異構(gòu)平臺編寫程序的框架。異構(gòu)平臺可以包括CPU,GPU和其他計算處理器。目的是使同一計算能夠支持不同平臺上的硬件加速。

Inel QuickSync:集成在Intel圖形卡中的專用視頻編模塊。

5、流程差異

硬件和軟件:讀取(ffmpeg)->(NVIDIA cuvid)->編碼器(ffmpeg)

軟解碼和編輯:讀取(ffmpeg)->(ffmpeg)->編碼器(ffmpeg)

軟硬代碼:讀取(ffmpeg)->(ffmpeg)->編碼器(NVIDIA nvenc)

NVIDIA + ffmpeg硬件加速部署1、環(huán)境安裝和部署:Windows10 + ffmpeg 4. 1. 3 + NVIDIA GeForce GTX 1660Ti

注意:您需要在計算機(jī)上安裝以下NVIDIA圖形卡之一。我本人使用GeForce GTX 1660Ti顯卡(在NVIDIA tesla T4顯卡上進(jìn)行了驗證,它可以同時對8個以上的通道進(jìn)行轉(zhuǎn)碼)

1. 1 ffmpeg Windows版本下載

下載鏈接:

在這里插入圖片描述

支持下載static / dev / shared

我使用的ffmpeg版本是4. 1. 3

1. 2下載NVIDIA驅(qū)動程序(GTX 1660Ti)

下載鏈接:

在這里插入圖片描述

版本45 1. 77(1 1. 0)地址:

在這里插入圖片描述

1. 3下載cuda工具包(GTX 1660Ti)

下載鏈接:

版本45 1. 48(1 1. 0)地址:

在這里插入圖片描述

不會介紹安裝。

1. 4使用ffmpeg.exe -hwaccels顯示所有可用的硬件

我下載的FFmpeg已經(jīng)包含Nvidia的硬件

在這里插入圖片描述

1. 5使用ffmpeg.exe -codecs查看編支持

DEV.LS h264 H.264 / AVC / MPEG-4 AVC / MPEG-4第10部分(:h264 h264_qsv h264_cuvid)(編碼器:libx264 libx264rgb h264_amf h264_nvenc h264_qsv nvenc nvenc_h264)

DEV.L。 hevc H.265 / HEVC(高效視頻編碼)(:hevc hevc_qsv hevc_cuvid)(編碼器:libx265 nvenc_hevc hevc_amf hevc_nvenc hevc_qsv)

h264_cuvid:h264硬件

h264_nvenc:h264硬件編碼器

hevc_cuvid:h265硬件

c++ 利用ffmpeg解碼播放h264文件_ffmpeg調(diào)用顯卡編解碼_ffmpeg 解碼h264文件

hevc_nvenc:h265硬件編碼器

在這里插入圖片描述

NVENC簡介

NVENC是NVIDIA開發(fā)的API,允許使用NVIDIA GPU圖形卡執(zhí)行h.264和HEVC(即H.26 5)編碼。FFmpeg通過h264_nvenc和hevc_nvenc編碼器支持NVENC。

要在FFmpeg中啟用它,您需要:

支持硬件編碼和解碼的NVIDIA GPU

NVIDIA GPU驅(qū)動程序

沒有配置禁用nvenc的ffmpeg

使用示例:

ffmpeg -i input -c:v h264_nvenc -profile high444p -pixel_format yuv444p -preset default output.mp4

您可以通過ffmpeg -h編碼器= h264_nvenc或ffmpeg -h編碼器= hevc_nvenc來查看可用的預(yù)設(shè),其他選項和編碼器信息。

注意:如果在沒有NVENC功能的設(shè)備中發(fā)現(xiàn)錯誤,請確保您的編碼采用受支持的像素格式。請參閱上面顯示的編碼器信息。

CUDA / CUVID / NvDecode

CUVID現(xiàn)在也被Nvidia稱為nvdec,可以在Windows和Linux上進(jìn)行解碼。與nvenc結(jié)合使用,可提供完整的硬件轉(zhuǎn)碼。

CUVID提供H264,HEVC,MJPEG,mpeg1 / 2/4,vp8 / 9,vc1。編支持因硬件而異。

1、使用CUVID。在此示例中,CUVID將幀復(fù)制到系統(tǒng)內(nèi)存:

ffmpeg -c:v h264_cuvid -i input output.mkv

2、使用CUVID和NVENC來實現(xiàn)完整的硬件轉(zhuǎn)碼:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input -c:v h264_nvenc -preset slow output.mkv

3、硬件轉(zhuǎn)碼的一部分,該幀通過系統(tǒng)內(nèi)存(這是對10位內(nèi)容進(jìn)行轉(zhuǎn)碼所必需的):

ffmpeg -c:v h264_cuvid -i input -c:v h264_nvenc -preset slow output.mkv

4、如果在編譯ffmpeg時支持libnpp,則可以使用它在鏈中插入基于GPU的縮放器:

ffmpeg -hwaccel_device 0 -hwaccel cuvid -c:v h264_cuvid -i input -vf scale_npp=-1:720 -c:v h264_nvenc -preset slow output.mkv

hwaccel_device選項可用于指定ffmpeg:中的cuvid hwaccel使用的GPU。

FFmpeg命令行硬件對H265原始流文件進(jìn)行代碼轉(zhuǎn)換

使用NVIDIA GTX1660ti圖形卡+ ffmpeg 4. 1. 3

1、 H265軟件解碼,H264硬件編碼

ffmpeg.exe -i h265toh264.h265 -vcodec h264_nvenc -r 30 -y h265toh264.h264

2、完整的硬件轉(zhuǎn)碼(H265硬件解碼,H264硬件編碼)

ffmpeg.exe -hwaccel cuvid -c:v hevc_cuvid -i h265toh264.h265 -c:v h264_nvenc -r 30 -y h265toh264.h264

用于將H265原始流文件轉(zhuǎn)碼為H264的FFmpeg API

在VS2017項目下,使用ffmpeg API將H265軟件解碼為YUV,并使用h264_nvenc(NVIDIA硬件編碼器)或libx264(h264軟件編碼器)將YUV編碼實現(xiàn)為H26 4.

c++ 利用ffmpeg解碼播放h264文件_ffmpeg調(diào)用顯卡編解碼_ffmpeg 解碼h264文件

直接轉(zhuǎn)到源代碼:

1、主要代碼

#include "H265Decoder.h"
#include "H264Encoder.h"
#define ISSTORAGEYUV 0
int main()
{
	int fpts = 0;
	char frame_buf[1024] = { 0 };
	int H265Lenth = 0;
	char H265Buf[1024 * 512];
	H265Decoder h265Decoder;
	H264Encoder h264Encoder;
	//初始化編時需要把正確的分辨率送進(jìn)去
	/*h265Decoder.Init(1920, 1080);
	h264Encoder.Init(1920, 1080);*/
	h265Decoder.Init(480, 272);
	h264Encoder.Init(480, 272);
	
	//讀取文件
	FILE * InFile = fopen("h265toh264.h265", "rb");
	//輸出文件
#if ISSTORAGEYUV
	FILE * OutFile = fopen("h265toYUV.YUV", "wb");
#else
	FILE * OutFile = fopen("h265toh264.h264", "wb");
#endif
	//打印ffmpeg輸出日志等級
	printf("log level %d \n", av_log_get_level());
	//設(shè)置ffmpeg輸出日志等級
	av_log_set_level(AV_LOG_INFO);
	
	while (true)
	{
		int iReadSize = fread(frame_buf, 1, 512, InFile);
		if (iReadSize <> 0)
		{
			break;
		}
		memcpy(H265Buf + H265Lenth, frame_buf, iReadSize);
		H265Lenth = H265Lenth + iReadSize;
		//獲取一幀數(shù)據(jù)
		while (true)
		{
			bool OneFrame = false;
			if (H265Lenth <> 8)
			{
				break;
			}
			for (int i = 4; i  H265Lenth - 4; i++)
			{
				//解析H265的nalu頭
				if (H265Buf[i] == 0x00 && H265Buf[i + 1] == 0x00 && H265Buf[i + 2] == 0x00 && H265Buf[i + 3] == 0x01)
				{
					h265Decoder.AddData(H265Buf, i);
					while (true)
					{
						char * pOutData = NULL;
						int OutSize = 0;
#if ISSTORAGEYUV
						//獲取H265解碼后的YUV并存文件
						if (!h265Decoder.GetYUVData(pOutData, OutSize))
						{
							break;
						}
						fwrite(pOutData, 1, OutSize, OutFile);
#else
						//獲取H265解碼frame并編碼H264存文件
						AVFrame *frame = NULL;
						frame = h265Decoder.GetData();
						if (!frame) {
							break;
						}
						frame->pts = fpts++;
						h264Encoder.encode(frame, pOutData, OutSize);
						fwrite(pOutData, 1, OutSize, OutFile);
#endif
					}
					H265Lenth = H265Lenth - i;
					memcpy(H265Buf, H265Buf + i, H265Lenth);
					OneFrame = true;
					break;
				}
			}
			if (OneFrame)
			{
				continue;
			}
			else
			{
				break;
			}
		}
	}
	if (OutFile) {
		fclose(OutFile);
		OutFile = NULL;
	}
	if (InFile) {
		fclose(InFile);
		InFile = NULL;
	}
	printf("pasing end\r\n");
	return 0;
}

2、過程分析

1、要初始化編,需要發(fā)送正確的H265分辨率格式進(jìn)行初始化

	h265Decoder.Init(480, 272);
	h264Encoder.Init(480, 272);

2、循環(huán)讀取H265文件以形成完整的H265幀(根據(jù)H265的nalu標(biāo)頭00 00 00 01判斷)

	if (H265Buf[i] == 0x00 && H265Buf[i + 1] == 0x00 && H265Buf[i + 2] == 0x00 && H265Buf[i + 3] == 0x01)

3、將H265的幀發(fā)送到H265以進(jìn)行軟件解碼

	h265Decoder.AddData(H265Buf, i);

4、要獲取由H265解碼的YUV,可以選擇保存YUV文件或?qū)⑵浒l(fā)送到H264編碼器進(jìn)行編碼并將其另存為H264文件

#if ISSTORAGEYUV
			//獲取H265解碼后的YUV并存文件
			if (!h265Decoder.GetYUVData(pOutData, OutSize))
			{
				break;
			}
			fwrite(pOutData, 1, OutSize, OutFile);
#else
			//獲取H265解碼frame并編碼H264存文件
			AVFrame *frame = NULL;
			frame = h265Decoder.GetData();
			if (!frame) {
				break;
			}
			frame->pts = fpts++;
			h264Encoder.encode(frame, pOutData, OutSize);
			fwrite(pOutData, 1, OutSize, OutFile);
#endif

3、遇到的問題

在調(diào)試過程中,調(diào)用h264_nvenc硬件編碼器時遇到錯誤。經(jīng)調(diào)查,發(fā)現(xiàn)H265解碼后的原始視頻格式為YUVJ420P。原因是來自某些視頻設(shè)備的H265視頻流,編碼前的數(shù)據(jù)是YUVJ420P,并非全部都是YUV420P。如果將此原始YUVJ420P直接發(fā)送到NVIDIA硬件編碼器,則將直接導(dǎo)致程序崩潰。經(jīng)過調(diào)查,發(fā)現(xiàn)NVIDIA不支持YUVJ420P的直接編碼,如下所示。如圖所示,僅YUV420P或YUV444P支持H264編碼。

在這里插入圖片描述

要解決此問題,只能使用ffmpeg的sws_scale將YUVJ420P轉(zhuǎn)換為YUV420P,然后將其發(fā)送到h264_nvenc硬件編碼器進(jìn)行編碼。

#if ISCHANGEFRAME
	if (frame->format == AV_PIX_FMT_YUVJ420P) {
		sws_scale(convert_ctx,frame->data, frame->linesize, 0, Height, frameYUV->data, frameYUV->linesize);
		frameYUV->format = AV_PIX_FMT_YUV420P;
		frameYUV->width = Width;
		frameYUV->height = Height;
		return frameYUV;
	}
#endif

4、補(bǔ)充

1、 libx264可以直接用264編碼YUVJ420P,而無需進(jìn)行格式轉(zhuǎn)換。

2、 YUVJ420P和YUV420P簡介

YUVJ420P的字面意思是“使用JPEG顏色范圍的YUV420P,并且像素使用的顏色的值范圍已更改。

YUV420p的像素顏色范圍是[16,235],16表示黑色,235表示白色

YUVJ420P的像素顏色范圍是[0,255]。 0表示黑色,255表示白色

FFmpeg的定義和解釋:

AV_PIX_FMT_YUV420P,   ///< planar="" yuv="" 4:2:0,="" 12bpp,="" (1="" cr="" &="" cb="" sample="" per="" 2x2="" y="" samples)="" av_pix_fmt_yuvj420p,="">< planar="" yuv="" 4:2:0,="" 12bpp,="" full="" scale="" (jpeg),="" deprecated="" in="" favor="" of="" av_pix_fmt_yuv420p="" and="" setting="" color_range="">

下載

1、測試視頻

2、 FFmpeg API H265轉(zhuǎn)碼H264源代碼

參考

1、

2、 ffmpeg nvidia硬件加速解決方案(參考博客)

3、 ffmpeg一些有關(guān)硬解碼和軟解碼的參考

4、 YUV420P和YUVJ420P簡介


本文來自本站,轉(zhuǎn)載請注明本文網(wǎng)址:
http://www.pc-fly.com/a/shenmilingyu/article-372913-1.html



溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統(tǒng)下載排行

網(wǎng)站地圖xml | 網(wǎng)站地圖html
主站蜘蛛池模板: 乌鲁木齐县| 湖州市| 金阳县| 迁西县| 五原县| 井研县| 忻州市| 乌苏市| 墨竹工卡县| 铜山县| 万源市| 宜良县| 通州市| 荔浦县| 香港 | 通许县| 开封县| 轮台县| 社会| 安塞县| 古浪县| 西林县| 盘山县| 泸州市| 枝江市| 大名县| 额敏县| 湘西| 资溪县| 蒙城县| 卢湾区| 鄂托克旗| 于田县| 湟中县| 柯坪县| 青岛市| 马公市| 永德县| 乌恰县| 榆林市| 雅安市|