Message ID | 20230406121241.86114-1-lq@chinaffmpeg.org |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/2] avformat/flvenc: Add support for HEVC over flv in muxer | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote: > Implements HEVC according to enhanced RTMP spec found at > https://github.com/veovera/enhanced-rtmp > > I think It's document or draft and not specs, I haven't heard any information for the veovera software organization. So before implementation, please prove it's recognized authority. Please see rfc2026. > And it has beed supported by OBS, Simple Realtime Server. > And the Enhancing FLV documentation Contributors include > Jean-Baptiste Kempf (FFmpeg, VideoLAN). > So this should be support by ffmpeg too. > > Signed-off-by: Steven Liu <lq@chinaffmpeg.org> > --- > libavformat/flv.h | 16 ++++++++++++++ > libavformat/flvenc.c | 50 +++++++++++++++++++++++++++++++++----------- > 2 files changed, 54 insertions(+), 12 deletions(-) > > diff --git a/libavformat/flv.h b/libavformat/flv.h > index 3571b90279..44d3b04ff9 100644 > --- a/libavformat/flv.h > +++ b/libavformat/flv.h > @@ -35,6 +35,12 @@ > > #define FLV_VIDEO_FRAMETYPE_OFFSET 4 > > +/* Extended VideoTagHeader > + * defined in reference link: > + * > https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf > + * */ > +#define FLV_IS_EX_HEADER 0x80 > + > /* bitmasks to isolate specific values */ > #define FLV_AUDIO_CHANNEL_MASK 0x01 > #define FLV_AUDIO_SAMPLESIZE_MASK 0x02 > @@ -110,6 +116,16 @@ enum { > FLV_CODECID_H264 = 7, > FLV_CODECID_REALH263= 8, > FLV_CODECID_MPEG4 = 9, > + FLV_CODECID_HEVC = 10, > +}; > + > +enum { > + PacketTypeSequenceStart = 0, > + PacketTypeCodedFrames = 1, > + PacketTypeSequenceEnd = 2, > + PacketTypeCodedFramesX = 3, > + PacketTypeMetadata = 4, > + PacketTypeMPEG2TSSequenceStart = 5, > }; > > enum { > diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c > index 64ea554dad..15a0f573f3 100644 > --- a/libavformat/flvenc.c > +++ b/libavformat/flvenc.c > @@ -28,6 +28,7 @@ > #include "libavcodec/mpeg4audio.h" > #include "avio.h" > #include "avc.h" > +#include "hevc.h" > #include "avformat.h" > #include "flv.h" > #include "internal.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 } > }; > > @@ -492,7 +494,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 ? > @@ -535,10 +537,19 @@ static void flv_write_codec_header(AVFormatContext* > s, AVCodecParameters* par, i > } > avio_write(pb, par->extradata, par->extradata_size); > } else { > - 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) { > + avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); > // ExVideoTagHeader mode with PacketTypeSequenceStart > + avio_write(pb, "hvc1", 4); > + } else { > + avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags > + avio_w8(pb, 0); // AVC sequence header > + avio_wb24(pb, 0); // composition time > + } > + > + 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); > @@ -628,7 +639,8 @@ static int flv_init(struct AVFormatContext *s) > return unsupported_codec(s, "Video", par->codec_id); > > if (par->codec_id == AV_CODEC_ID_MPEG4 || > - par->codec_id == AV_CODEC_ID_H263) { > + par->codec_id == AV_CODEC_ID_H263 || > + par->codec_id == AV_CODEC_ID_HEVC) { > int error = s->strict_std_compliance > > FF_COMPLIANCE_UNOFFICIAL; > av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING, > "Codec %s is not supported in the official FLV > specification,\n", avcodec_get_name(par->codec_id)); > @@ -784,8 +796,11 @@ end: > for (i = 0; i < s->nb_streams; i++) { > 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)) > + if (par->codec_id == AV_CODEC_ID_HEVC) { > + avio_w8(pb, 0x82); > + avio_write(pb, "hvc1", 4); > + } else 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_HEVC)) > put_eos_tag(pb, sc->last_ts, par->codec_id); > } > } > @@ -836,13 +851,13 @@ 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) { > + || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == > AV_CODEC_ID_HEVC) { > size_t side_size; > 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))) { > @@ -862,7 +877,7 @@ static int flv_write_packet(AVFormatContext *s, > AVPacket *pkt) > "Packets are not in the proper order with respect to > DTS\n"); > return AVERROR(EINVAL); > } > - if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == > AV_CODEC_ID_MPEG4) { > + if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == > AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) { > if (pkt->pts == AV_NOPTS_VALUE) { > av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n"); > return AVERROR(EINVAL); > @@ -907,6 +922,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) { > @@ -968,7 +987,12 @@ static int flv_write_packet(AVFormatContext *s, > AVPacket *pkt) > avio_wb32(pb, data_size + 11); > } else { > av_assert1(flags>=0); > - avio_w8(pb,flags); > + if (par->codec_id == AV_CODEC_ID_HEVC) { > + avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); // > ExVideoTagHeader mode with PacketTypeCodedFrames > + avio_write(pb, "hvc1", 4); > + } else { > + avio_w8(pb, flags); > + } > if (par->codec_id == AV_CODEC_ID_VP6) > avio_w8(pb,0); > if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == > AV_CODEC_ID_VP6A) { > @@ -982,6 +1006,8 @@ static int flv_write_packet(AVFormatContext *s, > AVPacket *pkt) > else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == > AV_CODEC_ID_MPEG4) { > avio_w8(pb, 1); // AVC NALU > avio_wb24(pb, pkt->pts - pkt->dts); > + } else if (par->codec_id == AV_CODEC_ID_HEVC) { > + avio_wb24(pb, pkt->pts - pkt->dts); > } > > avio_write(pb, data ? data : pkt->data, size); > -- > 2.40.0 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >
On 2023-04-06 08:14 pm, Lance Wang wrote: > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote: > >> Implements HEVC according to enhanced RTMP spec found at >> https://github.com/veovera/enhanced-rtmp >> >> > I think It's document or draft and not specs, I haven't heard any > information for the > veovera software organization. So before implementation, please prove it's > recognized authority. Please see rfc2026. Their Github readme claims "Additionally, Veovera has welcomed new members to the organization including Adobe, Google and Veriskope." I didn't find any public corroboration by these companies. However, one of the authors is cited as having OBS affiliation and they have indeed merged support: https://www.phoronix.com/news/OBS-Studio-AV1-HEVC-RTMP Since they claim jbk as a member, ping him. Regards, Gyan
On Thu, 6 Apr 2023, at 17:10, Gyan Doshi wrote: > On 2023-04-06 08:14 pm, Lance Wang wrote: >> On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote: >> >>> Implements HEVC according to enhanced RTMP spec found at >>> https://github.com/veovera/enhanced-rtmp >>> >>> >> I think It's document or draft and not specs, I haven't heard any >> information for the >> veovera software organization. So before implementation, please prove it's >> recognized authority. Please see rfc2026. > > Their Github readme claims > > "Additionally, Veovera has welcomed new members to the organization > including Adobe, Google and Veriskope." > > I didn't find any public corroboration by these companies. Technically, Veovera is the one doing the maintenance of Flash Media Server, given by Adobe. So it's so far, the best authority on flv and RTMP. But for me, all those are still drafts, and therefore need to wait a bit. Also, audio extension is coming too. (Same system for FourCC) jb
On Thu, Apr 6, 2023 at 6:11 PM Gyan Doshi <ffmpeg@gyani.pro> wrote: > > > > On 2023-04-06 08:14 pm, Lance Wang wrote: > > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote: > > > >> Implements HEVC according to enhanced RTMP spec found at > >> https://github.com/veovera/enhanced-rtmp > >> > >> > > I think It's document or draft and not specs, I haven't heard any > > information for the > > veovera software organization. So before implementation, please prove it's > > recognized authority. Please see rfc2026. > > Their Github readme claims > > "Additionally, Veovera has welcomed new members to the organization > including Adobe, Google and Veriskope." > > I didn't find any public corroboration by these companies. > Yea, it seems like this was mostly done in the background (classic corporations being corporations), but I think the most direct way to notice that Google at least has acknowledged this extension is because Youtube now seems to support AV1 live stream ingest via RTMP with these extensions. Jan
On Thu, Apr 6, 2023 at 1:03 PM Jan Ekström <jeebjp@gmail.com> wrote: > > On Thu, Apr 6, 2023 at 6:11 PM Gyan Doshi <ffmpeg@gyani.pro> wrote: > > > > > > > > On 2023-04-06 08:14 pm, Lance Wang wrote: > > > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote: > > > > > >> Implements HEVC according to enhanced RTMP spec found at > > >> https://github.com/veovera/enhanced-rtmp > > >> > > >> > > > I think It's document or draft and not specs, I haven't heard any > > > information for the > > > veovera software organization. So before implementation, please prove it's > > > recognized authority. Please see rfc2026. > > > > Their Github readme claims > > > > "Additionally, Veovera has welcomed new members to the organization > > including Adobe, Google and Veriskope." > > > > I didn't find any public corroboration by these companies. > > > > Yea, it seems like this was mostly done in the background (classic > corporations being corporations), but I think the most direct way to > notice that Google at least has acknowledged this extension is because > Youtube now seems to support AV1 live stream ingest via RTMP with > these extensions. > Notably though, these patches don't implement that, though. :(
Neal Gompa <ngompa13@gmail.com> 于2023年4月11日周二 16:57写道: > > On Thu, Apr 6, 2023 at 1:03 PM Jan Ekström <jeebjp@gmail.com> wrote: > > > > On Thu, Apr 6, 2023 at 6:11 PM Gyan Doshi <ffmpeg@gyani.pro> wrote: > > > > > > > > > > > > On 2023-04-06 08:14 pm, Lance Wang wrote: > > > > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote: > > > > > > > >> Implements HEVC according to enhanced RTMP spec found at > > > >> https://github.com/veovera/enhanced-rtmp > > > >> > > > >> > > > > I think It's document or draft and not specs, I haven't heard any > > > > information for the > > > > veovera software organization. So before implementation, please prove it's > > > > recognized authority. Please see rfc2026. > > > > > > Their Github readme claims > > > > > > "Additionally, Veovera has welcomed new members to the organization > > > including Adobe, Google and Veriskope." > > > > > > I didn't find any public corroboration by these companies. > > > > > > > Yea, it seems like this was mostly done in the background (classic > > corporations being corporations), but I think the most direct way to > > notice that Google at least has acknowledged this extension is because > > Youtube now seems to support AV1 live stream ingest via RTMP with > > these extensions. > > > > Notably though, these patches don't implement that, though. :( This is first step, if this patchset can be merge is means that the av1,vp9 can be accpected too. :D > > > > -- > 真実はいつも一つ!/ Always, there's only one truth! > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Tue, Apr 11, 2023 at 5:25 AM Steven Liu <lingjiujianke@gmail.com> wrote: > > Neal Gompa <ngompa13@gmail.com> 于2023年4月11日周二 16:57写道: > > > > On Thu, Apr 6, 2023 at 1:03 PM Jan Ekström <jeebjp@gmail.com> wrote: > > > > > > On Thu, Apr 6, 2023 at 6:11 PM Gyan Doshi <ffmpeg@gyani.pro> wrote: > > > > > > > > > > > > > > > > On 2023-04-06 08:14 pm, Lance Wang wrote: > > > > > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote: > > > > > > > > > >> Implements HEVC according to enhanced RTMP spec found at > > > > >> https://github.com/veovera/enhanced-rtmp > > > > >> > > > > >> > > > > > I think It's document or draft and not specs, I haven't heard any > > > > > information for the > > > > > veovera software organization. So before implementation, please prove it's > > > > > recognized authority. Please see rfc2026. > > > > > > > > Their Github readme claims > > > > > > > > "Additionally, Veovera has welcomed new members to the organization > > > > including Adobe, Google and Veriskope." > > > > > > > > I didn't find any public corroboration by these companies. > > > > > > > > > > Yea, it seems like this was mostly done in the background (classic > > > corporations being corporations), but I think the most direct way to > > > notice that Google at least has acknowledged this extension is because > > > Youtube now seems to support AV1 live stream ingest via RTMP with > > > these extensions. > > > > > > > Notably though, these patches don't implement that, though. :( > This is first step, if this patchset can be merge is means that the > av1,vp9 can be accpected too. :D > Could you submit a complete version when you respin v4? The only endpoint I can reasonably test is YouTube, so not having AV1 support makes it difficult for me to try it out...
Neal Gompa <ngompa13@gmail.com> 于2023年4月12日周三 09:27写道: > > On Tue, Apr 11, 2023 at 5:25 AM Steven Liu <lingjiujianke@gmail.com> wrote: > > > > Neal Gompa <ngompa13@gmail.com> 于2023年4月11日周二 16:57写道: > > > > > > On Thu, Apr 6, 2023 at 1:03 PM Jan Ekström <jeebjp@gmail.com> wrote: > > > > > > > > On Thu, Apr 6, 2023 at 6:11 PM Gyan Doshi <ffmpeg@gyani.pro> wrote: > > > > > > > > > > > > > > > > > > > > On 2023-04-06 08:14 pm, Lance Wang wrote: > > > > > > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote: > > > > > > > > > > > >> Implements HEVC according to enhanced RTMP spec found at > > > > > >> https://github.com/veovera/enhanced-rtmp > > > > > >> > > > > > >> > > > > > > I think It's document or draft and not specs, I haven't heard any > > > > > > information for the > > > > > > veovera software organization. So before implementation, please prove it's > > > > > > recognized authority. Please see rfc2026. > > > > > > > > > > Their Github readme claims > > > > > > > > > > "Additionally, Veovera has welcomed new members to the organization > > > > > including Adobe, Google and Veriskope." > > > > > > > > > > I didn't find any public corroboration by these companies. > > > > > > > > > > > > > Yea, it seems like this was mostly done in the background (classic > > > > corporations being corporations), but I think the most direct way to > > > > notice that Google at least has acknowledged this extension is because > > > > Youtube now seems to support AV1 live stream ingest via RTMP with > > > > these extensions. > > > > > > > > > > Notably though, these patches don't implement that, though. :( > > This is first step, if this patchset can be merge is means that the > > av1,vp9 can be accpected too. :D > > > > Could you submit a complete version when you respin v4? The only > endpoint I can reasonably test is YouTube, so not having AV1 support > makes it difficult for me to try it out... you can test it by ossrs :D I think i can submit new patchset after this patchset be merged :D > > > > -- > 真実はいつも一つ!/ Always, there's only one truth! > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Neal Gompa <ngompa13@gmail.com> 于2023年4月12日周三 09:27写道: > Could you submit a complete version when you respin v4? The only > endpoint I can reasonably test is YouTube, so not having AV1 support > makes it difficult for me to try it out... Try this patchset please. https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=8723 >
Steven Liu <lingjiujianke@gmail.com> 于2023年4月12日周三 12:32写道: > > Neal Gompa <ngompa13@gmail.com> 于2023年4月12日周三 09:27写道: > > Could you submit a complete version when you respin v4? The only > > endpoint I can reasonably test is YouTube, so not having AV1 support > > makes it difficult for me to try it out... > Try this patchset please. > https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=8723 Ignore this patchset, i resubmit a v5 fix compiling error at the third patch You can try the v5 version. Thanks Steven
diff --git a/libavformat/flv.h b/libavformat/flv.h index 3571b90279..44d3b04ff9 100644 --- a/libavformat/flv.h +++ b/libavformat/flv.h @@ -35,6 +35,12 @@ #define FLV_VIDEO_FRAMETYPE_OFFSET 4 +/* Extended VideoTagHeader + * defined in reference link: + * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf + * */ +#define FLV_IS_EX_HEADER 0x80 + /* bitmasks to isolate specific values */ #define FLV_AUDIO_CHANNEL_MASK 0x01 #define FLV_AUDIO_SAMPLESIZE_MASK 0x02 @@ -110,6 +116,16 @@ enum { FLV_CODECID_H264 = 7, FLV_CODECID_REALH263= 8, FLV_CODECID_MPEG4 = 9, + FLV_CODECID_HEVC = 10, +}; + +enum { + PacketTypeSequenceStart = 0, + PacketTypeCodedFrames = 1, + PacketTypeSequenceEnd = 2, + PacketTypeCodedFramesX = 3, + PacketTypeMetadata = 4, + PacketTypeMPEG2TSSequenceStart = 5, }; enum { diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index 64ea554dad..15a0f573f3 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -28,6 +28,7 @@ #include "libavcodec/mpeg4audio.h" #include "avio.h" #include "avc.h" +#include "hevc.h" #include "avformat.h" #include "flv.h" #include "internal.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 } }; @@ -492,7 +494,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 ? @@ -535,10 +537,19 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i } avio_write(pb, par->extradata, par->extradata_size); } else { - 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) { + avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart + avio_write(pb, "hvc1", 4); + } else { + avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags + avio_w8(pb, 0); // AVC sequence header + avio_wb24(pb, 0); // composition time + } + + 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); @@ -628,7 +639,8 @@ static int flv_init(struct AVFormatContext *s) return unsupported_codec(s, "Video", par->codec_id); if (par->codec_id == AV_CODEC_ID_MPEG4 || - par->codec_id == AV_CODEC_ID_H263) { + par->codec_id == AV_CODEC_ID_H263 || + par->codec_id == AV_CODEC_ID_HEVC) { int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL; av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING, "Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id)); @@ -784,8 +796,11 @@ end: for (i = 0; i < s->nb_streams; i++) { 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)) + if (par->codec_id == AV_CODEC_ID_HEVC) { + avio_w8(pb, 0x82); + avio_write(pb, "hvc1", 4); + } else 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_HEVC)) put_eos_tag(pb, sc->last_ts, par->codec_id); } } @@ -836,13 +851,13 @@ 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) { + || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) { size_t side_size; 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))) { @@ -862,7 +877,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) "Packets are not in the proper order with respect to DTS\n"); return AVERROR(EINVAL); } - if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) { + if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) { if (pkt->pts == AV_NOPTS_VALUE) { av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n"); return AVERROR(EINVAL); @@ -907,6 +922,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) { @@ -968,7 +987,12 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) avio_wb32(pb, data_size + 11); } else { av_assert1(flags>=0); - avio_w8(pb,flags); + if (par->codec_id == AV_CODEC_ID_HEVC) { + avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); // ExVideoTagHeader mode with PacketTypeCodedFrames + avio_write(pb, "hvc1", 4); + } else { + avio_w8(pb, flags); + } if (par->codec_id == AV_CODEC_ID_VP6) avio_w8(pb,0); if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A) { @@ -982,6 +1006,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) { avio_w8(pb, 1); // AVC NALU avio_wb24(pb, pkt->pts - pkt->dts); + } else if (par->codec_id == AV_CODEC_ID_HEVC) { + avio_wb24(pb, pkt->pts - pkt->dts); } avio_write(pb, data ? data : pkt->data, size);
Implements HEVC according to enhanced RTMP spec found at https://github.com/veovera/enhanced-rtmp And it has beed supported by OBS, Simple Realtime Server. And the Enhancing FLV documentation Contributors include Jean-Baptiste Kempf (FFmpeg, VideoLAN). So this should be support by ffmpeg too. Signed-off-by: Steven Liu <lq@chinaffmpeg.org> --- libavformat/flv.h | 16 ++++++++++++++ libavformat/flvenc.c | 50 +++++++++++++++++++++++++++++++++----------- 2 files changed, 54 insertions(+), 12 deletions(-)