Live Web page push push RTMP stream components EasyRTM extended support HEVC (H265)

Disclaimer: This article is EasyNVR technical team of the original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/EasyNVR/article/details/90597942

demand analysis

Most of the Internet currently on the market are based on live H.264 compression, but with the advent of the era of large-screen and high-definition era, people are no longer satisfied with VGA, CIF resolution of this small, replaced 720P, 1080P , 4K-quality video transmission, although the basis of the bandwidth of our country has been rising, but under the prevailing circumstances, or high-definition video transmission bandwidth traffic is not enough, and there is the high cost of a traffic situation. H.265 arrival of the era, not only can reduce the rate and can support the side edge broadcast video.

Here we will describe in detail how to achieve EasyRTMP support H265 push.

Although there are many online EasyRTMP implementation supports data h265 push, but are different in detail, there is no official update tag support for HEVC (H265, hereinafter collectively referred to as HEVC), so quite a few detours in the process of implementation. Finally, in the majority of users and ffmpeg with the help of code, I realized the push HEVC video frame data by EasyRTMP to EasyDSS, I will process the following detailed record for wide achieve your reference:

First, extend HEVC standard CDN Union

Before, RTMP header information package and not the definition HEVC, we use CDN Union HEVC standard extension of HEVC will VideoTagHeader defined as 12, see the figure below:
EasyRTMP

Then, to improve the package on the basis of H264, in order to support the head of the package HEVC

We H264 package on the basis of improved to support the package HEVC head, and head has HEVC
SPS PPS VPS, we refer to the HEVCDecoderConfigurationRecord ffmpeg encapsulated metadata structure, the structure code is as follows:

typedef struct HVCCNALUnitArray {
uint8_t  array_completeness;
uint8_t  NAL_unit_type;
uint16_t numNalus;
uint16_t *nalUnitLength;
uint8_t  **nalUnit;
} HVCCNALUnitArray;

typedef struct HEVCDecoderConfigurationRecord {
uint8_t  configurationVersion;
uint8_t  general_profile_space;
uint8_t  general_tier_flag;
uint8_t  general_profile_idc;
uint32_t general_profile_compatibility_flags;
uint64_t general_constraint_indicator_flags;
uint8_t  general_level_idc;
uint16_t min_spatial_segmentation_idc;
uint8_t  parallelismType;
uint8_t  chromaFormat;
uint8_t  bitDepthLumaMinus8;
uint8_t  bitDepthChromaMinus8;
uint16_t avgFrameRate;
uint8_t  constantFrameRate;
uint8_t  numTemporalLayers;
uint8_t  temporalIdNested;
uint8_t  lengthSizeMinusOne;
uint8_t  numOfArrays;
HVCCNALUnitArray *array;
} HEVCDecoderConfigurationRecord;

Reference ffmeg initialize the following structure:

static void hvcc_init(HEVCDecoderConfigurationRecord *hvcc)
{
memset(hvcc, 0, sizeof(HEVCDecoderConfigurationRecord));
hvcc->configurationVersion = 1;
hvcc->lengthSizeMinusOne   = 3; // 4 bytes

/*
 * The following fields have all their valid bits set by default,
 * the ProfileTierLevel parsing code will unset them when needed.
 */
hvcc->general_profile_compatibility_flags = 0xffffffff;
hvcc->general_constraint_indicator_flags  = 0xffffffffffff;

/*
 * Initialize this field with an invalid value which can be used to detect
 * whether we didn't see any VUI (in which case it should be reset to zero).
 */
hvcc->min_spatial_segmentation_idc = MAX_SPATIAL_SEGMENTATION + 1;
}

Note that: the structure of other parameters that we can actually do not particularly care about, we only need to HEVC HVCCNALUnitArray array of VPS, SPS and PPS information can fill.

Finally, modification of the transmitted frame data

Metadata fill information, we need to do at the time of transmitting data about the modified frame, the I frame into a tag header 12, P frame tag unchanged, can be set to 1, as shown in the following code:

int i = 0;
if(bIsKeyFrame)
{
	//body[i++] = 0x17;// 2:Pframe  7:AVC
	body[i++] = 	 (m_metadata.nVideoCodec  == FLV_CODECID_HEVC) ? 0x1C:0x17;// 1:Iframe  7:AVC 12:HEVC

	if (m_bWaitingKeyFrame)
	{
		m_bWaitingKeyFrame = false;
	}
}
else
{
	//body[i++] = 0x27;// 2:Pframe  7:AVC
	body[i++] = 	 (m_metadata.nVideoCodec  == FLV_CODECID_HEVC) ? 0x2C:0x27;// 1:Iframe  7:AVC 12:HEVC
}
body[i++] = 0x01;// AVC NALU
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;

// NALU size
body[i++] = size>>24;
body[i++] = size>>16;
body[i++] = size>>8;
body[i++] = size&0xff;

EasyRTMP plug flow

EasyRTMP is a simple call, functional, efficient and stable operation of RTMP functional components, after years of combat and operational lines to build, support RTMP push reconnection, a ring buffer, intelligent frame loss, network event callback, supports Windows, Linux , arm (hisiv100 / hisiv200 / hisiv300 / hisiv400 / etc ...), Android, iOS platform to support the market most of RTMP streaming media server, including Wowza, Red5, ngnix_rtmp, crtmpserver other mainstream RTMP servers, perfectly used in various live demand trades, the phone live desktop live, live cameras, etc., live classroom! (See blue rhinoceros official website: http://open.tsingsee.com/ )
tsingsee

Guess you like

Origin blog.csdn.net/EasyNVR/article/details/90597942