Skip to content

Commit

Permalink
Add flv+hevc support
Browse files Browse the repository at this point in the history
  • Loading branch information
pengbins committed Jun 29, 2022
1 parent 7407f42 commit 0a8325b
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 9 deletions.
8 changes: 1 addition & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
name: Build FFmpeg

on:
push:
paths-ignore:
- '**.md'
- 'LICENSE'
workflow_dispatch:
inputs:
doRelease:
Expand All @@ -17,8 +13,6 @@ on:
type: boolean
default: false
required: false
schedule:
- cron: '0 12 * * *'

env:
DOCKER_BUILDKIT: 1
Expand Down Expand Up @@ -141,7 +135,7 @@ jobs:
fail-fast: false
matrix:
target: [win64,linux64]
variant: [gpl,lgpl,gpl 4.4,gpl 5.0,lgpl 4.4,lgpl 5.0,gpl-shared,lgpl-shared,gpl-shared 4.4,gpl-shared 5.0,lgpl-shared 4.4,lgpl-shared 5.0]
variant: [gpl 5.0]
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
4 changes: 3 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ FFMPEG_REPO="${FFMPEG_REPO_OVERRIDE:-$FFMPEG_REPO}"
GIT_BRANCH="${GIT_BRANCH:-master}"
GIT_BRANCH="${GIT_BRANCH_OVERRIDE:-$GIT_BRANCH}"

cp patches/0001-ffmpeg-n5.0-flv-support-hevc.patch ffbuild

BUILD_SCRIPT="$(mktemp)"
trap "rm -f -- '$BUILD_SCRIPT'" EXIT

Expand All @@ -65,7 +67,7 @@ cat <<EOF >"$BUILD_SCRIPT"
git clone --filter=blob:none --branch='$GIT_BRANCH' '$FFMPEG_REPO' ffmpeg
cd ffmpeg
git apply ../0001-ffmpeg-n5.0-flv-support-hevc.patch
./configure --prefix=/ffbuild/prefix --pkg-config-flags="--static" \$FFBUILD_TARGET_FLAGS $FF_CONFIGURE \
--extra-cflags='$FF_CFLAGS' --extra-cxxflags='$FF_CXXFLAGS' \
--extra-ldflags='$FF_LDFLAGS' --extra-ldexeflags='$FF_LDEXEFLAGS' --extra-libs='$FF_LIBS' \
Expand Down
166 changes: 166 additions & 0 deletions patches/0001-ffmpeg-n5.0-flv-support-hevc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 3571b90..91f0065 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 b9e36b3..056381a 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

@@ -321,6 +322,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;
}
@@ -371,6 +374,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;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ ret = 3;
+ break;
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
@@ -1243,7 +1251,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--;

@@ -1252,7 +1261,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 = av_sat_add64(dts, cts);
@@ -1268,7 +1278,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 66c530a..fc01fd6 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -30,6 +30,7 @@
#include "avc.h"
#include "avformat.h"
#include "flv.h"
+#include "hevc.h"
#include "internal.h"
#include "metadata.h"
#include "libavutil/opt.h"
@@ -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);
@@ -797,7 +803,8 @@ 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);
}
}
@@ -848,14 +855,14 @@ 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)
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
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) {
- size_t side_size;
+ 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_HEVC) {
+ size_t 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))) {
ret = ff_alloc_extradata(par, side_size);
@@ -919,6 +926,11 @@ 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) {
+ /* check if extradata looks like mp4 formatted */
+ 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) {
@@ -991,7 +1003,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
(FFALIGN(par->height, 16) - par->height));
} 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);
}
3 changes: 2 additions & 1 deletion util/vars.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ while [[ "$#" -gt 0 ]]; do
shift
done

REPO="${GITHUB_REPOSITORY:-btbn/ffmpeg-builds}"
# REPO="${GITHUB_REPOSITORY:-btbn/ffmpeg-builds}"
REPO="${NO_GITHUB_REPOSITORY_XX:-btbn/ffmpeg-builds}"
REPO="${REPO,,}"
REGISTRY="ghcr.io"
BASE_IMAGE="${REGISTRY}/${REPO}/base:latest"
Expand Down

0 comments on commit 0a8325b

Please sign in to comment.