Re: [FFmpeg-devel] [PATCH] avformat/flvenc: add build_keyframes_index option
On Thu, Nov 3, 2016, at 05:05 AM, Steven Liu wrote: > Build keyframes index information into metadata. Can be simplified to: "Add keyframe index metadata." > Be used to http VOD flv. The above phrase is not very descriptive. I suggest something like: "Used to facilitate seeking; particularly for HTTP pseudo streaming." > Signed-off-by: Steven Liu> --- > doc/muxers.texi |3 + > libavformat/flvenc.c | 323 > -- > 2 files changed, 317 insertions(+), 9 deletions(-) > > diff --git a/doc/muxers.texi b/doc/muxers.texi > index 488ed43..1df7d97 100644 > --- a/doc/muxers.texi > +++ b/doc/muxers.texi > @@ -147,6 +147,9 @@ Place AAC sequence header based on audio stream data. > > @item no_sequence_end > Disable sequence end tag. > + > +@item build_keyframes_index "add_keyframe_index" makes more sense to me. > +Build keyframes index infomations into flv metadata. Be used to http > VOD.. You can reuse the commit message sentences here. > @end table > @end table > > diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c > index e50f8e4..1f1b608 100644 > --- a/libavformat/flvenc.c > +++ b/libavformat/flvenc.c > @@ -24,6 +24,8 @@ > #include "libavutil/intfloat.h" > #include "libavutil/avassert.h" > #include "libavutil/mathematics.h" > +#include "avio_internal.h" > +#include "avio.h" > #include "avc.h" > #include "avformat.h" > #include "flv.h" > @@ -64,8 +66,15 @@ static const AVCodecTag flv_audio_codec_ids[] = { > typedef enum { > FLV_AAC_SEQ_HEADER_DETECT = (1 << 0), > FLV_NO_SEQUENCE_END = (1 << 1), > +FLV_BUILD_KEYFRAME_IDX = (1 << 2), I would name it FLV_ADD_KEYFRAME_INDEX or similar, but I'll leave it to whatever you prefer. [...] > +if (ret < 0) { > +av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for " > + "the second pass (faststart)\n", s->filename); > +goto end; > +} "faststart" implies that an option or value named "faststart" was used. Should be renamed. > +/* mark the end of the shift to up to the last data we wrote, and > get ready > + * for writing */ > +pos_end = avio_tell(s->pb); > +avio_seek(s->pb, flv->keyframes_info_offset + metadata_size, > SEEK_SET); > + > +/* start reading at where the keyframe index information will be > placed */ > +avio_seek(read_pb, flv->keyframes_info_offset, SEEK_SET); > +pos = avio_tell(read_pb); > + > +/* shift data by chunk of at most keyframe infomations size */ I don't understand the above sentence. [...] > +{ "build_keyframes_index", "Build keyframes index information into > metadata", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_BUILD_KEYFRAME_IDX}, > INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" }, > { NULL }, > }; I would change it to: "add_keyframe_index", "Add keyframe index metadata" ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/flvenc: add build_keyframes_index option
Build keyframes index information into metadata. Be used to http VOD flv. Signed-off-by: Steven Liu--- doc/muxers.texi |3 + libavformat/flvenc.c | 323 -- 2 files changed, 317 insertions(+), 9 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 488ed43..1df7d97 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -147,6 +147,9 @@ Place AAC sequence header based on audio stream data. @item no_sequence_end Disable sequence end tag. + +@item build_keyframes_index +Build keyframes index infomations into flv metadata. Be used to http VOD.. @end table @end table diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index e50f8e4..1f1b608 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -24,6 +24,8 @@ #include "libavutil/intfloat.h" #include "libavutil/avassert.h" #include "libavutil/mathematics.h" +#include "avio_internal.h" +#include "avio.h" #include "avc.h" #include "avformat.h" #include "flv.h" @@ -64,8 +66,15 @@ static const AVCodecTag flv_audio_codec_ids[] = { typedef enum { FLV_AAC_SEQ_HEADER_DETECT = (1 << 0), FLV_NO_SEQUENCE_END = (1 << 1), +FLV_BUILD_KEYFRAME_IDX = (1 << 2), } FLVFlags; +typedef struct FLVFileposition { +int64_t keyframe_position; +double keyframe_timestamp; +struct FLVFileposition *next; +} FLVFileposition; + typedef struct FLVContext { AVClass *av_class; int reserved; @@ -74,6 +83,33 @@ typedef struct FLVContext { int64_t duration; int64_t delay; ///< first dts delay (needed for AVC & Speex) +int64_t datastart_offset; +int64_t datasize_offset; +int64_t datasize; +int64_t videosize_offset; +int64_t videosize; +int64_t audiosize_offset; +int64_t audiosize; + +int64_t metadata_size_pos; +int64_t metadata_totalsize_pos; +int64_t metadata_totalsize; +int64_t keyframe_index_size; + +int64_t lasttimestamp_offset; +double lasttimestamp; +int64_t lastkeyframetimestamp_offset; +double lastkeyframetimestamp; +int64_t lastkeyframelocation_offset; +int64_t lastkeyframelocation; + +int acurframeindex; +int64_t keyframes_info_offset; + +int64_t filepositions_count; +FLVFileposition *filepositions; +FLVFileposition *head_filepositions; + AVCodecParameters *audio_par; AVCodecParameters *video_par; double framerate; @@ -202,6 +238,17 @@ static void put_amf_double(AVIOContext *pb, double d) avio_wb64(pb, av_double2int(d)); } +static void put_amf_byte(AVIOContext *pb, unsigned char abyte) +{ +avio_w8(pb, abyte); +} + +static void put_amf_dword_array(AVIOContext *pb, uint32_t dw) +{ +avio_w8(pb, AMF_DATA_TYPE_ARRAY); +avio_wb32(pb, dw); +} + static void put_amf_bool(AVIOContext *pb, int b) { avio_w8(pb, AMF_DATA_TYPE_BOOL); @@ -213,12 +260,12 @@ static void write_metadata(AVFormatContext *s, unsigned int ts) AVIOContext *pb = s->pb; FLVContext *flv = s->priv_data; int metadata_count = 0; -int64_t metadata_size_pos, data_size, metadata_count_pos; +int64_t metadata_count_pos; AVDictionaryEntry *tag = NULL; /* write meta_tag */ -avio_w8(pb, 18);// tag type META -metadata_size_pos = avio_tell(pb); +avio_w8(pb, FLV_TAG_TYPE_META);// tag type META +flv->metadata_size_pos = avio_tell(pb); avio_wb24(pb, 0); // size of data part (sum of all parts below) avio_wb24(pb, ts); // timestamp avio_wb32(pb, 0); // reserved @@ -327,19 +374,87 @@ static void write_metadata(AVFormatContext *s, unsigned int ts) put_amf_double(pb, 0); // delayed write } +if (flv->flags & FLV_BUILD_KEYFRAME_IDX) { +flv->acurframeindex = 0; +flv->keyframe_index_size = 0; + +put_amf_string(pb, "hasVideo"); +put_amf_bool(pb, !!flv->video_par); +metadata_count++; + +put_amf_string(pb, "hasKeyframes"); +put_amf_bool(pb, 1); +metadata_count++; + +put_amf_string(pb, "hasAudio"); +put_amf_bool(pb, !!flv->audio_par); +metadata_count++; + +put_amf_string(pb, "hasMetadata"); +put_amf_bool(pb, 1); +metadata_count++; + +put_amf_string(pb, "canSeekToEnd"); +put_amf_bool(pb, 1); +metadata_count++; + +put_amf_string(pb, "datasize"); +flv->datasize_offset = avio_tell(pb); +flv->datasize = 0; +put_amf_double(pb, flv->datasize); +metadata_count++; + +put_amf_string(pb, "videosize"); +flv->videosize_offset = avio_tell(pb); +flv->videosize = 0; +put_amf_double(pb, flv->videosize); +metadata_count++; + +put_amf_string(pb, "audiosize"); +flv->audiosize_offset = avio_tell(pb); +flv->audiosize = 0; +put_amf_double(pb, flv->audiosize); +metadata_count++; + +