Last active
July 3, 2024 17:07
-
-
Save XueshiQiao/c50fd1f088d431ceb1f59bd4ec40c6d7 to your computer and use it in GitHub Desktop.
FFmpeg v3.3 支持 FLV + HEVC 的 patch,引用自:https://github.com/CDN-Union/H265/blob/master/Code/flv265patch_from_kingsoft.7z
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 88287f270df660645b3f6c813ab3fd7ad522e64c Mon Sep 17 00:00:00 2001 | |
From: KSC-VBU-SR <[email protected]> | |
Date: Wed, 14 Jun 2017 21:33:54 +0800 | |
Subject: [PATCH] The RTMP protocol extensions for H.265/HEVC | |
--- | |
libavformat/flv.h | 1 + | |
libavformat/flvdec.c | 16 +++++++++++++--- | |
libavformat/flvenc.c | 29 ++++++++++++++++++++--------- | |
3 files changed, 34 insertions(+), 12 deletions(-) | |
diff --git a/libavformat/flv.h b/libavformat/flv.h | |
index df5ce3d..089bc76 100644 | |
--- a/libavformat/flv.h | |
+++ b/libavformat/flv.h | |
@@ -109,6 +109,7 @@ enum { | |
FLV_CODECID_H264 = 7, | |
FLV_CODECID_REALH263= 8, | |
FLV_CODECID_MPEG4 = 9, | |
+ FLV_CODECID_HEVC = 12, | |
}; | |
enum { | |
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c | |
index 94c9e28..8adae2f 100644 | |
--- a/libavformat/flvdec.c | |
+++ b/libavformat/flvdec.c | |
@@ -36,6 +36,7 @@ | |
#include "internal.h" | |
#include "avio_internal.h" | |
#include "flv.h" | |
+#include "hevc.h" | |
#define VALIDATE_INDEX_TS_THRESH 2500 | |
@@ -291,6 +292,8 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags) | |
return vpar->codec_id == AV_CODEC_ID_VP6A; | |
case FLV_CODECID_H264: | |
return vpar->codec_id == AV_CODEC_ID_H264; | |
+ case FLV_CODECID_HEVC: | |
+ return vpar->codec_id == AV_CODEC_ID_HEVC; | |
default: | |
return vpar->codec_tag == flv_codecid; | |
} | |
@@ -340,6 +343,11 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, | |
par->codec_id = AV_CODEC_ID_MPEG4; | |
ret = 3; | |
break; | |
+ case FLV_CODECID_HEVC: | |
+ par->codec_id = AV_CODEC_ID_HEVC; | |
+ vstream->need_parsing = AVSTREAM_PARSE_NONE; | |
+ ret = 3; // not 4, reading packet type will consume one byte | |
+ break; | |
default: | |
avpriv_request_sample(s, "Video codec (%x)", flv_codecid); | |
par->codec_tag = flv_codecid; | |
@@ -1142,10 +1150,12 @@ retry_duration: | |
if (st->codecpar->codec_id == AV_CODEC_ID_AAC || | |
st->codecpar->codec_id == AV_CODEC_ID_H264 || | |
- st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { | |
+ st->codecpar->codec_id == AV_CODEC_ID_MPEG4 || | |
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC) { | |
int type = avio_r8(s->pb); | |
size--; | |
- if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { | |
+ if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4 | |
+ || st->codecpar->codec_id == AV_CODEC_ID_HEVC) { | |
// sign extension | |
int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000; | |
pts = dts + cts; | |
@@ -1161,7 +1171,7 @@ retry_duration: | |
} | |
} | |
if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC || | |
- st->codecpar->codec_id == AV_CODEC_ID_H264)) { | |
+ st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC)) { | |
AVDictionaryEntry *t; | |
if (st->codecpar->extradata) { | |
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c | |
index 899b07e..eb955e5 100644 | |
--- a/libavformat/flvenc.c | |
+++ b/libavformat/flvenc.c | |
@@ -34,6 +34,7 @@ | |
#include "libavutil/opt.h" | |
#include "libavcodec/put_bits.h" | |
#include "libavcodec/aacenctab.h" | |
+#include "hevc.h" | |
static const AVCodecTag flv_video_codec_ids[] = { | |
@@ -46,6 +47,7 @@ static const AVCodecTag flv_video_codec_ids[] = { | |
{ AV_CODEC_ID_VP6, FLV_CODECID_VP6 }, | |
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A }, | |
{ AV_CODEC_ID_H264, FLV_CODECID_H264 }, | |
+ { AV_CODEC_ID_HEVC, FLV_CODECID_HEVC }, | |
{ AV_CODEC_ID_NONE, 0 } | |
}; | |
@@ -486,7 +488,7 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par) { | |
FLVContext *flv = s->priv_data; | |
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264 | |
- || par->codec_id == AV_CODEC_ID_MPEG4) { | |
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) { | |
int64_t pos; | |
avio_w8(pb, | |
par->codec_type == AVMEDIA_TYPE_VIDEO ? | |
@@ -533,7 +535,11 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par) { | |
avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags | |
avio_w8(pb, 0); // AVC sequence header | |
avio_wb24(pb, 0); // composition time | |
- ff_isom_write_avcc(pb, par->extradata, par->extradata_size); | |
+ if (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); | |
+ } | |
} | |
data_size = avio_tell(pb) - pos; | |
avio_seek(pb, -data_size - 10, SEEK_CUR); | |
@@ -836,7 +842,7 @@ end: | |
AVCodecParameters *par = s->streams[i]->codecpar; | |
FLVStreamContext *sc = s->streams[i]->priv_data; | |
if (par->codec_type == AVMEDIA_TYPE_VIDEO && | |
- (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4)) | |
+ (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)) | |
put_avc_eos_tag(pb, sc->last_ts); | |
} | |
} | |
@@ -880,15 +886,16 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) | |
int64_t cur_offset = avio_tell(pb); | |
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A || | |
- par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC) | |
+ par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC) { | |
flags_size = 2; | |
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) | |
+ } else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) { | |
flags_size = 5; | |
- else | |
+ } else { | |
flags_size = 1; | |
+ } | |
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264 | |
- || par->codec_id == AV_CODEC_ID_MPEG4) { | |
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) { | |
int side_size = 0; | |
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); | |
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) { | |
@@ -951,6 +958,10 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) | |
if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1) | |
if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0) | |
return ret; | |
+ } 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; | |
} else if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 && | |
(AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { | |
if (!s->streams[pkt->stream_index]->nb_frames) { | |
@@ -1021,9 +1032,9 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) | |
else | |
avio_w8(pb, ((FFALIGN(par->width, 16) - par->width) << 4) | | |
(FFALIGN(par->height, 16) - par->height)); | |
- } else if (par->codec_id == AV_CODEC_ID_AAC) | |
+ } else if (par->codec_id == AV_CODEC_ID_AAC) { | |
avio_w8(pb, 1); // AAC raw | |
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) { | |
+ } else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) { | |
avio_w8(pb, 1); // AVC NALU | |
avio_wb24(pb, pkt->pts - pkt->dts); | |
} | |
-- | |
1.7.9.5 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment