[FFmpeg-devel] [PATCH 1/1] fix - increment index_entry_pos after log statement so that logs for index entries derived from trun atom use correct index
Signed-off-by: Nick Ryan --- libavformat/mov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index ec57a05803..540e5ca057 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4856,11 +4856,11 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->ctts_data[index_entry_pos].count = 1; sc->ctts_data[index_entry_pos].duration = ctts_duration; -index_entry_pos++; av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " "size %u, distance %d, keyframe %d\n", st->index, index_entry_pos, offset, dts, sample_size, distance, keyframe); +index_entry_pos++; distance++; dts += sample_duration; offset += sample_size; -- 2.17.1 (Apple Git-112) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/1] Minor fix to prevent confusing logs when demuxing fragmented mp4
Minor fix to prevent confusing logs when demuxing fragmented mp4 Nick Ryan (1): fix - increment index_entry_pos after log statement so that logs for index entries derived from trun atom use correct index libavformat/mov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.17.1 (Apple Git-112) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/1] mov.c: improvement to fMP4 bitrate estimation
Current code estimates bitrate by taking size of a single fragment and dividing by the total duration. This patch changes calculation to be based on duration used for framerate estimation. Example ffprobes BEFORE patch (note video stream 15 kb/s, audio stream 0 kb/s): ffprobe version N-91996-g94aed2265a Copyright (c) 2007-2018 the FFmpeg developers built with Apple LLVM version 10.0.0 (clang-1000.11.45.2) configuration: libavutil 56. 19.101 / 56. 19.101 libavcodec 58. 30.100 / 58. 30.100 libavformat58. 18.102 / 58. 18.102 libavdevice58. 4.103 / 58. 4.103 libavfilter 7. 32.100 / 7. 32.100 libswscale 5. 2.100 / 5. 2.100 libswresample 3. 2.100 / 3. 2.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/nick/media/v-a-hls/video/video.mp4': Metadata: major_brand : isom minor_version : 0 compatible_brands: iso8mp41dashavc1cmfc creation_time : 2018-08-30T11:28:56.00Z Duration: 00:11:24.00, start: 0.00, bitrate: 999 kb/s Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1024x576 [SAR 1:1 DAR 16:9], 15 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default) Metadata: creation_time : 2018-08-30T11:28:56.00Z handler_name: VideoHandler encoder : AVC Coding ffprobe version N-91996-g94aed2265a Copyright (c) 2007-2018 the FFmpeg developers built with Apple LLVM version 10.0.0 (clang-1000.11.45.2) configuration: libavutil 56. 19.101 / 56. 19.101 libavcodec 58. 30.100 / 58. 30.100 libavformat58. 18.102 / 58. 18.102 libavdevice58. 4.103 / 58. 4.103 libavfilter 7. 32.100 / 7. 32.100 libswscale 5. 2.100 / 5. 2.100 libswresample 3. 2.100 / 3. 2.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/nick/media/v-a-hls/audio/audio.mp4': Metadata: major_brand : isom minor_version : 0 compatible_brands: iso8mp41dashcmfc creation_time : 2018-08-30T11:28:56.00Z Duration: 00:11:24.00, start: -0.023220, bitrate: 59 kb/s Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 0 kb/s (default) Metadata: creation_time : 2018-08-30T11:28:56.00Z handler_name: SoundHandler Example ffprobes AFTER patch (note video stream 1027 kb/s, audio stream 4 kb/s): ffprobe version N-91996-g94aed2265a Copyright (c) 2007-2018 the FFmpeg developers built with Apple LLVM version 10.0.0 (clang-1000.11.45.2) configuration: libavutil 56. 19.101 / 56. 19.101 libavcodec 58. 30.100 / 58. 30.100 libavformat58. 18.102 / 58. 18.102 libavdevice58. 4.103 / 58. 4.103 libavfilter 7. 32.100 / 7. 32.100 libswscale 5. 2.100 / 5. 2.100 libswresample 3. 2.100 / 3. 2.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/nick/media/v-a-hls/video/video.mp4': Metadata: major_brand : isom minor_version : 0 compatible_brands: iso8mp41dashavc1cmfc creation_time : 2018-08-30T11:28:56.00Z Duration: 00:11:24.00, start: 0.00, bitrate: 999 kb/s Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1024x576 [SAR 1:1 DAR 16:9], 1027 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default) Metadata: creation_time : 2018-08-30T11:28:56.00Z handler_name: VideoHandler encoder : AVC Coding ffprobe version N-91996-g94aed2265a Copyright (c) 2007-2018 the FFmpeg developers built with Apple LLVM version 10.0.0 (clang-1000.11.45.2) configuration: libavutil 56. 19.101 / 56. 19.101 libavcodec 58. 30.100 / 58. 30.100 libavformat58. 18.102 / 58. 18.102 libavdevice58. 4.103 / 58. 4.103 libavfilter 7. 32.100 / 7. 32.100 libswscale 5. 2.100 / 5. 2.100 libswresample 3. 2.100 / 3. 2.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/nick/media/v-a-hls/audio/audio.mp4': Metadata: major_brand : isom minor_version : 0 compatible_brands: iso8mp41dashcmfc creation_time : 2018-08-30T11:28:56.00Z Duration: 00:11:24.00, start: -0.023220, bitrate: 59 kb/s Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 4 kb/s (default) Metadata: creation_time : 2018-08-30T11:28:56.00Z handler_name: SoundHandler Nick Ryan (1): possible fix to correct (improve) bitrate estimation for streams in fragmented MP4 when calculation is based on trex_data libavformat/mov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -- 2.17.1 (Apple Git-112) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/1] mov.c: improvement to fMP4 bitrate estimation
Current code estimates bitrate by taking size of a single fragment and dividing by the total duration. This patch changes calculation to be based on duration used for framerate estimation. Nick Ryan (1): possible fix to correct (improve) bitrate estimation for streams in fragmented MP4 when calculation is based on trex_data libavformat/mov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -- 2.17.1 (Apple Git-112) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/1] possible fix to correct (improve) bitrate estimation for streams in fragmented MP4 when calculation is based on trex_data
Signed-off-by: Nick Ryan --- libavformat/mov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 540e5ca057..67015a72a1 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -7459,14 +7459,14 @@ static int mov_read_header(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; MOVStreamContext *sc = st->priv_data; -if (st->duration > 0) { +if (sc->duration_for_fps > 0) { if (sc->data_size > INT64_MAX / sc->time_scale / 8) { av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n", sc->data_size, sc->time_scale); mov_read_close(s); return AVERROR_INVALIDDATA; } -st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration; +st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / sc->duration_for_fps; } } } -- 2.17.1 (Apple Git-112) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/1] Trying to fix trac ticket #7359
Signed-off-by: Nick Ryan --- libavformat/mov.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 67015a72a1..587513e06e 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -7605,15 +7605,15 @@ static int mov_switch_root(AVFormatContext *s, int64_t target, int index) if (index >= 0 && index < mov->frag_index.nb_items) target = mov->frag_index.item[index].moof_offset; -if (avio_seek(s->pb, target, SEEK_SET) != target) { +if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) { av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target); return AVERROR_INVALIDDATA; } mov->next_root_atom = 0; -if (index < 0 || index >= mov->frag_index.nb_items) +if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items) index = search_frag_moof_offset(&mov->frag_index, target); -if (index < mov->frag_index.nb_items) { +if (index >= 0 && index < mov->frag_index.nb_items) { if (index + 1 < mov->frag_index.nb_items) mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset; if (mov->frag_index.item[index].headers_read) @@ -7663,9 +7663,22 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) AVIndexEntry *sample; AVStream *st = NULL; int64_t current_index; +int i; int ret; mov->fc = s; retry: +if (s->pb->pos == 0) { +mov->frag_index.nb_items = 0; +mov->frag_index.current = -1; +for (i = 0; i < s->nb_streams; i++) { +AVStream *avst = s->streams[i]; +avst->index_entries = NULL; +avst->index_entries_allocated_size = 0; +avst->nb_index_entries = 0; +} +if ((ret = mov_switch_root(s, -1, -1)) < 0) +return ret; +} sample = mov_find_next_sample(s, &st); if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) { if (!mov->next_root_atom) -- 2.17.1 (Apple Git-112) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/1] Trying to fix trac ticket #7359
Hello, With reference to: https://trac.ffmpeg.org/ticket/7359 I believe another way this issue manifests itself is using ffplay and trying to seek forward 10 seconds with the right arrow key: playback freezes. I have dug into this and developed a hack which seems to resolve the issue, BUT I have no idea if this is a valid, correct fix. I have a local m3u8 file which was showing this problem and I can now programmatically seek to the correct point. I can also seek correctly via ffplay and ffmpeg. I have also tried the URL from the trak ticket and this now works as well. All current fate samples tests pass. I submit the patch here for anyone that knows more about the codebase. I am happy to rework etc. as required. At the very least it might help anyone experiencing this problem in the meantime if they wish to run a patched ffmpeg version. Within hls.c when hls_read_seek() is called it resets the stream position as follows: /* Reset the pos, to let the mpegts demuxer know we've seeked. */ pls->pb.pos = 0; There is support for this in the mpegts handle_packets() code to check if the position has been reset and clear out any PES packets: if (avio_tell(s->pb) != ts->last_pos) { int i; av_log(ts->stream, AV_LOG_TRACE, "Skipping after seek\n"); /* seek detected, flush pes buffer */ I have basically tried to do the same ‘reset’ logic within mov.c mov_read_packet() and force a search for the next mov root. Regards, Nick Nick Ryan (1): Trying to fix trac ticket #7359 libavformat/mov.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) -- 2.17.1 (Apple Git-112) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] Possible fix for trac ticket #7359
This is my 2nd attempt with an improved fix. With reference to: https://trac.ffmpeg.org/ticket/7359 I believe another way this issue manifests itself is using ffplay and trying to seek forward 10 seconds with the right arrow key: playback freezes. I have dug into this and developed a solution which seems to resolve the issue. I have a local m3u8 file which was showing this problem and I can now programmatically seek to the correct point. I can also seek correctly via ffplay and ffmpeg. I have also tried the URL from the trak ticket and this now works as well. All current fate samples tests pass. I submit the patch here for anyone that knows more about the codebase. I am happy to rework etc. as required. At the very least it might help anyone experiencing this problem in the meantime if they wish to run a patched ffmpeg version. I have also now successfully reproduced and fixed the issue mentioned here: http://www.ffmpeg-archive.org/HLS-accurate-seeking-vs-MP4-td4685570.html There are 2 items to this fix: 1. related to seek logic in HLS and 2. related to effect of HLS seeking on fMP4 files. 1. Change to logic in hls.c for seeking After performing a rough seek in hls.c hls_read_seek() to the nearest segment, the logic for hls_read_packet() was to discard packets until a DTS after the accurate seek point is discovered. This was done even if AVSEEK_FLAG_ANY was not specified in the initial seek request. The patch changes this so that if AVSEEK_FLAG_ANY has not been specified, it will return the first keyframe discovered after the rough seek point. 2. Change to logic in mov.c for reading packets after an HLS seek Within hls.c when hls_read_seek() is called it resets the stream position as follows: /* Reset the pos, to let the mpegts demuxer know we've seeked. */ pls->pb.pos = 0; There is support for this in the mpegts handle_packets() code to check if the position has been reset and clear out any PES packets: if (avio_tell(s->pb) != ts->last_pos) { int i; av_log(ts->stream, AV_LOG_TRACE, "Skipping after seek\n"); /* seek detected, flush pes buffer */ In mov.c it now detects the pos has been reset in mov_read_packet(). It clears fragments and indexes and searches for the next root i.e. the next fragment via mov_switch_root(). Regards, Nick ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] fix trac ticket #7359
Signed-off-by: Nick Ryan --- libavformat/hls.c | 6 -- libavformat/mov.c | 36 +--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 8ad08baaed..99373d0f45 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2107,8 +2107,10 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) ts_diff = av_rescale_rnd(pls->pkt.dts, AV_TIME_BASE, tb.den, AV_ROUND_DOWN) - pls->seek_timestamp; -if (ts_diff >= 0 && (pls->seek_flags & AVSEEK_FLAG_ANY || -pls->pkt.flags & AV_PKT_FLAG_KEY)) { +/* If AVSEEK_FLAG_ANY, keep reading until ts_diff is greater than 0 + * otherwise return the first keyframe encountered */ +if ((ts_diff >= 0 && (pls->seek_flags & AVSEEK_FLAG_ANY)) || +(!(pls->seek_flags & AVSEEK_FLAG_ANY) && (pls->pkt.flags & AV_PKT_FLAG_KEY))) { pls->seek_timestamp = AV_NOPTS_VALUE; break; } diff --git a/libavformat/mov.c b/libavformat/mov.c index ec57a05803..b13c3143ef 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -7605,15 +7605,15 @@ static int mov_switch_root(AVFormatContext *s, int64_t target, int index) if (index >= 0 && index < mov->frag_index.nb_items) target = mov->frag_index.item[index].moof_offset; -if (avio_seek(s->pb, target, SEEK_SET) != target) { +if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) { av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target); return AVERROR_INVALIDDATA; } mov->next_root_atom = 0; -if (index < 0 || index >= mov->frag_index.nb_items) +if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items) index = search_frag_moof_offset(&mov->frag_index, target); -if (index < mov->frag_index.nb_items) { +if (index >= 0 && index < mov->frag_index.nb_items) { if (index + 1 < mov->frag_index.nb_items) mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset; if (mov->frag_index.item[index].headers_read) @@ -7664,8 +7664,38 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) AVStream *st = NULL; int64_t current_index; int ret; +int i; mov->fc = s; retry: +if (s->pb->pos == 0) { + +// Discard current fragment index +if (mov->frag_index.allocated_size > 0) { +av_freep(&mov->frag_index.item); +mov->frag_index.nb_items = 0; +mov->frag_index.allocated_size = 0; +mov->frag_index.current = -1; +mov->frag_index.complete = 0; +} + +for (i = 0; i < s->nb_streams; i++) { +AVStream *avst = s->streams[i]; +MOVStreamContext *msc = avst->priv_data; + +// Clear current sample +mov_current_sample_set(msc, 0); + +// Discard current index entries +if (avst->index_entries_allocated_size > 0) { +av_freep(&avst->index_entries); +avst->index_entries_allocated_size = 0; +avst->nb_index_entries = 0; +} +} + +if ((ret = mov_switch_root(s, -1, -1)) < 0) +return ret; +} sample = mov_find_next_sample(s, &st); if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) { if (!mov->next_root_atom) -- 2.17.1 (Apple Git-112) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel