Skip to content

Commit

Permalink
feat(external): flv support hevc
Browse files Browse the repository at this point in the history
Signed-off-by: pingkai <pingkai010@gmail.com>
  • Loading branch information
pingkai committed Feb 12, 2020
1 parent d43a225 commit 6180d52
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 10 deletions.
23 changes: 13 additions & 10 deletions external/build_external.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,23 @@ PATH=$PATH:${BUILD_TOOLS_DIR}
source ../build_tools/utils.sh
source user_env.sh

function patch_ffmpeg() {

cd ${FFMPEG_SOURCE_DIR}
git am ../../contribute/ffmpeg/0001-chore-win32-fix-not-find-openssl-1.1.1.patch

function git_am_patch() {
git am $1
if [ $? -ne 0 ]; then
print_warning "patch error, may be patched"
git am --abort
return 0;
fi
git am ../../contribute/ffmpeg/0002-chore-avformat-change-MAX_PES_PAYLOAD-to-5M.patch
git am ../../contribute/ffmpeg/0003-chore-libavformat-exoport-some-functions.patch
git am ../../contribute/ffmpeg/0004-chore-fix-Linux-build.patch
git am ../../contribute/ffmpeg/0005-chore-disable-libdav1d-check.patch
}

function patch_ffmpeg() {

cd ${FFMPEG_SOURCE_DIR}
git_am_patch ../../contribute/ffmpeg/0001-chore-win32-fix-not-find-openssl-1.1.1.patch
git_am_patch ../../contribute/ffmpeg/0002-chore-avformat-change-MAX_PES_PAYLOAD-to-5M.patch
git_am_patch ../../contribute/ffmpeg/0003-chore-libavformat-exoport-some-functions.patch
git_am_patch ../../contribute/ffmpeg/0004-chore-fix-Linux-build.patch
git_am_patch ../../contribute/ffmpeg/0005-chore-disable-libdav1d-check.patch
git_am_patch ../../contribute/ffmpeg/0006-flv-add-extensions-for-H.265-HEVC.patch
}

function load_source() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
From df6c3a9541f2d834fdd1f6bb14e18c12e5994d1f Mon Sep 17 00:00:00 2001
From: pingkai <pingkai010@gmail.com>
Date: Wed, 12 Feb 2020 11:50:26 +0800
Subject: [PATCH 6/6] flv: add extensions for H.265/HEVC

form https://github.com/ksvc/FFmpeg/commit/e40fcb1113cb1c93c48b8ef74b8aec6437f23d84.patch

Signed-off-by: pingkai <pingkai010@gmail.com>
---
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 3571b90279..e776555a96 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -110,6 +110,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 b531a39adc..4835b1e75f 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -37,6 +37,7 @@
#include "internal.h"
#include "avio_internal.h"
#include "flv.h"
+#include "hevc.h"

#define VALIDATE_INDEX_TS_THRESH 2500

@@ -319,6 +320,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;
}
@@ -368,6 +371,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;
@@ -1223,7 +1231,8 @@ 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--;

@@ -1232,7 +1241,8 @@ retry_duration:
goto leave;
}

- 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;
@@ -1248,7 +1258,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 fb1dede7ae..a62f7008bf 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 }
};

@@ -491,7 +493,7 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
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 ?
@@ -537,7 +539,11 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
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);
@@ -847,7 +853,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);
}
}
@@ -896,15 +902,16 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
}

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))) {
@@ -967,6 +974,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) {
@@ -1036,9 +1047,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);
}
--
2.14.1

0 comments on commit 6180d52

Please sign in to comment.