<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何在RTMP協議中增加對HEVC視頻編碼格式的支持

LiveVideoStack ? 來源:互聯網 ? 作者:佚名 ? 2018-01-23 09:36 ? 次閱讀

視頻流媒體中視頻數據的傳輸占據了絕大部分的帶寬,如何提升編碼效率、減小帶寬使用、提升畫面質量,成為音視頻開發者努力的重點。HEVC編碼格式的推出為此帶來了突破點。對于直播而言,大部分推拉流協議是基于RTMP的,因此本文將主要介紹如何在RTMP協議中增加對HEVC視頻編碼格式的支持。

本文來自金山云OBG事業部投稿,是《FFmpeg從入門到出家》系列的第一篇下半部分,由LiveVideoStack審校整理,希望能讓大家對FFmpeg有更深入了解。閱讀上半部分內容請點擊【閱讀原文】。

文 / 施雪梅

4. HEVC在RTMP中的擴展

為推進HEVC視頻編碼格式在直播方案中的落地,經過CDN聯盟討論,并和主流云服務廠商達成一致,規范了HEVC在RTMP/FLV中的擴展,具體修改內容見下。

4.1 FLV規范擴展

HEVC為視頻編碼格式,因此對FLV規范的擴展,只集中在Video Tag,其它部分,無任何改動。

4.1.1 支持HEVC的VideoTagHeader

擴展后的VideoTagHeader如下圖所示(紅色字體為新增內容):

圖9. 支持HEVC的FLVTagHeader

修改點如下:

1.CodecID - 定義HEVC格式的值為12;

2.HEVCPacketType - 當CodecID == 12時,AVCPacketType為HEVCPacketType:

  • 如果HEVCPacketType為0,表示HEVCVIDEOPACKET中存放的是HEVC sequence header;

  • 如果HEVCPacketType為1,表示HEVCVIDEOPACKET中存放的是HEVC NALU;

  • 如果HEVCPacketType為2,表示HEVCVIDEPACKET中存放的是HEVC end of sequence,即HEVCDecoderConfigurationRecord;

3.CompositionTime - 當CodecID == 12時,同樣需要CompositionTime。

4.1.2 支持HEVC的VideoTagBody

當CodecID為12時,VideoTagBody中存放的就是HEVC視頻幀內容。

擴展后的VideoTagBody如下圖所示(紅色字體為HEVC新增內容):

圖10. 支持HEVC的VideoTagBody

4.2 FFmpeg中的修改

我們已在FFmpeg的各個版本上提供相關的完整修改,具體參見:https://github.com/ksvc/FFmpeg,完整patch獲取及相關說明見:https://github.com/ksvc/FFmpeg/wiki。

由第二章節的闡述可知,FLV的解復用和復用功能代碼分別在libavformt/flvdec.c和libavformat/flvenc.c中,擴展后的修改也都集中在這兩個文件。本節將在FFmpeg3.3的基礎上,說明修改的關鍵點。

4.2.1 編碼類型定義

libavformat/flv.h中按照VideoTagHeader中的CodecID定義了一組視頻編碼格式的枚舉值,擴展后的枚舉定義如下:


	

enum { FLV_CODECID_H263 = 2, FLV_CODECID_SCREEN = 3, FLV_CODECID_VP6 = 4, FLV_CODECID_VP6A = 5, FLV_CODECID_SCREEN2 = 6, FLV_CODECID_H264 = 7, FLV_CODECID_REALH263= 8, FLV_CODECID_MPEG4 = 9, FLV_CODECID_HEVC = 12,};

4.2.2 FLV demux

在解復用過程中,flv_read_packet方法是整個過程的核心,它里面完成了對每個Tag的讀取和解析。

4.1.1中提到,如果HEVCPacketType為0時,表示HEVCVIDEOPACKET中存放的是HEVC sequence header,也就是HEVCDecoderConfigurationRecord,解碼時需設置HEVCDecoderConfigurationRecord方能正確解碼。

HEVC與AVC視頻幀在FLV中的存放格式相同,所以只需在讀取Video Tag的地方增加AV_CODEC_ID_HEVC的判斷條件即可,調整后的代碼如下:


	

if (st->codecpar->codec_id == AV_CODEC_ID_AAC || st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC || st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { int type = avio_r8(s->pb); size--; if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC || st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { // sign extension int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000; pts = dts + cts; if (cts< 0) { // dts might be wrong if (!flv->wrong_dts) av_log(s, AV_LOG_WARNING, "Negative cts, previous timestamps might be wrong.\n"); flv->wrong_dts = 1; } else if (FFABS(dts - pts) > 1000*60*15) { av_log(s, AV_LOG_WARNING, "invalid timestamps %"PRId64" %"PRId64"\n", dts, pts); dts = pts = AV_NOPTS_VALUE; } } if (type == 0 &&(!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC || st->codecpar->codec_id == AV_CODEC_ID_HEVC || st->codecpar->codec_id == AV_CODEC_ID_H264)) { AVDictionaryEntry *t; if (st->codecpar->extradata) { if ((ret = flv_queue_extradata(flv, s->pb, stream_type, size)) < 0) return ret; ret = FFERROR_REDO; goto leave; } if ((ret = flv_get_extradata(s, st, size)) < 0) return ret; …… }}

AVCDecoderConfigurationRecord和HEVCDecoderConfigurationRecord都是存放在AVStream->AVCodecParameter->extradata中。

4.2.3 FLV mux

FLV mux的修改相對較多、header、packet、trailer中均有涉及。

4.2.3.1 write header

flv_write_header中主要完成了以下工作:

  1. 寫入FLV Header;

  2. 寫入Metadata;

  3. 如果音頻編碼格式為AAC,則寫入第一個Audio Tag,其AudioTagBody中存放的是AAC sequence header;

  4. 如果視頻編碼格式為AVC,則寫入第一個Video Tag,其中VideoTagBody中存放的是AVC sequence header。

同樣,當視頻編碼格式HEVC時,也要寫入第一個VideoTag,其中VideoTagBody中存放的是HEVCDecoderConfigurationRecord,修改點如下:


	

avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flagsavio_w8(pb, 0); // AVC sequence headeravio_wb24(pb, 0); // composition timeif (par->codec_id == AV_CODEC_ID_HEVC) ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);else ff_isom_write_avcc(pb, par->extradata, par->extradata_size);

ff_isom_write_hvcc的作用是將extradata轉為HEVCDecoderConfigurationRecord結構并寫入。

4.2.3.2 write packet

flv_write_packet的作用是寫入音視頻幀,其中有關寫入video數據的地方,都需要加上AV_CODEC_ID_HEVC的判斷條件,修改內容如下:


	

else if (par->codec_id == AV_CODEC_ID_HEVC ){ if (par->extradata_size> 0 && *(uint8_t*)par->extradata != 1) if ((ret = ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL)) < 0) return ret; }

ff_hevc_annexb2mp4_buf方法的作用是將Annex-B格式的HEVC視頻幀轉為HVCC格式。

AnnexB與AVCC/HVCC(ISO/IEC14496-15中所定義,通常也稱為MPEG-4格式)的區別在于參數集與幀格式,AnnexB的參數集sps、pps以NAL的形式存在碼流中(帶內傳輸),以startcode分割NAL。而HVCC 的參數集存儲在extradata中(帶外傳輸),使用NALU長度(固定字節,通常為4字節,從extradata中解析)分隔NAL。

4.2.3.3 write trailer

結束時需要寫入HEVC end of sequence,其格式與AVC end of sequence相同,直接復用即可,flv_write_trailer的修改內容如下:


	

if (par->codec_type == AVMEDIA_TYPE_VIDEO && (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_MPEG4)) put_avc_eos_tag(pb, sc->last_ts);?

5. 結束語

本文簡單介紹了如何在FFmpeg中擴展rtmp協議對HEVC編碼格式的支持,而要將HEVC應用于直播整體方案,除推流端和播放端要提供相應能力外,源站、CDN、轉碼服務同樣都需要提供這種能力。金山云的所有視頻服務中,已完全支持HEVC視頻編碼格式,歡迎大家使用。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    4996

    文章

    18380

    瀏覽量

    290479
  • 視頻編碼
    +關注

    關注

    2

    文章

    111

    瀏覽量

    20893
  • 視頻流
    +關注

    關注

    0

    文章

    16

    瀏覽量

    10299

原文標題:FFmpeg代碼導讀——HEVC在RTMP中的擴展

文章出處:【微信號:livevideostack,微信公眾號:LiveVideoStack】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    高清模擬視頻采集與H.264編碼?體化采集卡LCC261數據手冊

    LCC261是靈卡技術研發的?款高清模擬視頻采集與H.264編碼?體化的采集卡。輸入接口采用BNC接頭,支持AHD/TVI/CVI/ CVBS多種格式標準,最高
    發表于 04-12 14:40 ?0次下載

    視頻更便于傳輸,智能家居中的HEVC芯片

    電子發燒友網報道(文/黃山明)在智能家居中,視頻壓縮處理非常關鍵,視頻壓縮處理芯片通常采用先進的視頻壓縮標準,如H.264/AVC或H.265/HEVC。這些標準能夠將
    的頭像 發表于 02-22 00:17 ?2723次閱讀

    格式支持:無縫高清矩陣切換器的靈活應用

    無縫高清矩陣切換器的多格式支持是其靈活應用的關鍵之一。通過多格式支持,切換器能夠滿足不同設備、不同應用場景和不同傳輸協議的需求,實現
    的頭像 發表于 01-24 14:33 ?169次閱讀

    車載播放器怎么選擇格式

    選購車載播放器時,格式選擇是一個關鍵的因素。不同的格式支持不同的音頻和視頻文件類型,因此在購買之前了解和理解各種格式是非常重要的。下面將為您
    的頭像 發表于 01-05 16:36 ?709次閱讀

    Enhanced-RTMP協議如何支持H.265呢?

    準確的說,RTMP是傳輸協議,傳輸協議內部的封裝是flv格式,其實我們所說的支持H.265,是在flv封裝
    的頭像 發表于 01-03 09:15 ?491次閱讀

    iPhone將增加對RCS消息的支持

    根據9to5Mac的一份報告(9to5mac.com/2023/11/16/apple-rcs-coming-to-iphone/),蘋果表示,2024年,iPhone將增加對RCS消息的支持
    的頭像 發表于 11-20 16:55 ?492次閱讀

    什么是m3u8格式

    m3u8是什么格式?m3u8是蘋果公司推出的視頻播放標準,是m3u的一種,只是編碼格式采用的是UTF-8。 使用m3u8格式文件主要因為可以
    的頭像 發表于 10-31 15:59 ?1.5w次閱讀
    什么是m3u8<b class='flag-5'>格式</b>

    HarmonyOS音視頻開發概述

    類型 說明 surface_yuv 輸入surface攜帶的是raw data。 surface_es 輸入surface攜帶的是ES data。 支持的音視頻
    發表于 10-17 16:39

    什么是m3u8格式

    m3u8是什么格式?m3u8是蘋果公司推出的視頻播放標準,是m3u的一種,只是編碼格式采用的是UTF-8。 使用m3u8格式文件主要因為可以
    的頭像 發表于 10-17 11:24 ?4.9w次閱讀
    什么是m3u8<b class='flag-5'>格式</b>

    【悟空派H3開發板免費體驗】03.在悟空派上搭建RTMP服務器并實現RTSP轉RTMP

    ,那么服務能力就更加強悍了,而且也可以實現將視頻流保留下來。 搭建RTMP服務器 之前曾再其他帖子里介紹過SRS的服務器搭建,這次決定采用nginx來進行服務器的搭建,SRS的優勢在于易部署
    發表于 09-27 13:40

    NGCodec硬件HEVC編碼用戶指南

    電子發燒友網站提供《NGCodec硬件HEVC編碼用戶指南.pdf》資料免費下載
    發表于 09-13 10:26 ?0次下載
    NGCodec硬件<b class='flag-5'>HEVC</b><b class='flag-5'>編碼</b>用戶指南

    訊維網絡解碼矩陣:為媒體內容制作提供全方位支持!

    。支持多種視頻格式和分辨率,滿足不同制作需求。 網絡適應性:支持多種網絡傳輸協議,如RTMP、HLS等,能夠適應不同的網絡環境和帶寬條件,保
    的頭像 發表于 09-04 11:32 ?264次閱讀
    訊維網絡解碼矩陣:為媒體內容制作提供全方位<b class='flag-5'>支持</b>!

    【風火輪YY3568開發板免費體驗】FFMPEG的軟編碼、RTMP直播服務、以及板上直播服務器搭建

    通過RTMP協議發送就好,因為我們的格式本身就是AAC -vcodec copy 這個和音頻流一樣,不過這里肯定代表的是視頻流,格式也本身就
    發表于 08-29 09:49

    視頻編碼器的軟件功能組成

    等。 聲明:部分內容及圖片來源于網絡,如有侵權請聯系刪除。 視頻編碼器的軟件一般包括如下幾個部分:操作系統、Web服務、CGI應用、編碼壓縮程序、網絡傳輸協議、
    的頭像 發表于 08-17 10:21 ?365次閱讀
    <b class='flag-5'>視頻</b><b class='flag-5'>編碼</b>器的軟件功能組成

    何在nice協處理器案例的基礎上增加對擴展指令rs2的使用?

    在官方提供的nice 協處理案例 僅使用了rs1 和 rd,請問如何修改以下C代碼來增加對rs2的使用
    發表于 08-11 07:48
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>