FMUSER Wirless Transmit Video And Audio More Easier !

[email protected] WhatsApp +8618078869184
Language

    How to implement RTSP H.265 (HEVC) flow transfer RTMP H.265 (HEVC) to stream flow to the RTMP streaming server to realize Internet CDN live

     

    "Speaking RTSP H.265 (HEVC) to RTMP, first of all, I have to know about the RTMP protocol. The RTMP protocol is originally defined without H.265, and the domestic CDN manufacturers jointly developed an RTMP / FLV extension h. .265 (HEVC) program, this is to adapt to the domestic video Internet Expressway, the current domestic developers are basically done according to this extension agreement. The RTMP header information package does not define the HEVC. We use the CDN League's HEVC extension standard to define the HEVC's videotagheader as 12. See the figure below for details: RTMP stream The protocol layer has been determined that the key problem with the next step is to implement the RTMP H.265 (HEVC) push module. In the video push, we can choose FFMPEG or EasyRTMP, both can support the H.265 (HEVC) RTMP stream. But ffmpeg is a need to do some small modifications and recompile: Step 1: We have improved on the basis of the H264 package to support the HEVC header package, and the HEVC head has SPS PPS VPS, and we refer to FFmpeg's HevcDecoderConfigurationRecord structure package Metadata, this structure code Typedef struct hvcnalunitArray { 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 parallex; Uint8_t chromaformat; Uint8_t BitDepthlumaminus8; Uint8_t BitDepthromaminus8; UINT16_T AVGFRAMERATE; Uint8_t constantframerate; UINT8_T NUMTEMPORALLAYERS; Uint8_t temporalidnested; Uint8_t lengthsizeminusone; Uint8_t numofarrays; HVCCNALUNITARRAY * Array; HevcdecoderConfigurationRecord; 123456789101112131415161718192021222324252627282930 This structure is initialized with reference ffmeg as follows: // Need to note is that other parameters of this structure we can actually care // We only need to fill in the HEVC's VPS, SPS, and PPS information in the HVCCNALUNITARRAY array. Static void HVCC_INIT (HevcdecoderConfigurationRecord * HVCC) { Memset (HVCC, 0, SIZEOF (HevcDecoderConfigurationRecord); HVCC-> configurationVersion = 1; HVCC-> Length = 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 = 0xffffff; HVCC-> general_constraint_indicator_flags = 0xfffffffffff; / * * 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; } 12345678910111213141516171819202122 Finally, after filling the metadata information, we also need to modify it when sending frame data, change the tag head of I frame to 12, and the p frame tag is constant, set to 1, as shown below 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; 12345678910111213141516171819202122232425262728 EasyRTMP can directly support the H.265 (HEVC) stream, Easyrtmp is a set of simplicity, functional, efficient and stable RTMP function components, supporting most RTMP streaming media servers on the market, including Wowza, Red5, NGNIX_RTMP, CRTMPSERVER and other mainstream RTMP servers can be perfectly used in live demand, mobile phone live, live broadcast, live broadcast, live broadcast, classroom broadcast, etc.! GitHub Address: https://github.com/easydss/easyrtmp RTSP draws At present, the two sets of relatively good RTSP protocols in the market are the Live555, one is FFMPEG, two sets of frames have a thousand autumn, each has a series of applications: Live555: Very old style RTSP framework, more than ten years, is still iterative and maintenance, the author Ross also uses this, open source + commercial operation, everyone is well known, the RTSP draw is Live555 Ffmpeg: ffmpeg is not more useful. At present, most of the domestic players are used in this, and the RTSP module is self-written, and the compatibility is also very good; If the RTSP process protocol is not very familiar, and for FFMPEG's transformation or compiling is a very time-consuming event, and there is not high success rate, so you can use easyRTSPCLIENT: https: //github.com/tsingsee/ EasyRTSPClient, optimized and developed based on Live555, greatly simplifies the calling process of the RTSP protocol, especially if you don't have to care about RTSP DESCRIBE, SETUP, and PLAY process, direct callback, you can get the corresponding error message and data information. Includes data information such as SPS, PPS, VPS, such as H.264 / H.265; EasyRTSPLIVE The basic components described above are all components, and how can they connect the entire process to a complete set of RTSP pull-up RTMP streams, still need a lot of things, so we integrate an EasyRTSPLIVE project. It is very convenient to connect the entire process, supporting H.264, H.265 stream RTSP pull RTMP push: https: //github.com/easydarwin/easyrtsplive #define _crtdbg_map_alloc #include #ifdef _win32 #include "" windows.h "" #ELSE #include #include #ENDIF #include "getopt.h" " #include #include #include #include // # include #include #include "EasyRTSPClientApi.h" " #include "Easyrtmpapi.h" " #include "INI.H" " #include "TRACE.H" " #ifdef _win32 #pragma Comment (Lib, "LibeasyrtSpClient.lib") #pragma comment (Lib, "Libeasyrtmp.Lib") #ENDIF #define max_rtmp_URL_LEN 256 #define buffer_size 1024 * 1024 #define max_channel_index 1024 #define conf_file_path "" config.ini "" Typedef struct _channel_cfg_struct_t { Int ChannelID; Int option; CHAR CHANELNAME [64]; Char srcrtspaddr [512]; Char DestMpAddr [512]; } _Channel_cfg; Typedef struct _rtmp_pusher_struct_t { Easy_Handle Rtmphandle; Unsigned int u32audiocodec; Unsigned int u32audiosample; Unsigned int U32audiochannel; } _RTMP_PUSHER; Typedef struct _channel_info_struct_t { _Channel_cfg fcfginfo; _RTMP_PUSHER FPUSHERINFO; Easy_handle fnvshandle; File * floghandle; Bool FhavePrintKeyInfo; EASY_MEDIA_INFO_T fmediaInfo; } _CHANNEL_INFO; Static std :: list <_channel_info *> gchannelinfolist; INT __EASYRTMP_CALLBACK (int _frametype, char * pbuf, easy_rtmp_state_t _state, void * _userptr) { _Channel_INFO * PCHANNEL = (_Channel_INFO *) _ Userptr; Switch (_State) { Case Easy_rtmp_State_Connecting: Trace_log (PChannel-> Floghandle, "Connecting ... \ n" "); Break; Case Easy_rtmp_State_Connected: Trace_log (PChannel-> Floghandle, "Connected \ n"); Break; Case Easy_rtmp_State_Connect_failed: Trace_log (PChannel-> Floghandle, "Connect Failed \ N"); Break; Case Easy_rtmp_State_Connect_Abort: Trace_log (PChannel-> Floghandle, "" Connect Abort \ n ""); Break; Case Easy_rtmp_State_disconnected: Trace_log (PChannel-> FlogHandle, "Disconnect. \ N"); Break; DEFAULT: Break; } Return 0; } / * EasyrtSpClient Callback * / INT Easy_apicall __rtspsourceCallback (int _chid, void * _chptr, int _mediatype, char * pbuf, easy_frame_info * frameinfo) { IF (NULL! = frameInfo) { IF (frameInfo-> height == 1088) frameinfo-> height = 1080; Else if (frameInfo-> height == 544) frameinfo-> height = 540; } Easy_bool Bret = 0; INT IRET = 0; Be _Channel_INFO * PCHANNEL = (_Channel_Info *) _CHPTR; IF (_mediatype == easy_SDK_VIDEO_FRAME_FLAG) { IF (FrameInfo && Frameinfo-> Length) { IF (frameInfo-> type == easy_sdk_video_frame_i) { IF (PChannel-> fpusherinfo.rtmphandle == 0) { PCHANNEL-> fpusherinfo.rtmphandle = easyrtmp_create (); IF (PChannel-> fpusherinfo.rtmphandle == null) { Trace_log (PChannel-> Floghandle, "Fail to RTMP CREATE FAILED ... \ N" "); Return -1; } EasyRTMP_SETCALLBACK (PChannel-> fpusherinfo.rtmphandle, __easyrtmp_callback, pchannel); Bret = easyrtmp_connect (pchannel-> fpusherinfo.rtmphandle, pchannel-> fcfginfo.destrtmpaddr); IF (! bret) { Trace_log (PChannel-> Floghandle, "Fail to RTMP Connect Failed ... \ n" "); } Easy_Media_Info_t MediaInfo; MEMSET (& MediaInfo, 0, Sizeof (easy_media_info_t)); MediaInfo.u32video = pchannel-> fmediaInfo.u32videofps; MediaInfo.u32audiosample = 8000; Iret = easyrtmp_initmetadata (PChannel-> fpusherinfo.rtmphandle, & mediaInfo, 1024); IF (IRET <0) { Trace_log (PChannel-> Floghandle, "Fail to Init Metadata ... \ n" "); } } Easy_AV_Frame Avframe MEMSET (& Avframe, 0, Sizeof (easy_av_frame); Avframe.u32avframeflag = easy_SDK_VIDEO_FRAME_FLAG; Avframe.u32avframelen = frameinfo-> length; Avframe.pbuffer = (unsigned char *) PBUF; Avframe.u32vframetype = easy_SDK_VIDEO_FRAME_I; //AVFrame.u32timestampsec = frameinfo-> timestamp_sec; //AVFrame.u32timestampusec = frameinfo-> timestamp_usec; // Iret = easyrtmp_sendpacket (pchannel-> fpusherinfo.rtmphandle, & avframe); IF (IRET <0) { Trace_log (PChannel-> Floghandle, "" Fail to Send H264 Packet (I-Frame) ... \ n ""); } Else { IF (! PChannel-> FhavePrintKeyInfo) { Trace_log (PChannel-> Floghandle, "I \ n" "); PCHANNEL-> FHAVEPRINTKEYINFO = TRUE; } } } Else { IF (PChannel-> fpusherinfo.rtmphandle) { Easy_AV_Frame Avframe MEMSET (& Avframe, 0, Sizeof (easy_av_frame); Avframe.u32avframeflag = easy_SDK_VIDEO_FRAME_FLAG; Avframel.u32avframelen = frameinfo-> length-4; Avframe.pbuffer = (unsigned char *) PBUF + 4; Avframe.u32vframetype = easy_SDK_VIDEO_FRAME_P; //AVFrame.u32timestampsec = frameinfo-> timestamp_sec; //AVFrame.u32timestampusec = frameinfo-> timestamp_usec; Iret = easyrtmp_sendpacket (pchannel-> fpusherinfo.rtmphandle, & avframe); IF (IRET <0) { Trace_log (pchannel-> floghandle, "" Fail to Send H264 Packet (P-FRAME) ... \ N ""); } Else { IF (! PChannel-> FhavePrintKeyInfo) { Trace_log (PChannel-> Floghandle, "P \ n" "); } } } } } } Else IF (_MEDiaType == easy_sdk_media_info_flag) { IF (PBUF! = NULL) { Easy_Media_Info_t MediaInfo; Memset (PChannel-> fmediaInfo), 0x00, sizeof (easy_media_info_t); Memcpy (& (PChannel-> fmediaInfo), PBUF, SIZEOF (EASY_MEDIA_INFO_T); TRACE_LOG (PCHANNEL-> FlogHandle, "" RTSP Describe Get Media Info: Video:% U FPS:% U Audio:% U Channel:% u SampleRate:% U \ N ", pChannel-> fMediainfo.u32VideoCodec, pChannel-> fMediainfo.u32VideoFps, pChannel-> fMediainfo.u32AudioCodec, pChannel-> fMediainfo.u32AudioChannel, pChannel-> fMediainfo.u32AudioSamplerate); } } Return 0; } BOOL INITCFGINFO (VOID) { INT i = 0; GChannelInfolist.clear (); For (i = 0; i fcfginfo.channelid = i; PCHANNELINFO-> FhavePrintKeyinfo = FALSE; Sprintf (pchannelinfo-> fcfginfo.channelname, "" CHANNEL% D ", i); STRCPY (PChannelInfo-> fcfginfo.srcrtspaddr, GetIniKeystring (pchannelinfo-> fcfginfo.channelname, "RTSP", conf_file_path); STRCPY (PChannelInfo-> fcfginfo.destrtmpaddr, GetInikeystring

     

     

     

     

    List all Question

    Nickname

    Email

    Questions

    Our other product:

    Professional FM Radio Station Equipment Package

     



     

    Hotel IPTV Solution

     


      Enter email  to get a surprise

      fmuser.org

      es.fmuser.org
      it.fmuser.org
      fr.fmuser.org
      de.fmuser.org
      af.fmuser.org ->Afrikaans
      sq.fmuser.org ->Albanian
      ar.fmuser.org ->Arabic
      hy.fmuser.org ->Armenian
      az.fmuser.org ->Azerbaijani
      eu.fmuser.org ->Basque
      be.fmuser.org ->Belarusian
      bg.fmuser.org ->Bulgarian
      ca.fmuser.org ->Catalan
      zh-CN.fmuser.org ->Chinese (Simplified)
      zh-TW.fmuser.org ->Chinese (Traditional)
      hr.fmuser.org ->Croatian
      cs.fmuser.org ->Czech
      da.fmuser.org ->Danish
      nl.fmuser.org ->Dutch
      et.fmuser.org ->Estonian
      tl.fmuser.org ->Filipino
      fi.fmuser.org ->Finnish
      fr.fmuser.org ->French
      gl.fmuser.org ->Galician
      ka.fmuser.org ->Georgian
      de.fmuser.org ->German
      el.fmuser.org ->Greek
      ht.fmuser.org ->Haitian Creole
      iw.fmuser.org ->Hebrew
      hi.fmuser.org ->Hindi
      hu.fmuser.org ->Hungarian
      is.fmuser.org ->Icelandic
      id.fmuser.org ->Indonesian
      ga.fmuser.org ->Irish
      it.fmuser.org ->Italian
      ja.fmuser.org ->Japanese
      ko.fmuser.org ->Korean
      lv.fmuser.org ->Latvian
      lt.fmuser.org ->Lithuanian
      mk.fmuser.org ->Macedonian
      ms.fmuser.org ->Malay
      mt.fmuser.org ->Maltese
      no.fmuser.org ->Norwegian
      fa.fmuser.org ->Persian
      pl.fmuser.org ->Polish
      pt.fmuser.org ->Portuguese
      ro.fmuser.org ->Romanian
      ru.fmuser.org ->Russian
      sr.fmuser.org ->Serbian
      sk.fmuser.org ->Slovak
      sl.fmuser.org ->Slovenian
      es.fmuser.org ->Spanish
      sw.fmuser.org ->Swahili
      sv.fmuser.org ->Swedish
      th.fmuser.org ->Thai
      tr.fmuser.org ->Turkish
      uk.fmuser.org ->Ukrainian
      ur.fmuser.org ->Urdu
      vi.fmuser.org ->Vietnamese
      cy.fmuser.org ->Welsh
      yi.fmuser.org ->Yiddish

       
  •  

    FMUSER Wirless Transmit Video And Audio More Easier !

  • Contact

    Address:
    No.305 Room HuiLan Building No.273 Huanpu Road Guangzhou China 510620

    E-mail:
    [email protected]

    Tel / WhatApps:
    +8618078869184

  • Categories

  • Newsletter

    FIRST OR FULL NAME

    E-mail

  • paypal solution  Western UnionBank OF China
    E-mail:[email protected]   WhatsApp:+8618078869184   Skype:sky198710021 Chat with me
    Copyright 2006-2020 Powered By www.fmuser.org

    Contact Us