Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Wed, Jul 27, 2016 at 10:17 AM, Michael Niedermayer wrote: > On Wed, Jul 27, 2016 at 09:56:02AM +0800, XinZheng Zhang wrote: >> On Wed, Jul 27, 2016 at 7:25 AM, Michael Niedermayer >> wrote: >> > On Wed, Jul 27, 2016 at 01:31:29AM +0800, XinZheng Zhang wrote: >> >> On Wed, Jul 27, 2016 at 1:12 AM, Michael Niedermayer >> >> wrote: >> >> > On Tue, Jul 26, 2016 at 08:17:46PM +0800, Xinzheng Zhang wrote: >> > [...] >> >> >> + >> >> >> +AVStream *streams[2] = {vstream, astream}; >> >> >> +for (i = 0; i < 2; i++) { >> >> >> +current_stream = streams[i]; >> >> >> +if (current_stream && current_stream->nb_index_entries==0) { >> >> >> +for (j = 0; j < flv->keyframe_count; j++) { >> >> >> +av_add_index_entry(current_stream, >> >> >> flv->keyframe_filepositions[j], flv->keyframe_times[j] * 1000, >> >> >> + 0, 0, AVINDEX_KEYFRAME); >> >> >> +} >> >> >> +} >> >> >> +} >> >> >> + >> >> >> +// free keyframe index only if all expected streams have been >> >> >> created >> >> >> +if (((vstream && vstream->nb_index_entries>0) || >> >> >> !flv->vhead_exists) && >> >> >> +((astream && astream->nb_index_entries>0) || >> >> >> !flv->ahead_exists)) { >> >> >> +av_freep(&flv->keyframe_times); >> >> >> +av_freep(&flv->keyframe_filepositions); >> >> >> +flv->keyframe_count = 0; >> >> >> +} >> >> >> +} >> >> > >> >> > spliting add_keyframes_index() out must be in a seperate patch >> >> > >> >> > also i would not trust the *head_exists flags, IIRC they can be >> >> > wrong and they are not needed >> >> > the function should just take the table load it with >> >> > av_add_index_entry() and free the table. >> >> > The rest should not be needed >> >> > should be much simpler unless iam missing something >> >> > >> >> > >> >> >> >> If I don't trust the head_exists flags, when should I free the index >> >> table? >> >> Should I keep the index util both a\v stream have been loaded or keep >> >> it util the flv_read_close(). >> > >> > the table was freed after av_add_index_entry() >> > that should still work fine unless i miss somethig >> > >> >> [meta]-[v]-[v]..[a] >> In this case both video and audio stream share the same index table. >> I am not know whether the audio stream exists until the first audio >> packet parsed. >> I thought that I should keep the index until all the streams have been >> loaded. > > in the example above the video key frame table would be loaded > and added into the video stream once it has been created, and > freed afterwards > nothing is done with audio (currently or after the change) > > if the audio table is prior the video one its loaded and freed once > the video table is encountered > > do i miss something ? > Now I understand it. Before that I thought that both streams have to install the index table. > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > There will always be a question for which you do not know the correct answer. > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Wed, Jul 27, 2016 at 09:56:02AM +0800, XinZheng Zhang wrote: > On Wed, Jul 27, 2016 at 7:25 AM, Michael Niedermayer > wrote: > > On Wed, Jul 27, 2016 at 01:31:29AM +0800, XinZheng Zhang wrote: > >> On Wed, Jul 27, 2016 at 1:12 AM, Michael Niedermayer > >> wrote: > >> > On Tue, Jul 26, 2016 at 08:17:46PM +0800, Xinzheng Zhang wrote: > > [...] > >> >> + > >> >> +AVStream *streams[2] = {vstream, astream}; > >> >> +for (i = 0; i < 2; i++) { > >> >> +current_stream = streams[i]; > >> >> +if (current_stream && current_stream->nb_index_entries==0) { > >> >> +for (j = 0; j < flv->keyframe_count; j++) { > >> >> +av_add_index_entry(current_stream, > >> >> flv->keyframe_filepositions[j], flv->keyframe_times[j] * 1000, > >> >> + 0, 0, AVINDEX_KEYFRAME); > >> >> +} > >> >> +} > >> >> +} > >> >> + > >> >> +// free keyframe index only if all expected streams have been > >> >> created > >> >> +if (((vstream && vstream->nb_index_entries>0) || > >> >> !flv->vhead_exists) && > >> >> +((astream && astream->nb_index_entries>0) || > >> >> !flv->ahead_exists)) { > >> >> +av_freep(&flv->keyframe_times); > >> >> +av_freep(&flv->keyframe_filepositions); > >> >> +flv->keyframe_count = 0; > >> >> +} > >> >> +} > >> > > >> > spliting add_keyframes_index() out must be in a seperate patch > >> > > >> > also i would not trust the *head_exists flags, IIRC they can be > >> > wrong and they are not needed > >> > the function should just take the table load it with > >> > av_add_index_entry() and free the table. > >> > The rest should not be needed > >> > should be much simpler unless iam missing something > >> > > >> > > >> > >> If I don't trust the head_exists flags, when should I free the index table? > >> Should I keep the index util both a\v stream have been loaded or keep > >> it util the flv_read_close(). > > > > the table was freed after av_add_index_entry() > > that should still work fine unless i miss somethig > > > > [meta]-[v]-[v]..[a] > In this case both video and audio stream share the same index table. > I am not know whether the audio stream exists until the first audio > packet parsed. > I thought that I should keep the index until all the streams have been loaded. in the example above the video key frame table would be loaded and added into the video stream once it has been created, and freed afterwards nothing is done with audio (currently or after the change) if the audio table is prior the video one its loaded and freed once the video table is encountered do i miss something ? [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB There will always be a question for which you do not know the correct answer. signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Wed, Jul 27, 2016 at 7:25 AM, Michael Niedermayer wrote: > On Wed, Jul 27, 2016 at 01:31:29AM +0800, XinZheng Zhang wrote: >> On Wed, Jul 27, 2016 at 1:12 AM, Michael Niedermayer >> wrote: >> > On Tue, Jul 26, 2016 at 08:17:46PM +0800, Xinzheng Zhang wrote: > [...] >> >> + >> >> +AVStream *streams[2] = {vstream, astream}; >> >> +for (i = 0; i < 2; i++) { >> >> +current_stream = streams[i]; >> >> +if (current_stream && current_stream->nb_index_entries==0) { >> >> +for (j = 0; j < flv->keyframe_count; j++) { >> >> +av_add_index_entry(current_stream, >> >> flv->keyframe_filepositions[j], flv->keyframe_times[j] * 1000, >> >> + 0, 0, AVINDEX_KEYFRAME); >> >> +} >> >> +} >> >> +} >> >> + >> >> +// free keyframe index only if all expected streams have been created >> >> +if (((vstream && vstream->nb_index_entries>0) || !flv->vhead_exists) >> >> && >> >> +((astream && astream->nb_index_entries>0) || >> >> !flv->ahead_exists)) { >> >> +av_freep(&flv->keyframe_times); >> >> +av_freep(&flv->keyframe_filepositions); >> >> +flv->keyframe_count = 0; >> >> +} >> >> +} >> > >> > spliting add_keyframes_index() out must be in a seperate patch >> > >> > also i would not trust the *head_exists flags, IIRC they can be >> > wrong and they are not needed >> > the function should just take the table load it with >> > av_add_index_entry() and free the table. >> > The rest should not be needed >> > should be much simpler unless iam missing something >> > >> > >> >> If I don't trust the head_exists flags, when should I free the index table? >> Should I keep the index util both a\v stream have been loaded or keep >> it util the flv_read_close(). > > the table was freed after av_add_index_entry() > that should still work fine unless i miss somethig > [meta]-[v]-[v]..[a] In this case both video and audio stream share the same index table. I am not know whether the audio stream exists until the first audio packet parsed. I thought that I should keep the index until all the streams have been loaded. > some cleanup code at close might be needed to catch error conditions > so theres never a memleak > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > Dictatorship naturally arises out of democracy, and the most aggravated > form of tyranny and slavery out of the most extreme liberty. -- Plato > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Tue, Jul 26, 2016 at 08:17:46PM +0800, Xinzheng Zhang wrote: > --- > libavformat/flvdec.c | 84 > ++-- > 1 file changed, 69 insertions(+), 15 deletions(-) also: someone please fix the spelling&grammer in the commit message: "avformat/fivdec: cached keyframes before video or audio stream was created" [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No snowflake in an avalanche ever feels responsible. -- Voltaire signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Wed, Jul 27, 2016 at 01:31:29AM +0800, XinZheng Zhang wrote: > On Wed, Jul 27, 2016 at 1:12 AM, Michael Niedermayer > wrote: > > On Tue, Jul 26, 2016 at 08:17:46PM +0800, Xinzheng Zhang wrote: [...] > >> + > >> +AVStream *streams[2] = {vstream, astream}; > >> +for (i = 0; i < 2; i++) { > >> +current_stream = streams[i]; > >> +if (current_stream && current_stream->nb_index_entries==0) { > >> +for (j = 0; j < flv->keyframe_count; j++) { > >> +av_add_index_entry(current_stream, > >> flv->keyframe_filepositions[j], flv->keyframe_times[j] * 1000, > >> + 0, 0, AVINDEX_KEYFRAME); > >> +} > >> +} > >> +} > >> + > >> +// free keyframe index only if all expected streams have been created > >> +if (((vstream && vstream->nb_index_entries>0) || !flv->vhead_exists) > >> && > >> +((astream && astream->nb_index_entries>0) || !flv->ahead_exists)) > >> { > >> +av_freep(&flv->keyframe_times); > >> +av_freep(&flv->keyframe_filepositions); > >> +flv->keyframe_count = 0; > >> +} > >> +} > > > > spliting add_keyframes_index() out must be in a seperate patch > > > > also i would not trust the *head_exists flags, IIRC they can be > > wrong and they are not needed > > the function should just take the table load it with > > av_add_index_entry() and free the table. > > The rest should not be needed > > should be much simpler unless iam missing something > > > > > > If I don't trust the head_exists flags, when should I free the index table? > Should I keep the index util both a\v stream have been loaded or keep > it util the flv_read_close(). the table was freed after av_add_index_entry() that should still work fine unless i miss somethig some cleanup code at close might be needed to catch error conditions so theres never a memleak [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Dictatorship naturally arises out of democracy, and the most aggravated form of tyranny and slavery out of the most extreme liberty. -- Plato signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Wed, Jul 27, 2016 at 1:12 AM, Michael Niedermayer wrote: > On Tue, Jul 26, 2016 at 08:17:46PM +0800, Xinzheng Zhang wrote: >> --- >> libavformat/flvdec.c | 84 >> ++-- >> 1 file changed, 69 insertions(+), 15 deletions(-) >> >> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c >> index 2bf1e05..82b9f83 100644 >> --- a/libavformat/flvdec.c >> +++ b/libavformat/flvdec.c >> @@ -61,6 +61,12 @@ typedef struct FLVContext { >> >> int broken_sizes; >> int sum_flv_tag_size; >> + >> +int vhead_exists; >> +int ahead_exists; >> +int keyframe_count; >> +int64_t *keyframe_times; >> +int64_t *keyframe_filepositions; >> } FLVContext; >> >> static int probe(AVProbeData *p, int live) >> @@ -92,6 +98,42 @@ static int live_flv_probe(AVProbeData *p) >> return probe(p, 1); >> } >> >> +static void add_keyframes_index(AVFormatContext *s) >> +{ >> +FLVContext *flv = s->priv_data; >> +AVStream *current_stream = NULL; >> +AVStream *vstream = NULL; >> +AVStream *astream = NULL; >> +unsigned int i,j; >> + >> +for (i = 0; i< s->nb_streams; i++) { >> +if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { >> +vstream = s->streams[i]; >> +} else if (s->streams[i]->codecpar->codec_type == >> AVMEDIA_TYPE_AUDIO) { >> +astream = s->streams[i]; >> +} >> +} > > this shouldt be needed > just keep track of the stram index that the table belongs to > that is add a flv->keyframe_stream_index > > ok >> + >> +AVStream *streams[2] = {vstream, astream}; >> +for (i = 0; i < 2; i++) { >> +current_stream = streams[i]; >> +if (current_stream && current_stream->nb_index_entries==0) { >> +for (j = 0; j < flv->keyframe_count; j++) { >> +av_add_index_entry(current_stream, >> flv->keyframe_filepositions[j], flv->keyframe_times[j] * 1000, >> + 0, 0, AVINDEX_KEYFRAME); >> +} >> +} >> +} >> + >> +// free keyframe index only if all expected streams have been created >> +if (((vstream && vstream->nb_index_entries>0) || !flv->vhead_exists) && >> +((astream && astream->nb_index_entries>0) || !flv->ahead_exists)) { >> +av_freep(&flv->keyframe_times); >> +av_freep(&flv->keyframe_filepositions); >> +flv->keyframe_count = 0; >> +} >> +} > > spliting add_keyframes_index() out must be in a seperate patch > > also i would not trust the *head_exists flags, IIRC they can be > wrong and they are not needed > the function should just take the table load it with > av_add_index_entry() and free the table. > The rest should not be needed > should be much simpler unless iam missing something > > If I don't trust the head_exists flags, when should I free the index table? Should I keep the index util both a\v stream have been loaded or keep it util the flv_read_close(). > [...] >> @@ -305,8 +348,7 @@ static int amf_get_string(AVIOContext *ioc, char >> *buffer, int buffsize) >> return length; >> } >> >> -static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, >> - AVStream *vstream, int64_t max_pos) >> +static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, >> int64_t max_pos) >> { >> FLVContext *flv = s->priv_data; >> unsigned int timeslen = 0, fileposlen = 0, i; >> @@ -316,7 +358,7 @@ static int parse_keyframes_index(AVFormatContext *s, >> AVIOContext *ioc, >> int ret= AVERROR(ENOSYS); >> int64_t initial_pos= avio_tell(ioc); >> >> -if (vstream->nb_index_entries>0) { >> +if (flv->keyframe_count > 0) { >> av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); >> return 0; >> } > > this looks wrong, a file can contain an index for each stream > that shouldnt trigger a warning, only if there are 2 for the same > stream its a duplicate > > ok > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > What does censorship reveal? It reveals fear. -- Julian Assange > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Tue, Jul 26, 2016 at 08:17:46PM +0800, Xinzheng Zhang wrote: > --- > libavformat/flvdec.c | 84 > ++-- > 1 file changed, 69 insertions(+), 15 deletions(-) > > diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c > index 2bf1e05..82b9f83 100644 > --- a/libavformat/flvdec.c > +++ b/libavformat/flvdec.c > @@ -61,6 +61,12 @@ typedef struct FLVContext { > > int broken_sizes; > int sum_flv_tag_size; > + > +int vhead_exists; > +int ahead_exists; > +int keyframe_count; > +int64_t *keyframe_times; > +int64_t *keyframe_filepositions; > } FLVContext; > > static int probe(AVProbeData *p, int live) > @@ -92,6 +98,42 @@ static int live_flv_probe(AVProbeData *p) > return probe(p, 1); > } > > +static void add_keyframes_index(AVFormatContext *s) > +{ > +FLVContext *flv = s->priv_data; > +AVStream *current_stream = NULL; > +AVStream *vstream = NULL; > +AVStream *astream = NULL; > +unsigned int i,j; > + > +for (i = 0; i< s->nb_streams; i++) { > +if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { > +vstream = s->streams[i]; > +} else if (s->streams[i]->codecpar->codec_type == > AVMEDIA_TYPE_AUDIO) { > +astream = s->streams[i]; > +} > +} this shouldt be needed just keep track of the stram index that the table belongs to that is add a flv->keyframe_stream_index > + > +AVStream *streams[2] = {vstream, astream}; > +for (i = 0; i < 2; i++) { > +current_stream = streams[i]; > +if (current_stream && current_stream->nb_index_entries==0) { > +for (j = 0; j < flv->keyframe_count; j++) { > +av_add_index_entry(current_stream, > flv->keyframe_filepositions[j], flv->keyframe_times[j] * 1000, > + 0, 0, AVINDEX_KEYFRAME); > +} > +} > +} > + > +// free keyframe index only if all expected streams have been created > +if (((vstream && vstream->nb_index_entries>0) || !flv->vhead_exists) && > +((astream && astream->nb_index_entries>0) || !flv->ahead_exists)) { > +av_freep(&flv->keyframe_times); > +av_freep(&flv->keyframe_filepositions); > +flv->keyframe_count = 0; > +} > +} spliting add_keyframes_index() out must be in a seperate patch also i would not trust the *head_exists flags, IIRC they can be wrong and they are not needed the function should just take the table load it with av_add_index_entry() and free the table. The rest should not be needed should be much simpler unless iam missing something [...] > @@ -305,8 +348,7 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, > int buffsize) > return length; > } > > -static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, > - AVStream *vstream, int64_t max_pos) > +static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, > int64_t max_pos) > { > FLVContext *flv = s->priv_data; > unsigned int timeslen = 0, fileposlen = 0, i; > @@ -316,7 +358,7 @@ static int parse_keyframes_index(AVFormatContext *s, > AVIOContext *ioc, > int ret= AVERROR(ENOSYS); > int64_t initial_pos= avio_tell(ioc); > > -if (vstream->nb_index_entries>0) { > +if (flv->keyframe_count > 0) { > av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); > return 0; > } this looks wrong, a file can contain an index for each stream that shouldnt trigger a warning, only if there are 2 for the same stream its a duplicate [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB What does censorship reveal? It reveals fear. -- Julian Assange signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
--- libavformat/flvdec.c | 84 ++-- 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 2bf1e05..82b9f83 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -61,6 +61,12 @@ typedef struct FLVContext { int broken_sizes; int sum_flv_tag_size; + +int vhead_exists; +int ahead_exists; +int keyframe_count; +int64_t *keyframe_times; +int64_t *keyframe_filepositions; } FLVContext; static int probe(AVProbeData *p, int live) @@ -92,6 +98,42 @@ static int live_flv_probe(AVProbeData *p) return probe(p, 1); } +static void add_keyframes_index(AVFormatContext *s) +{ +FLVContext *flv = s->priv_data; +AVStream *current_stream = NULL; +AVStream *vstream = NULL; +AVStream *astream = NULL; +unsigned int i,j; + +for (i = 0; i< s->nb_streams; i++) { +if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { +vstream = s->streams[i]; +} else if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { +astream = s->streams[i]; +} +} + +AVStream *streams[2] = {vstream, astream}; +for (i = 0; i < 2; i++) { +current_stream = streams[i]; +if (current_stream && current_stream->nb_index_entries==0) { +for (j = 0; j < flv->keyframe_count; j++) { +av_add_index_entry(current_stream, flv->keyframe_filepositions[j], flv->keyframe_times[j] * 1000, + 0, 0, AVINDEX_KEYFRAME); +} +} +} + +// free keyframe index only if all expected streams have been created +if (((vstream && vstream->nb_index_entries>0) || !flv->vhead_exists) && +((astream && astream->nb_index_entries>0) || !flv->ahead_exists)) { +av_freep(&flv->keyframe_times); +av_freep(&flv->keyframe_filepositions); +flv->keyframe_count = 0; +} +} + static AVStream *create_stream(AVFormatContext *s, int codec_type) { AVStream *st = avformat_new_stream(s, NULL); @@ -104,6 +146,7 @@ static AVStream *create_stream(AVFormatContext *s, int codec_type) s->ctx_flags &= ~AVFMTCTX_NOHEADER; avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ +add_keyframes_index(s); return st; } @@ -305,8 +348,7 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) return length; } -static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, - AVStream *vstream, int64_t max_pos) +static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t max_pos) { FLVContext *flv = s->priv_data; unsigned int timeslen = 0, fileposlen = 0, i; @@ -316,7 +358,7 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int ret= AVERROR(ENOSYS); int64_t initial_pos= avio_tell(ioc); -if (vstream->nb_index_entries>0) { +if (flv->keyframe_count > 0) { av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); return 0; } @@ -324,6 +366,10 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, if (s->flags & AVFMT_FLAG_IGNIDX) return 0; +av_freep(&flv->keyframe_times); +av_freep(&flv->keyframe_filepositions); +flv->keyframe_count = 0; + while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { int64_t **current_array; @@ -366,17 +412,17 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, break; } } - if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) { -for (i = 0; i < fileposlen; i++) { -av_add_index_entry(vstream, filepositions[i], times[i] * 1000, - 0, 0, AVINDEX_KEYFRAME); -if (i < 2) { -flv->validate_index[i].pos = filepositions[i]; -flv->validate_index[i].dts = times[i] * 1000; -flv->validate_count= i + 1; -} +for (i = 0; i < FFMIN(2,fileposlen); i++) { +flv->validate_index[i].pos = filepositions[i]; +flv->validate_index[i].dts = times[i] * 1000; +flv->validate_count= i + 1; } +flv->keyframe_times = times; +flv->keyframe_filepositions = filepositions; +flv->keyframe_count = timeslen; +times = NULL; +filepositions = NULL; } else { invalid: av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n"); @@ -418,12 +464,14 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, } break; case AMF_DATA_TYPE_OBJECT: -if ((vstream || astream) && key && +if (key && ioc->seeka
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Mon, Jul 25, 2016 at 05:34:58PM +0800, XinZheng Zhang wrote: > On Mon, Jul 25, 2016 at 4:41 PM, Michael Niedermayer > wrote: > > On Thu, Jul 21, 2016 at 10:36:20AM +0800, Xinzheng Zhang wrote: > >> --- > >> libavformat/flvdec.c | 51 > >> --- > >> 1 file changed, 44 insertions(+), 7 deletions(-) > >> > >> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c > >> index 2bf1e05..b4fb4e2 100644 > >> --- a/libavformat/flvdec.c > >> +++ b/libavformat/flvdec.c > >> @@ -30,6 +30,7 @@ > >> #include "libavutil/opt.h" > >> #include "libavutil/intfloat.h" > >> #include "libavutil/mathematics.h" > >> +#include "libavutil/mem.h" > >> #include "libavcodec/bytestream.h" > >> #include "libavcodec/mpeg4audio.h" > >> #include "avformat.h" > >> @@ -41,6 +42,11 @@ > >> > >> #define RESYNC_BUFFER_SIZE (1<<20) > >> > >> +typedef struct FLVKeyFrame { > >> +int64_t pos; > >> +int64_t timestamp; > >> +} FLVKeyFrame; > > > > instead of adding a 3rd array the local arrays from parse_keyframes_index() > > could be moved into the context. That would reduce the memory needed > > > > ok > > > It also may be needed to keep 2 sets that is one per stream > > and the arrays should be freed after their use > > > > > > Is that mean we need to call av_add_index_entry() for both stream? no, but i am not sure if its guranteed that we never read both when it first looks like theres just an audio stream the audio index is loaded but when then a video index is found that is loaded i think maybe you could free the previous one in that case if you prefer to have only single set of arrays [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB You can kill me, but you cannot change the truth. signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Mon, Jul 25, 2016 at 4:41 PM, Michael Niedermayer wrote: > On Thu, Jul 21, 2016 at 10:36:20AM +0800, Xinzheng Zhang wrote: >> --- >> libavformat/flvdec.c | 51 >> --- >> 1 file changed, 44 insertions(+), 7 deletions(-) >> >> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c >> index 2bf1e05..b4fb4e2 100644 >> --- a/libavformat/flvdec.c >> +++ b/libavformat/flvdec.c >> @@ -30,6 +30,7 @@ >> #include "libavutil/opt.h" >> #include "libavutil/intfloat.h" >> #include "libavutil/mathematics.h" >> +#include "libavutil/mem.h" >> #include "libavcodec/bytestream.h" >> #include "libavcodec/mpeg4audio.h" >> #include "avformat.h" >> @@ -41,6 +42,11 @@ >> >> #define RESYNC_BUFFER_SIZE (1<<20) >> >> +typedef struct FLVKeyFrame { >> +int64_t pos; >> +int64_t timestamp; >> +} FLVKeyFrame; > > instead of adding a 3rd array the local arrays from parse_keyframes_index() > could be moved into the context. That would reduce the memory needed > ok > It also may be needed to keep 2 sets that is one per stream > and the arrays should be freed after their use > > Is that mean we need to call av_add_index_entry() for both stream? >> + >> typedef struct FLVContext { >> const AVClass *class; ///< Class for private options. >> int trust_metadata; ///< configure streams according onMetaData >> @@ -61,6 +67,10 @@ typedef struct FLVContext { >> >> int broken_sizes; >> int sum_flv_tag_size; >> + >> +int head_flags; //r8 >> +FLVKeyFrame *keyframes; >> +int keyframe_count; >> } FLVContext; >> >> static int probe(AVProbeData *p, int live) >> @@ -95,6 +105,9 @@ static int live_flv_probe(AVProbeData *p) >> static AVStream *create_stream(AVFormatContext *s, int codec_type) >> { >> AVStream *st = avformat_new_stream(s, NULL); >> +FLVContext *flv = s->priv_data; >> +int flags = flv->head_flags; >> +int i = 0; >> if (!st) >> return NULL; >> st->codecpar->codec_type = codec_type; >> @@ -104,6 +117,17 @@ static AVStream *create_stream(AVFormatContext *s, int >> codec_type) >> s->ctx_flags &= ~AVFMTCTX_NOHEADER; >> >> avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ >> +if ((!(flags & FLV_HEADER_FLAG_HASVIDEO) && codec_type == >> AVMEDIA_TYPE_AUDIO) || >> +(codec_type == AVMEDIA_TYPE_VIDEO) >> +) { >> +for (; i < flv->keyframe_count; i++) { >> +FLVKeyFrame *keyframe = &flv->keyframes[i]; >> +av_add_index_entry(st, keyframe->pos, keyframe->timestamp, >> + 0, 0, AVINDEX_KEYFRAME); >> +} >> +flv->keyframe_count = 0; >> +av_freep(&flv->keyframes); >> +} >> return st; >> } >> >> @@ -306,7 +330,7 @@ static int amf_get_string(AVIOContext *ioc, char >> *buffer, int buffsize) >> } >> >> static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, >> - AVStream *vstream, int64_t max_pos) >> + AVStream *vstream, AVStream *astream, >> int64_t max_pos) >> { >> FLVContext *flv = s->priv_data; >> unsigned int timeslen = 0, fileposlen = 0, i; >> @@ -315,8 +339,12 @@ static int parse_keyframes_index(AVFormatContext *s, >> AVIOContext *ioc, >> int64_t *filepositions = NULL; >> int ret= AVERROR(ENOSYS); >> int64_t initial_pos= avio_tell(ioc); >> +int head_flags = flv->head_flags; >> +AVStream *kf_stream= vstream; >> +if (!kf_stream && astream && (!(head_flags & FLV_HEADER_FLAG_HASVIDEO) >> && (head_flags & FLV_HEADER_FLAG_HASAUDIO))) >> +kf_stream = astream; >> >> -if (vstream->nb_index_entries>0) { >> +if (kf_stream && kf_stream->nb_index_entries > 0) { >> av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); >> return 0; >> } > >> @@ -369,8 +397,16 @@ static int parse_keyframes_index(AVFormatContext *s, >> AVIOContext *ioc, >> >> if (timeslen == fileposlen && fileposlen>1 && max_pos <= >> filepositions[0]) { >> for (i = 0; i < fileposlen; i++) { >> -av_add_index_entry(vstream, filepositions[i], times[i] * 1000, >> - 0, 0, AVINDEX_KEYFRAME); >> +if (kf_stream) { >> +av_add_index_entry(kf_stream, filepositions[i], times[i] * >> 1000, >> + 0, 0, AVINDEX_KEYFRAME); >> +} else { >> +FLVKeyFrame frame = {0}; >> +frame.pos = filepositions[i]; >> +frame.timestamp = times[i] * 1000; >> +av_dynarray2_add((void **)&flv->keyframes, >> &flv->keyframe_count,sizeof(FLVKeyFrame), (const uint8_t *)&frame); >> +} >> + >> if (i < 2) { >> flv->validate_index[i].pos = filepositions[i]; >> flv->validate_index[i].dts = times[i] * 1000; >> @@ -418,10 +4
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Thu, Jul 21, 2016 at 10:36:20AM +0800, Xinzheng Zhang wrote: > --- > libavformat/flvdec.c | 51 --- > 1 file changed, 44 insertions(+), 7 deletions(-) > > diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c > index 2bf1e05..b4fb4e2 100644 > --- a/libavformat/flvdec.c > +++ b/libavformat/flvdec.c > @@ -30,6 +30,7 @@ > #include "libavutil/opt.h" > #include "libavutil/intfloat.h" > #include "libavutil/mathematics.h" > +#include "libavutil/mem.h" > #include "libavcodec/bytestream.h" > #include "libavcodec/mpeg4audio.h" > #include "avformat.h" > @@ -41,6 +42,11 @@ > > #define RESYNC_BUFFER_SIZE (1<<20) > > +typedef struct FLVKeyFrame { > +int64_t pos; > +int64_t timestamp; > +} FLVKeyFrame; instead of adding a 3rd array the local arrays from parse_keyframes_index() could be moved into the context. That would reduce the memory needed It also may be needed to keep 2 sets that is one per stream and the arrays should be freed after their use > + > typedef struct FLVContext { > const AVClass *class; ///< Class for private options. > int trust_metadata; ///< configure streams according onMetaData > @@ -61,6 +67,10 @@ typedef struct FLVContext { > > int broken_sizes; > int sum_flv_tag_size; > + > +int head_flags; //r8 > +FLVKeyFrame *keyframes; > +int keyframe_count; > } FLVContext; > > static int probe(AVProbeData *p, int live) > @@ -95,6 +105,9 @@ static int live_flv_probe(AVProbeData *p) > static AVStream *create_stream(AVFormatContext *s, int codec_type) > { > AVStream *st = avformat_new_stream(s, NULL); > +FLVContext *flv = s->priv_data; > +int flags = flv->head_flags; > +int i = 0; > if (!st) > return NULL; > st->codecpar->codec_type = codec_type; > @@ -104,6 +117,17 @@ static AVStream *create_stream(AVFormatContext *s, int > codec_type) > s->ctx_flags &= ~AVFMTCTX_NOHEADER; > > avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ > +if ((!(flags & FLV_HEADER_FLAG_HASVIDEO) && codec_type == > AVMEDIA_TYPE_AUDIO) || > +(codec_type == AVMEDIA_TYPE_VIDEO) > +) { > +for (; i < flv->keyframe_count; i++) { > +FLVKeyFrame *keyframe = &flv->keyframes[i]; > +av_add_index_entry(st, keyframe->pos, keyframe->timestamp, > + 0, 0, AVINDEX_KEYFRAME); > +} > +flv->keyframe_count = 0; > +av_freep(&flv->keyframes); > +} > return st; > } > > @@ -306,7 +330,7 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, > int buffsize) > } > > static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, > - AVStream *vstream, int64_t max_pos) > + AVStream *vstream, AVStream *astream, > int64_t max_pos) > { > FLVContext *flv = s->priv_data; > unsigned int timeslen = 0, fileposlen = 0, i; > @@ -315,8 +339,12 @@ static int parse_keyframes_index(AVFormatContext *s, > AVIOContext *ioc, > int64_t *filepositions = NULL; > int ret= AVERROR(ENOSYS); > int64_t initial_pos= avio_tell(ioc); > +int head_flags = flv->head_flags; > +AVStream *kf_stream= vstream; > +if (!kf_stream && astream && (!(head_flags & FLV_HEADER_FLAG_HASVIDEO) > && (head_flags & FLV_HEADER_FLAG_HASAUDIO))) > +kf_stream = astream; > > -if (vstream->nb_index_entries>0) { > +if (kf_stream && kf_stream->nb_index_entries > 0) { > av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); > return 0; > } > @@ -369,8 +397,16 @@ static int parse_keyframes_index(AVFormatContext *s, > AVIOContext *ioc, > > if (timeslen == fileposlen && fileposlen>1 && max_pos <= > filepositions[0]) { > for (i = 0; i < fileposlen; i++) { > -av_add_index_entry(vstream, filepositions[i], times[i] * 1000, > - 0, 0, AVINDEX_KEYFRAME); > +if (kf_stream) { > +av_add_index_entry(kf_stream, filepositions[i], times[i] * > 1000, > + 0, 0, AVINDEX_KEYFRAME); > +} else { > +FLVKeyFrame frame = {0}; > +frame.pos = filepositions[i]; > +frame.timestamp = times[i] * 1000; > +av_dynarray2_add((void **)&flv->keyframes, > &flv->keyframe_count,sizeof(FLVKeyFrame), (const uint8_t *)&frame); > +} > + > if (i < 2) { > flv->validate_index[i].pos = filepositions[i]; > flv->validate_index[i].dts = times[i] * 1000; > @@ -418,10 +454,10 @@ static int amf_parse_object(AVFormatContext *s, > AVStream *astream, maybe the filepositions/times -> av_add_index_entry() code can be split out of parse_keyframes_index() in a seperate patch that way parse_keyframes_index() would always do th
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
2016-07-25 10:29 GMT+08:00 XinZheng Zhang : > Ping. > > On Thu, Jul 21, 2016 at 11:59 AM, XinZheng Zhang > wrote: > > On Thu, Jul 21, 2016 at 5:03 AM, Moritz Barsnick > wrote: > >> On Thu, Jul 21, 2016 at 00:06:44 +0800, zhangxinzheng wrote: > >> > >>> Subject: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes > before video or audio stream was created > >>^^^ flv > >> > >>> There has an error when seeking in a flv file, which key frames was > >>> sorted before video frame. > >>> This ensures that all the key frames was cached, and add to > >>> corresponding stream when it was created. > >> > >> Thanks to the grammar, I don't understand the intent of the patch. > >> (Don't get me wrong, I'm not scorning your English, but it needs to be > >> improved.) > >> > > > > In flvdec.c 420 > > case AMF_DATA_TYPE_OBJECT: > > if ((vstream || astream) && key && > > ioc->seekable && > > !strcmp(KEYFRAMES_TAG, key) && depth == 1) > > if (parse_keyframes_index(s, ioc, vstream ? vstream : astream, > > max_pos) < 0) > > > > If the first packet we got is object, both vstream and astream are NULL, > > that may prevent keyframe index being parsed. > > > > This patch saves keyframe index before A/V streams are created. > > > > The issue was introduced since 09ae7b81ea. > > > > I have created a ticket #5729 with a sample attatched. > > > >>> #define RESYNC_BUFFER_SIZE (1<<20) > >>> > >>> + > >>> +typedef struct FLVKeyFrame { > >> > >> Why the extra newline? > >> > > > https://trac.ffmpeg.org/ticket/5729#comment:1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
Ping. On Thu, Jul 21, 2016 at 11:59 AM, XinZheng Zhang wrote: > On Thu, Jul 21, 2016 at 5:03 AM, Moritz Barsnick wrote: >> On Thu, Jul 21, 2016 at 00:06:44 +0800, zhangxinzheng wrote: >> >>> Subject: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before >>> video or audio stream was created >>^^^ flv >> >>> There has an error when seeking in a flv file, which key frames was >>> sorted before video frame. >>> This ensures that all the key frames was cached, and add to >>> corresponding stream when it was created. >> >> Thanks to the grammar, I don't understand the intent of the patch. >> (Don't get me wrong, I'm not scorning your English, but it needs to be >> improved.) >> > > In flvdec.c 420 > case AMF_DATA_TYPE_OBJECT: > if ((vstream || astream) && key && > ioc->seekable && > !strcmp(KEYFRAMES_TAG, key) && depth == 1) > if (parse_keyframes_index(s, ioc, vstream ? vstream : astream, > max_pos) < 0) > > If the first packet we got is object, both vstream and astream are NULL, > that may prevent keyframe index being parsed. > > This patch saves keyframe index before A/V streams are created. > > The issue was introduced since 09ae7b81ea. > > I have created a ticket #5729 with a sample attatched. > >>> #define RESYNC_BUFFER_SIZE (1<<20) >>> >>> + >>> +typedef struct FLVKeyFrame { >> >> Why the extra newline? >> > > The extra newline has been removed in new patch. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Thu, Jul 21, 2016 at 5:03 AM, Moritz Barsnick wrote: > On Thu, Jul 21, 2016 at 00:06:44 +0800, zhangxinzheng wrote: > >> Subject: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before >> video or audio stream was created >^^^ flv > >> There has an error when seeking in a flv file, which key frames was >> sorted before video frame. >> This ensures that all the key frames was cached, and add to >> corresponding stream when it was created. > > Thanks to the grammar, I don't understand the intent of the patch. > (Don't get me wrong, I'm not scorning your English, but it needs to be > improved.) > In flvdec.c 420 case AMF_DATA_TYPE_OBJECT: if ((vstream || astream) && key && ioc->seekable && !strcmp(KEYFRAMES_TAG, key) && depth == 1) if (parse_keyframes_index(s, ioc, vstream ? vstream : astream, max_pos) < 0) If the first packet we got is object, both vstream and astream are NULL, that may prevent keyframe index being parsed. This patch saves keyframe index before A/V streams are created. The issue was introduced since 09ae7b81ea. I have created a ticket #5729 with a sample attatched. >> #define RESYNC_BUFFER_SIZE (1<<20) >> >> + >> +typedef struct FLVKeyFrame { > > Why the extra newline? > The extra newline has been removed in new patch. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
2016-07-21 10:35 GMT+08:00 XinZheng Zhang : > I apologize about my English and let me re-arrange my words. > The current realization would result in the loss of all key frame > indices from all the current video frames, > which would lead to the failure of seeking in FLVs. > My current patch will cache all key frame indices without creating any > video streams, > and put in all those immediately after creating any relevant video streams. > > I found that there has something error with my `egrep`, > caused all the patches (include applied patch) could not be checked > successfully. > The error message is same to the log which Steven Liu posted. > Here is my platform message: > egrep (BSD grep) 2.5.1-FreeBSD > osx 10.11.4 > > Your patch is passed by tool/patcheck, and is have read your patch, it read the keyframe ts and pos from metadata, is see, Perhaps it's usefull when the flv is TOO BIG, Thanks! > > I will resend a new patch without the extra new line. > > On Thu, Jul 21, 2016 at 7:39 AM, Steven Liu > wrote: > > 2016-07-21 7:29 GMT+08:00 Steven Liu : > > > >> > >> > >> 2016-07-21 5:03 GMT+08:00 Moritz Barsnick : > >> > >>> On Thu, Jul 21, 2016 at 00:06:44 +0800, zhangxinzheng wrote: > >>> > >>> > Subject: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes > >>> before video or audio stream was created > >>>^^^ flv > >>> > >>> > There has an error when seeking in a flv file, which key frames was > >>> > sorted before video frame. > >>> > This ensures that all the key frames was cached, and add to > >>> > corresponding stream when it was created. > >>> > >>> Thanks to the grammar, I don't understand the intent of the patch. > >>> (Don't get me wrong, I'm not scorning your English, but it needs to be > >>> improved.) > >>> > >> Hi Moritz, > >> Perhaps he want to create a keyframe index for flv file, to seek flv > >> keyframe. > >> > >> > >> > >>> > #define RESYNC_BUFFER_SIZE (1<<20) > >>> > > >>> > + > >>> > +typedef struct FLVKeyFrame { > >>> > >>> Why the extra newline? > >> > >> > >> Hi Zhang Xinzheng , > >> > >> You should check the patch use the tool at ./tools/patcheck . > >> Please reading > >> http://ffmpeg.org/developer.html#toc-Submitting-patches-1 . > >> > > ok, I make a mistake, the patchcheck can not check the newline > > > > > > > > localhost:ffmpeg StevenLiu$ cat new_patch.patch | head -n 30 > > --- > > libavformat/flvdec.c | 52 > > +--- > > 1 file changed, 45 insertions(+), 7 deletions(-) > > > > diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c > > index 2bf1e05..8a73b68 100644 > > --- a/libavformat/flvdec.c > > +++ b/libavformat/flvdec.c > > @@ -30,6 +30,7 @@ > > #include "libavutil/opt.h" > > #include "libavutil/intfloat.h" > > #include "libavutil/mathematics.h" > > +#include "libavutil/mem.h" > > #include "libavcodec/bytestream.h" > > #include "libavcodec/mpeg4audio.h" > > #include "avformat.h" > > @@ -41,6 +42,12 @@ > > > > #define RESYNC_BUFFER_SIZE (1<<20) > > > > + > > +typedef struct FLVKeyFrame { > > +int64_t pos; > > +int64_t timestamp; > > +} FLVKeyFrame; > > + > > typedef struct FLVContext { > > const AVClass *class; ///< Class for private options. > > int trust_metadata; ///< configure streams according onMetaData > > @@ -61,6 +68,10 @@ typedef struct FLVContext { > > localhost:ffmpeg StevenLiu$ > > localhost:ffmpeg StevenLiu$ ./tools/patcheck new_patch.patch > > patCHeck 1e10.0 > > This tool is intended to help a human check/review patches. It is very > far > > from > > being free of false positives and negatives, and its output are just > hints > > of what > > may or may not be bad. When you use it and it misses something or detects > > something wrong, fix it and send a patch to the ffmpeg-devel mailing > list. > > License: GPL, Author: Michael Niedermayer > > egrep: empty (sub)expression > > egrep: empty (sub)expression > > egrep: empty (sub)expression > > egrep: empty (sub)expression > > egrep: empty (sub)expression > > egrep: empty (sub)expression > > egrep: empty (sub)expression > > egrep: empty (sub)expression > > egrep: empty (sub)expression > > egrep: empty (sub)expression > > egrep: empty (sub)expression > > xargs: illegal option -- d > > usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J > replstr] > > [-L number] [-n number [-x]] [-P maxprocs] [-s size] > > [utility [argument ...]] > > > > Missing changelog entry (ignore if minor change) > > egrep: empty (sub)expression > > localhost:ffmpeg StevenLiu$ > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
--- libavformat/flvdec.c | 51 --- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 2bf1e05..b4fb4e2 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -30,6 +30,7 @@ #include "libavutil/opt.h" #include "libavutil/intfloat.h" #include "libavutil/mathematics.h" +#include "libavutil/mem.h" #include "libavcodec/bytestream.h" #include "libavcodec/mpeg4audio.h" #include "avformat.h" @@ -41,6 +42,11 @@ #define RESYNC_BUFFER_SIZE (1<<20) +typedef struct FLVKeyFrame { +int64_t pos; +int64_t timestamp; +} FLVKeyFrame; + typedef struct FLVContext { const AVClass *class; ///< Class for private options. int trust_metadata; ///< configure streams according onMetaData @@ -61,6 +67,10 @@ typedef struct FLVContext { int broken_sizes; int sum_flv_tag_size; + +int head_flags; //r8 +FLVKeyFrame *keyframes; +int keyframe_count; } FLVContext; static int probe(AVProbeData *p, int live) @@ -95,6 +105,9 @@ static int live_flv_probe(AVProbeData *p) static AVStream *create_stream(AVFormatContext *s, int codec_type) { AVStream *st = avformat_new_stream(s, NULL); +FLVContext *flv = s->priv_data; +int flags = flv->head_flags; +int i = 0; if (!st) return NULL; st->codecpar->codec_type = codec_type; @@ -104,6 +117,17 @@ static AVStream *create_stream(AVFormatContext *s, int codec_type) s->ctx_flags &= ~AVFMTCTX_NOHEADER; avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ +if ((!(flags & FLV_HEADER_FLAG_HASVIDEO) && codec_type == AVMEDIA_TYPE_AUDIO) || +(codec_type == AVMEDIA_TYPE_VIDEO) +) { +for (; i < flv->keyframe_count; i++) { +FLVKeyFrame *keyframe = &flv->keyframes[i]; +av_add_index_entry(st, keyframe->pos, keyframe->timestamp, + 0, 0, AVINDEX_KEYFRAME); +} +flv->keyframe_count = 0; +av_freep(&flv->keyframes); +} return st; } @@ -306,7 +330,7 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) } static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, - AVStream *vstream, int64_t max_pos) + AVStream *vstream, AVStream *astream, int64_t max_pos) { FLVContext *flv = s->priv_data; unsigned int timeslen = 0, fileposlen = 0, i; @@ -315,8 +339,12 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t *filepositions = NULL; int ret= AVERROR(ENOSYS); int64_t initial_pos= avio_tell(ioc); +int head_flags = flv->head_flags; +AVStream *kf_stream= vstream; +if (!kf_stream && astream && (!(head_flags & FLV_HEADER_FLAG_HASVIDEO) && (head_flags & FLV_HEADER_FLAG_HASAUDIO))) +kf_stream = astream; -if (vstream->nb_index_entries>0) { +if (kf_stream && kf_stream->nb_index_entries > 0) { av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); return 0; } @@ -369,8 +397,16 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) { for (i = 0; i < fileposlen; i++) { -av_add_index_entry(vstream, filepositions[i], times[i] * 1000, - 0, 0, AVINDEX_KEYFRAME); +if (kf_stream) { +av_add_index_entry(kf_stream, filepositions[i], times[i] * 1000, + 0, 0, AVINDEX_KEYFRAME); +} else { +FLVKeyFrame frame = {0}; +frame.pos = filepositions[i]; +frame.timestamp = times[i] * 1000; +av_dynarray2_add((void **)&flv->keyframes, &flv->keyframe_count,sizeof(FLVKeyFrame), (const uint8_t *)&frame); +} + if (i < 2) { flv->validate_index[i].pos = filepositions[i]; flv->validate_index[i].dts = times[i] * 1000; @@ -418,10 +454,10 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, } break; case AMF_DATA_TYPE_OBJECT: -if ((vstream || astream) && key && +if (key && ioc->seekable && !strcmp(KEYFRAMES_TAG, key) && depth == 1) -if (parse_keyframes_index(s, ioc, vstream ? vstream : astream, +if (parse_keyframes_index(s, ioc, vstream, astream, max_pos) < 0) av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n"); @@ -633,7 +669,7 @@ static int flv_read_header(AVFormatContext *s) int offset; avio_skip(s->pb, 4); -avio_r8(s->pb); // flags +flv->head_flags = avio_r8(s->pb); // flags s->ctx_flags |= AVFMTCTX_NOHEADER; @@ -653,6 +689,7 @@ sta
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
I apologize about my English and let me re-arrange my words. The current realization would result in the loss of all key frame indices from all the current video frames, which would lead to the failure of seeking in FLVs. My current patch will cache all key frame indices without creating any video streams, and put in all those immediately after creating any relevant video streams. I found that there has something error with my `egrep`, caused all the patches (include applied patch) could not be checked successfully. The error message is same to the log which Steven Liu posted. Here is my platform message: egrep (BSD grep) 2.5.1-FreeBSD osx 10.11.4 I will resend a new patch without the extra new line. On Thu, Jul 21, 2016 at 7:39 AM, Steven Liu wrote: > 2016-07-21 7:29 GMT+08:00 Steven Liu : > >> >> >> 2016-07-21 5:03 GMT+08:00 Moritz Barsnick : >> >>> On Thu, Jul 21, 2016 at 00:06:44 +0800, zhangxinzheng wrote: >>> >>> > Subject: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes >>> before video or audio stream was created >>>^^^ flv >>> >>> > There has an error when seeking in a flv file, which key frames was >>> > sorted before video frame. >>> > This ensures that all the key frames was cached, and add to >>> > corresponding stream when it was created. >>> >>> Thanks to the grammar, I don't understand the intent of the patch. >>> (Don't get me wrong, I'm not scorning your English, but it needs to be >>> improved.) >>> >> Hi Moritz, >> Perhaps he want to create a keyframe index for flv file, to seek flv >> keyframe. >> >> >> >>> > #define RESYNC_BUFFER_SIZE (1<<20) >>> > >>> > + >>> > +typedef struct FLVKeyFrame { >>> >>> Why the extra newline? >> >> >> Hi Zhang Xinzheng , >> >> You should check the patch use the tool at ./tools/patcheck . >> Please reading >> http://ffmpeg.org/developer.html#toc-Submitting-patches-1 . >> > ok, I make a mistake, the patchcheck can not check the newline > > > > localhost:ffmpeg StevenLiu$ cat new_patch.patch | head -n 30 > --- > libavformat/flvdec.c | 52 > +--- > 1 file changed, 45 insertions(+), 7 deletions(-) > > diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c > index 2bf1e05..8a73b68 100644 > --- a/libavformat/flvdec.c > +++ b/libavformat/flvdec.c > @@ -30,6 +30,7 @@ > #include "libavutil/opt.h" > #include "libavutil/intfloat.h" > #include "libavutil/mathematics.h" > +#include "libavutil/mem.h" > #include "libavcodec/bytestream.h" > #include "libavcodec/mpeg4audio.h" > #include "avformat.h" > @@ -41,6 +42,12 @@ > > #define RESYNC_BUFFER_SIZE (1<<20) > > + > +typedef struct FLVKeyFrame { > +int64_t pos; > +int64_t timestamp; > +} FLVKeyFrame; > + > typedef struct FLVContext { > const AVClass *class; ///< Class for private options. > int trust_metadata; ///< configure streams according onMetaData > @@ -61,6 +68,10 @@ typedef struct FLVContext { > localhost:ffmpeg StevenLiu$ > localhost:ffmpeg StevenLiu$ ./tools/patcheck new_patch.patch > patCHeck 1e10.0 > This tool is intended to help a human check/review patches. It is very far > from > being free of false positives and negatives, and its output are just hints > of what > may or may not be bad. When you use it and it misses something or detects > something wrong, fix it and send a patch to the ffmpeg-devel mailing list. > License: GPL, Author: Michael Niedermayer > egrep: empty (sub)expression > egrep: empty (sub)expression > egrep: empty (sub)expression > egrep: empty (sub)expression > egrep: empty (sub)expression > egrep: empty (sub)expression > egrep: empty (sub)expression > egrep: empty (sub)expression > egrep: empty (sub)expression > egrep: empty (sub)expression > egrep: empty (sub)expression > xargs: illegal option -- d > usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr] > [-L number] [-n number [-x]] [-P maxprocs] [-s size] > [utility [argument ...]] > > Missing changelog entry (ignore if minor change) > egrep: empty (sub)expression > localhost:ffmpeg StevenLiu$ > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
2016-07-21 7:29 GMT+08:00 Steven Liu : > > > 2016-07-21 5:03 GMT+08:00 Moritz Barsnick : > >> On Thu, Jul 21, 2016 at 00:06:44 +0800, zhangxinzheng wrote: >> >> > Subject: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes >> before video or audio stream was created >>^^^ flv >> >> > There has an error when seeking in a flv file, which key frames was >> > sorted before video frame. >> > This ensures that all the key frames was cached, and add to >> > corresponding stream when it was created. >> >> Thanks to the grammar, I don't understand the intent of the patch. >> (Don't get me wrong, I'm not scorning your English, but it needs to be >> improved.) >> > Hi Moritz, > Perhaps he want to create a keyframe index for flv file, to seek flv > keyframe. > > > >> > #define RESYNC_BUFFER_SIZE (1<<20) >> > >> > + >> > +typedef struct FLVKeyFrame { >> >> Why the extra newline? > > > Hi Zhang Xinzheng , > > You should check the patch use the tool at ./tools/patcheck . > Please reading > http://ffmpeg.org/developer.html#toc-Submitting-patches-1 . > ok, I make a mistake, the patchcheck can not check the newline localhost:ffmpeg StevenLiu$ cat new_patch.patch | head -n 30 --- libavformat/flvdec.c | 52 +--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 2bf1e05..8a73b68 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -30,6 +30,7 @@ #include "libavutil/opt.h" #include "libavutil/intfloat.h" #include "libavutil/mathematics.h" +#include "libavutil/mem.h" #include "libavcodec/bytestream.h" #include "libavcodec/mpeg4audio.h" #include "avformat.h" @@ -41,6 +42,12 @@ #define RESYNC_BUFFER_SIZE (1<<20) + +typedef struct FLVKeyFrame { +int64_t pos; +int64_t timestamp; +} FLVKeyFrame; + typedef struct FLVContext { const AVClass *class; ///< Class for private options. int trust_metadata; ///< configure streams according onMetaData @@ -61,6 +68,10 @@ typedef struct FLVContext { localhost:ffmpeg StevenLiu$ localhost:ffmpeg StevenLiu$ ./tools/patcheck new_patch.patch patCHeck 1e10.0 This tool is intended to help a human check/review patches. It is very far from being free of false positives and negatives, and its output are just hints of what may or may not be bad. When you use it and it misses something or detects something wrong, fix it and send a patch to the ffmpeg-devel mailing list. License: GPL, Author: Michael Niedermayer egrep: empty (sub)expression egrep: empty (sub)expression egrep: empty (sub)expression egrep: empty (sub)expression egrep: empty (sub)expression egrep: empty (sub)expression egrep: empty (sub)expression egrep: empty (sub)expression egrep: empty (sub)expression egrep: empty (sub)expression egrep: empty (sub)expression xargs: illegal option -- d usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr] [-L number] [-n number [-x]] [-P maxprocs] [-s size] [utility [argument ...]] Missing changelog entry (ignore if minor change) egrep: empty (sub)expression localhost:ffmpeg StevenLiu$ ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
2016-07-21 5:03 GMT+08:00 Moritz Barsnick : > On Thu, Jul 21, 2016 at 00:06:44 +0800, zhangxinzheng wrote: > > > Subject: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before > video or audio stream was created >^^^ flv > > > There has an error when seeking in a flv file, which key frames was > > sorted before video frame. > > This ensures that all the key frames was cached, and add to > > corresponding stream when it was created. > > Thanks to the grammar, I don't understand the intent of the patch. > (Don't get me wrong, I'm not scorning your English, but it needs to be > improved.) > Hi Moritz, Perhaps he want to create a keyframe index for flv file, to seek flv keyframe. > > #define RESYNC_BUFFER_SIZE (1<<20) > > > > + > > +typedef struct FLVKeyFrame { > > Why the extra newline? Hi Zhang Xinzheng , You should check the patch use the tool at ./tools/patcheck . Please reading http://ffmpeg.org/developer.html#toc-Submitting-patches-1 . ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
On Thu, Jul 21, 2016 at 00:06:44 +0800, zhangxinzheng wrote: > Subject: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before > video or audio stream was created ^^^ flv > There has an error when seeking in a flv file, which key frames was > sorted before video frame. > This ensures that all the key frames was cached, and add to > corresponding stream when it was created. Thanks to the grammar, I don't understand the intent of the patch. (Don't get me wrong, I'm not scorning your English, but it needs to be improved.) > #define RESYNC_BUFFER_SIZE (1<<20) > > + > +typedef struct FLVKeyFrame { Why the extra newline? Moritz ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
From: Xinzheng Zhang There has an error when seeking in a flv file, which key frames was sorted before video frame. This ensures that all the key frames was cached, and add to corresponding stream when it was created. --- libavformat/flvdec.c | 52 +--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 2bf1e05..8a73b68 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -30,6 +30,7 @@ #include "libavutil/opt.h" #include "libavutil/intfloat.h" #include "libavutil/mathematics.h" +#include "libavutil/mem.h" #include "libavcodec/bytestream.h" #include "libavcodec/mpeg4audio.h" #include "avformat.h" @@ -41,6 +42,12 @@ #define RESYNC_BUFFER_SIZE (1<<20) + +typedef struct FLVKeyFrame { +int64_t pos; +int64_t timestamp; +} FLVKeyFrame; + typedef struct FLVContext { const AVClass *class; ///< Class for private options. int trust_metadata; ///< configure streams according onMetaData @@ -61,6 +68,10 @@ typedef struct FLVContext { int broken_sizes; int sum_flv_tag_size; + +int head_flags; //r8 +FLVKeyFrame *keyframes; +int keyframe_count; } FLVContext; static int probe(AVProbeData *p, int live) @@ -95,6 +106,9 @@ static int live_flv_probe(AVProbeData *p) static AVStream *create_stream(AVFormatContext *s, int codec_type) { AVStream *st = avformat_new_stream(s, NULL); +FLVContext *flv = s->priv_data; +int flags = flv->head_flags; +int i = 0; if (!st) return NULL; st->codecpar->codec_type = codec_type; @@ -104,6 +118,17 @@ static AVStream *create_stream(AVFormatContext *s, int codec_type) s->ctx_flags &= ~AVFMTCTX_NOHEADER; avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ +if ((!(flags & FLV_HEADER_FLAG_HASVIDEO) && codec_type == AVMEDIA_TYPE_AUDIO) || +(codec_type == AVMEDIA_TYPE_VIDEO) +) { +for (; i < flv->keyframe_count; i++) { +FLVKeyFrame *keyframe = &flv->keyframes[i]; +av_add_index_entry(st, keyframe->pos, keyframe->timestamp, + 0, 0, AVINDEX_KEYFRAME); +} +flv->keyframe_count = 0; +av_freep(&flv->keyframes); +} return st; } @@ -306,7 +331,7 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) } static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, - AVStream *vstream, int64_t max_pos) + AVStream *vstream, AVStream *astream, int64_t max_pos) { FLVContext *flv = s->priv_data; unsigned int timeslen = 0, fileposlen = 0, i; @@ -315,8 +340,12 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t *filepositions = NULL; int ret= AVERROR(ENOSYS); int64_t initial_pos= avio_tell(ioc); +int head_flags = flv->head_flags; +AVStream *kf_stream= vstream; +if (!kf_stream && astream && (!(head_flags & FLV_HEADER_FLAG_HASVIDEO) && (head_flags & FLV_HEADER_FLAG_HASAUDIO))) +kf_stream = astream; -if (vstream->nb_index_entries>0) { +if (kf_stream && kf_stream->nb_index_entries > 0) { av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); return 0; } @@ -369,8 +398,16 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) { for (i = 0; i < fileposlen; i++) { -av_add_index_entry(vstream, filepositions[i], times[i] * 1000, - 0, 0, AVINDEX_KEYFRAME); +if (kf_stream) { +av_add_index_entry(kf_stream, filepositions[i], times[i] * 1000, + 0, 0, AVINDEX_KEYFRAME); +} else { +FLVKeyFrame frame = {0}; +frame.pos = filepositions[i]; +frame.timestamp = times[i] * 1000; +av_dynarray2_add((void **)&flv->keyframes, &flv->keyframe_count,sizeof(FLVKeyFrame), (const uint8_t *)&frame); +} + if (i < 2) { flv->validate_index[i].pos = filepositions[i]; flv->validate_index[i].dts = times[i] * 1000; @@ -418,10 +455,10 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, } break; case AMF_DATA_TYPE_OBJECT: -if ((vstream || astream) && key && +if (key && ioc->seekable && !strcmp(KEYFRAMES_TAG, key) && depth == 1) -if (parse_keyframes_index(s, ioc, vstream ? vstream : astream, +if (parse_keyframes_index(s, ioc, vstream, astream, max_pos) < 0) av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n"); @@ -633,7 +670,7 @@ static int flv
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
XinZheng Zhang 于2016年7月20日 周三下午11:05写道: > What are you meaning for the original mail? > > On Wed, Jul 20, 2016 at 10:24 PM, Steven Liu > wrote: > > > > > > 2016-07-20 21:46 GMT+08:00 XinZheng Zhang : > >> > >> There has an error when seeking in a flv file, which key frames was > >> sorted before video frame. > >> This ensures that all the key frames was cached, and add to > >> corresponding stream when it was created. > >> > >> On Wed, Jul 20, 2016 at 9:30 PM, zhangxinzheng > >> wrote: > >> > From: Xinzheng Zhang > >> > > >> > --- > >> > libavformat/flvdec.c | 52 > >> > +--- > >> > 1 file changed, 45 insertions(+), 7 deletions(-) > >> > > >> > diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c > >> > index 2bf1e05..8a73b68 100644 > >> > --- a/libavformat/flvdec.c > >> > +++ b/libavformat/flvdec.c > >> > @@ -30,6 +30,7 @@ > >> > #include "libavutil/opt.h" > >> > #include "libavutil/intfloat.h" > >> > #include "libavutil/mathematics.h" > >> > +#include "libavutil/mem.h" > >> > #include "libavcodec/bytestream.h" > >> > #include "libavcodec/mpeg4audio.h" > >> > #include "avformat.h" > >> > @@ -41,6 +42,12 @@ > >> > > >> > #define RESYNC_BUFFER_SIZE (1<<20) > >> > > >> > + > >> > +typedef struct FLVKeyFrame { > >> > +int64_t pos; > >> > +int64_t timestamp; > >> > +} FLVKeyFrame; > >> > + > >> > typedef struct FLVContext { > >> > const AVClass *class; ///< Class for private options. > >> > int trust_metadata; ///< configure streams according onMetaData > >> > @@ -61,6 +68,10 @@ typedef struct FLVContext { > >> > > >> > int broken_sizes; > >> > int sum_flv_tag_size; > >> > + > >> > +int head_flags; //r8 > >> > +FLVKeyFrame *keyframes; > >> > +int keyframe_count; > >> > } FLVContext; > >> > > >> > static int probe(AVProbeData *p, int live) > >> > @@ -95,6 +106,9 @@ static int live_flv_probe(AVProbeData *p) > >> > static AVStream *create_stream(AVFormatContext *s, int codec_type) > >> > { > >> > AVStream *st = avformat_new_stream(s, NULL); > >> > +FLVContext *flv = s->priv_data; > >> > +int flags = flv->head_flags; > >> > +int i = 0; > >> > if (!st) > >> > return NULL; > >> > st->codecpar->codec_type = codec_type; > >> > @@ -104,6 +118,17 @@ static AVStream *create_stream(AVFormatContext > *s, > >> > int codec_type) > >> > s->ctx_flags &= ~AVFMTCTX_NOHEADER; > >> > > >> > avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ > >> > +if ((!(flags & FLV_HEADER_FLAG_HASVIDEO) && codec_type == > >> > AVMEDIA_TYPE_AUDIO) || > >> > +(codec_type == AVMEDIA_TYPE_VIDEO) > >> > +) { > >> > +for (; i < flv->keyframe_count; i++) { > >> > +FLVKeyFrame *keyframe = &flv->keyframes[i]; > >> > +av_add_index_entry(st, keyframe->pos, > keyframe->timestamp, > >> > + 0, 0, AVINDEX_KEYFRAME); > >> > +} > >> > +flv->keyframe_count = 0; > >> > +av_freep(&flv->keyframes); > >> > +} > >> > return st; > >> > } > >> > > >> > @@ -306,7 +331,7 @@ static int amf_get_string(AVIOContext *ioc, char > >> > *buffer, int buffsize) > >> > } > >> > > >> > static int parse_keyframes_index(AVFormatContext *s, AVIOContext > *ioc, > >> > - AVStream *vstream, int64_t max_pos) > >> > + AVStream *vstream, AVStream > *astream, > >> > int64_t max_pos) > >> > { > >> > FLVContext *flv = s->priv_data; > >> > unsigned int timeslen = 0, fileposlen = 0, i; > >> > @@ -315,8 +340,12 @@ static int parse_keyframes_index(AVFormatContext > >> > *s, AVIOContext *ioc, > >> > int64_t *filepositions = NULL; > >> > int ret= AVERROR(ENOSYS); > >> > int64_t initial_pos= avio_tell(ioc); > >> > +int head_flags = flv->head_flags; > >> > +AVStream *kf_stream= vstream; > >> > +if (!kf_stream && astream && (!(head_flags & > >> > FLV_HEADER_FLAG_HASVIDEO) && (head_flags & FLV_HEADER_FLAG_HASAUDIO))) > >> > +kf_stream = astream; > >> > > >> > -if (vstream->nb_index_entries>0) { > >> > +if (kf_stream && kf_stream->nb_index_entries > 0) { > >> > av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); > >> > return 0; > >> > } > >> > @@ -369,8 +398,16 @@ static int parse_keyframes_index(AVFormatContext > >> > *s, AVIOContext *ioc, > >> > > >> > if (timeslen == fileposlen && fileposlen>1 && max_pos <= > >> > filepositions[0]) { > >> > for (i = 0; i < fileposlen; i++) { > >> > -av_add_index_entry(vstream, filepositions[i], times[i] * > >> > 1000, > >> > - 0, 0, AVINDEX_KEYFRAME); > >> > +if (kf_stream) { > >> > +av_add_index_entry(kf_stream, filepositions[i], > >> > times[i] * 1000, > >> > + 0, 0, AVINDEX_KEYFRAME); >
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
2016-07-20 21:46 GMT+08:00 XinZheng Zhang : > There has an error when seeking in a flv file, which key frames was > sorted before video frame. > This ensures that all the key frames was cached, and add to > corresponding stream when it was created. > > On Wed, Jul 20, 2016 at 9:30 PM, zhangxinzheng > wrote: > > From: Xinzheng Zhang > > > > --- > > libavformat/flvdec.c | 52 > +--- > > 1 file changed, 45 insertions(+), 7 deletions(-) > > > > diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c > > index 2bf1e05..8a73b68 100644 > > --- a/libavformat/flvdec.c > > +++ b/libavformat/flvdec.c > > @@ -30,6 +30,7 @@ > > #include "libavutil/opt.h" > > #include "libavutil/intfloat.h" > > #include "libavutil/mathematics.h" > > +#include "libavutil/mem.h" > > #include "libavcodec/bytestream.h" > > #include "libavcodec/mpeg4audio.h" > > #include "avformat.h" > > @@ -41,6 +42,12 @@ > > > > #define RESYNC_BUFFER_SIZE (1<<20) > > > > + > > +typedef struct FLVKeyFrame { > > +int64_t pos; > > +int64_t timestamp; > > +} FLVKeyFrame; > > + > > typedef struct FLVContext { > > const AVClass *class; ///< Class for private options. > > int trust_metadata; ///< configure streams according onMetaData > > @@ -61,6 +68,10 @@ typedef struct FLVContext { > > > > int broken_sizes; > > int sum_flv_tag_size; > > + > > +int head_flags; //r8 > > +FLVKeyFrame *keyframes; > > +int keyframe_count; > > } FLVContext; > > > > static int probe(AVProbeData *p, int live) > > @@ -95,6 +106,9 @@ static int live_flv_probe(AVProbeData *p) > > static AVStream *create_stream(AVFormatContext *s, int codec_type) > > { > > AVStream *st = avformat_new_stream(s, NULL); > > +FLVContext *flv = s->priv_data; > > +int flags = flv->head_flags; > > +int i = 0; > > if (!st) > > return NULL; > > st->codecpar->codec_type = codec_type; > > @@ -104,6 +118,17 @@ static AVStream *create_stream(AVFormatContext *s, > int codec_type) > > s->ctx_flags &= ~AVFMTCTX_NOHEADER; > > > > avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ > > +if ((!(flags & FLV_HEADER_FLAG_HASVIDEO) && codec_type == > AVMEDIA_TYPE_AUDIO) || > > +(codec_type == AVMEDIA_TYPE_VIDEO) > > +) { > > +for (; i < flv->keyframe_count; i++) { > > +FLVKeyFrame *keyframe = &flv->keyframes[i]; > > +av_add_index_entry(st, keyframe->pos, keyframe->timestamp, > > + 0, 0, AVINDEX_KEYFRAME); > > +} > > +flv->keyframe_count = 0; > > +av_freep(&flv->keyframes); > > +} > > return st; > > } > > > > @@ -306,7 +331,7 @@ static int amf_get_string(AVIOContext *ioc, char > *buffer, int buffsize) > > } > > > > static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, > > - AVStream *vstream, int64_t max_pos) > > + AVStream *vstream, AVStream *astream, > int64_t max_pos) > > { > > FLVContext *flv = s->priv_data; > > unsigned int timeslen = 0, fileposlen = 0, i; > > @@ -315,8 +340,12 @@ static int parse_keyframes_index(AVFormatContext > *s, AVIOContext *ioc, > > int64_t *filepositions = NULL; > > int ret= AVERROR(ENOSYS); > > int64_t initial_pos= avio_tell(ioc); > > +int head_flags = flv->head_flags; > > +AVStream *kf_stream= vstream; > > +if (!kf_stream && astream && (!(head_flags & > FLV_HEADER_FLAG_HASVIDEO) && (head_flags & FLV_HEADER_FLAG_HASAUDIO))) > > +kf_stream = astream; > > > > -if (vstream->nb_index_entries>0) { > > +if (kf_stream && kf_stream->nb_index_entries > 0) { > > av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); > > return 0; > > } > > @@ -369,8 +398,16 @@ static int parse_keyframes_index(AVFormatContext > *s, AVIOContext *ioc, > > > > if (timeslen == fileposlen && fileposlen>1 && max_pos <= > filepositions[0]) { > > for (i = 0; i < fileposlen; i++) { > > -av_add_index_entry(vstream, filepositions[i], times[i] * > 1000, > > - 0, 0, AVINDEX_KEYFRAME); > > +if (kf_stream) { > > +av_add_index_entry(kf_stream, filepositions[i], > times[i] * 1000, > > + 0, 0, AVINDEX_KEYFRAME); > > +} else { > > +FLVKeyFrame frame = {0}; > > +frame.pos = filepositions[i]; > > +frame.timestamp = times[i] * 1000; > > +av_dynarray2_add((void **)&flv->keyframes, > &flv->keyframe_count,sizeof(FLVKeyFrame), (const uint8_t *)&frame); > > +} > > + > > if (i < 2) { > > flv->validate_index[i].pos = filepositions[i]; > > flv->validate_index[i].dts = times[i] * 1000; > > @@ -418,10 +455,10 @@ static int amf_parse_obj
Re: [FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created
There has an error when seeking in a flv file, which key frames was sorted before video frame. This ensures that all the key frames was cached, and add to corresponding stream when it was created. On Wed, Jul 20, 2016 at 9:30 PM, zhangxinzheng wrote: > From: Xinzheng Zhang > > --- > libavformat/flvdec.c | 52 > +--- > 1 file changed, 45 insertions(+), 7 deletions(-) > > diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c > index 2bf1e05..8a73b68 100644 > --- a/libavformat/flvdec.c > +++ b/libavformat/flvdec.c > @@ -30,6 +30,7 @@ > #include "libavutil/opt.h" > #include "libavutil/intfloat.h" > #include "libavutil/mathematics.h" > +#include "libavutil/mem.h" > #include "libavcodec/bytestream.h" > #include "libavcodec/mpeg4audio.h" > #include "avformat.h" > @@ -41,6 +42,12 @@ > > #define RESYNC_BUFFER_SIZE (1<<20) > > + > +typedef struct FLVKeyFrame { > +int64_t pos; > +int64_t timestamp; > +} FLVKeyFrame; > + > typedef struct FLVContext { > const AVClass *class; ///< Class for private options. > int trust_metadata; ///< configure streams according onMetaData > @@ -61,6 +68,10 @@ typedef struct FLVContext { > > int broken_sizes; > int sum_flv_tag_size; > + > +int head_flags; //r8 > +FLVKeyFrame *keyframes; > +int keyframe_count; > } FLVContext; > > static int probe(AVProbeData *p, int live) > @@ -95,6 +106,9 @@ static int live_flv_probe(AVProbeData *p) > static AVStream *create_stream(AVFormatContext *s, int codec_type) > { > AVStream *st = avformat_new_stream(s, NULL); > +FLVContext *flv = s->priv_data; > +int flags = flv->head_flags; > +int i = 0; > if (!st) > return NULL; > st->codecpar->codec_type = codec_type; > @@ -104,6 +118,17 @@ static AVStream *create_stream(AVFormatContext *s, int > codec_type) > s->ctx_flags &= ~AVFMTCTX_NOHEADER; > > avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ > +if ((!(flags & FLV_HEADER_FLAG_HASVIDEO) && codec_type == > AVMEDIA_TYPE_AUDIO) || > +(codec_type == AVMEDIA_TYPE_VIDEO) > +) { > +for (; i < flv->keyframe_count; i++) { > +FLVKeyFrame *keyframe = &flv->keyframes[i]; > +av_add_index_entry(st, keyframe->pos, keyframe->timestamp, > + 0, 0, AVINDEX_KEYFRAME); > +} > +flv->keyframe_count = 0; > +av_freep(&flv->keyframes); > +} > return st; > } > > @@ -306,7 +331,7 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, > int buffsize) > } > > static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, > - AVStream *vstream, int64_t max_pos) > + AVStream *vstream, AVStream *astream, > int64_t max_pos) > { > FLVContext *flv = s->priv_data; > unsigned int timeslen = 0, fileposlen = 0, i; > @@ -315,8 +340,12 @@ static int parse_keyframes_index(AVFormatContext *s, > AVIOContext *ioc, > int64_t *filepositions = NULL; > int ret= AVERROR(ENOSYS); > int64_t initial_pos= avio_tell(ioc); > +int head_flags = flv->head_flags; > +AVStream *kf_stream= vstream; > +if (!kf_stream && astream && (!(head_flags & FLV_HEADER_FLAG_HASVIDEO) > && (head_flags & FLV_HEADER_FLAG_HASAUDIO))) > +kf_stream = astream; > > -if (vstream->nb_index_entries>0) { > +if (kf_stream && kf_stream->nb_index_entries > 0) { > av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); > return 0; > } > @@ -369,8 +398,16 @@ static int parse_keyframes_index(AVFormatContext *s, > AVIOContext *ioc, > > if (timeslen == fileposlen && fileposlen>1 && max_pos <= > filepositions[0]) { > for (i = 0; i < fileposlen; i++) { > -av_add_index_entry(vstream, filepositions[i], times[i] * 1000, > - 0, 0, AVINDEX_KEYFRAME); > +if (kf_stream) { > +av_add_index_entry(kf_stream, filepositions[i], times[i] * > 1000, > + 0, 0, AVINDEX_KEYFRAME); > +} else { > +FLVKeyFrame frame = {0}; > +frame.pos = filepositions[i]; > +frame.timestamp = times[i] * 1000; > +av_dynarray2_add((void **)&flv->keyframes, > &flv->keyframe_count,sizeof(FLVKeyFrame), (const uint8_t *)&frame); > +} > + > if (i < 2) { > flv->validate_index[i].pos = filepositions[i]; > flv->validate_index[i].dts = times[i] * 1000; > @@ -418,10 +455,10 @@ static int amf_parse_object(AVFormatContext *s, > AVStream *astream, > } > break; > case AMF_DATA_TYPE_OBJECT: > -if ((vstream || astream) && key && > +if (key && > ioc->seekable && > !strcmp(KEYFRAMES_TAG, key) && depth == 1) > -