[FFmpeg-devel] [PATCH] avformat/mov: fix hang while seek on a kind of fragmented mp4.

2019-03-06 Thread Charles Liu
1. organize fragmented information according to the tracks.
2. do NOT skip the last boxes of fragmented info.

ticket #7572

To reproduce #7572, need to revert commit 
aa25198f1b925a464bdfa83a98476f08d26c9209 first. That commit works for ticket 
7572 luckily. However, #7572 has a deeper reason. Mov demuxer consider that 
fragmented index is completed if a ‘sidx’ point to the end of the file. But 
there may be other ‘sidx’ for other tracks. If we skip the tail from there, we 
will missing the last ‘sidx’ and ‘moof’. Then AV_NOPTS_VALUE occurs.

Signed-off-by: Charles Liu 
---
 libavformat/isom.h |  10 +-
 libavformat/mov.c  | 378 +
 2 files changed, 185 insertions(+), 203 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 69452cae8e..eea8fa4e8f 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -125,7 +125,7 @@ typedef struct MOVEncryptionIndex {
 } MOVEncryptionIndex;
 
 typedef struct MOVFragmentStreamInfo {
-int id;
+unsigned stsd_id;
 int64_t sidx_pts;
 int64_t first_tfra_pts;
 int64_t tfdt_dts;
@@ -136,14 +136,13 @@ typedef struct MOVFragmentStreamInfo {
 typedef struct MOVFragmentIndexItem {
 int64_t moof_offset;
 int headers_read;
-int current;
-int nb_stream_info;
-MOVFragmentStreamInfo * stream_info;
+MOVFragmentStreamInfo stream_info;
 } MOVFragmentIndexItem;
 
 typedef struct MOVFragmentIndex {
 int allocated_size;
 int complete;
+int id;  // track id
 int current;
 int nb_items;
 MOVFragmentIndexItem * item;
@@ -274,7 +273,8 @@ typedef struct MOVContext {
 int moov_retry;
 int use_mfra_for;
 int has_looked_for_mfra;
-MOVFragmentIndex frag_index;
+unsigned nb_frag_indices;
+MOVFragmentIndex *frag_indices;
 int atom_depth;
 unsigned int aax_mode;  ///< 'aax' file has been detected
 uint8_t file_key[20];
diff --git a/libavformat/mov.c b/libavformat/mov.c
index a7d444b0ee..b150710a40 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1153,59 +1153,29 @@ static int mov_read_moov(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return 0; /* now go for mdat */
 }
 
-static MOVFragmentStreamInfo * get_frag_stream_info(
-MOVFragmentIndex *frag_index,
-int index,
-int id)
+static MOVFragmentIndex *mov_find_frag_index(MOVFragmentIndex *frag_indices, 
int nb_frag_indices, int track_id)
 {
-int i;
-MOVFragmentIndexItem * item;
+unsigned i;
+MOVFragmentIndex *frag_index = NULL;
 
-if (index < 0 || index >= frag_index->nb_items)
-return NULL;
-item = _index->item[index];
-for (i = 0; i < item->nb_stream_info; i++)
-if (item->stream_info[i].id == id)
-return >stream_info[i];
+for (i = 0; i < nb_frag_indices; i++)
+if (frag_indices[i].id == track_id)
+frag_index = _indices[i];
 
-// This shouldn't happen
-return NULL;
+return frag_index;
 }
 
-static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
+static MOVFragmentStreamInfo *get_current_frag_stream_info(MOVContext *c, int 
id)
 {
-int i;
-MOVFragmentIndexItem * item;
+MOVFragmentIndex *frag_index = NULL;
 
-if (frag_index->current < 0 ||
-frag_index->current >= frag_index->nb_items)
-return;
-
-item = _index->item[frag_index->current];
-for (i = 0; i < item->nb_stream_info; i++)
-if (item->stream_info[i].id == id) {
-item->current = i;
-return;
-}
-
-// id not found.  This shouldn't happen.
-item->current = -1;
-}
-
-static MOVFragmentStreamInfo * get_current_frag_stream_info(
-MOVFragmentIndex *frag_index)
-{
-MOVFragmentIndexItem *item;
-if (frag_index->current < 0 ||
+frag_index = mov_find_frag_index(c->frag_indices, c->nb_frag_indices, id);
+if (!frag_index ||
+frag_index->current < 0 ||
 frag_index->current >= frag_index->nb_items)
 return NULL;
 
-item = _index->item[frag_index->current];
-if (item->current >= 0 && item->current < item->nb_stream_info)
-return >stream_info[item->current];
-
-// This shouldn't happen
-return NULL;
+return _index->item[frag_index->current].stream_info;
 }
 
 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t 
offset)
@@ -1232,9 +1202,9 @@ static int search_frag_moof_offset(MOVFragmentIndex 
*frag_index, int64_t offset)
 return b;
 }
 
-static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
-{
-av_assert0(frag_stream_info);
+static int64_t get_frag_time(MOVFragmentIndex *frag_index,
+ int index, int track_id) {
+MOVFragmentStreamInfo *frag_stream_info = 
_index->item[index].stream_info;
 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
  

[FFmpeg-devel] [PATCH] avformat/mov: fix hang while seek on a kind of fragmented mp4.

2019-03-05 Thread Charles Liu
1. organize fragmented information according to the tracks.
2. do NOT skip the last boxes of fragmented info.

ticket #7572

Signed-off-by: Charles Liu 
---
 libavformat/isom.h |  10 +-
 libavformat/mov.c  | 378 +
 2 files changed, 185 insertions(+), 203 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 69452cae8e..eea8fa4e8f 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -125,7 +125,7 @@ typedef struct MOVEncryptionIndex {
 } MOVEncryptionIndex;
 
 typedef struct MOVFragmentStreamInfo {
-int id;
+unsigned stsd_id;
 int64_t sidx_pts;
 int64_t first_tfra_pts;
 int64_t tfdt_dts;
@@ -136,14 +136,13 @@ typedef struct MOVFragmentStreamInfo {
 typedef struct MOVFragmentIndexItem {
 int64_t moof_offset;
 int headers_read;
-int current;
-int nb_stream_info;
-MOVFragmentStreamInfo * stream_info;
+MOVFragmentStreamInfo stream_info;
 } MOVFragmentIndexItem;
 
 typedef struct MOVFragmentIndex {
 int allocated_size;
 int complete;
+int id;  // track id
 int current;
 int nb_items;
 MOVFragmentIndexItem * item;
@@ -274,7 +273,8 @@ typedef struct MOVContext {
 int moov_retry;
 int use_mfra_for;
 int has_looked_for_mfra;
-MOVFragmentIndex frag_index;
+unsigned nb_frag_indices;
+MOVFragmentIndex *frag_indices;
 int atom_depth;
 unsigned int aax_mode;  ///< 'aax' file has been detected
 uint8_t file_key[20];
diff --git a/libavformat/mov.c b/libavformat/mov.c
index a7d444b0ee..b150710a40 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1153,59 +1153,29 @@ static int mov_read_moov(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return 0; /* now go for mdat */
 }
 
-static MOVFragmentStreamInfo * get_frag_stream_info(
-MOVFragmentIndex *frag_index,
-int index,
-int id)
+static MOVFragmentIndex *mov_find_frag_index(MOVFragmentIndex *frag_indices, 
int nb_frag_indices, int track_id)
 {
-int i;
-MOVFragmentIndexItem * item;
+unsigned i;
+MOVFragmentIndex *frag_index = NULL;
 
-if (index < 0 || index >= frag_index->nb_items)
-return NULL;
-item = _index->item[index];
-for (i = 0; i < item->nb_stream_info; i++)
-if (item->stream_info[i].id == id)
-return >stream_info[i];
+for (i = 0; i < nb_frag_indices; i++)
+if (frag_indices[i].id == track_id)
+frag_index = _indices[i];
 
-// This shouldn't happen
-return NULL;
+return frag_index;
 }
 
-static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
+static MOVFragmentStreamInfo *get_current_frag_stream_info(MOVContext *c, int 
id)
 {
-int i;
-MOVFragmentIndexItem * item;
+MOVFragmentIndex *frag_index = NULL;
 
-if (frag_index->current < 0 ||
-frag_index->current >= frag_index->nb_items)
-return;
-
-item = _index->item[frag_index->current];
-for (i = 0; i < item->nb_stream_info; i++)
-if (item->stream_info[i].id == id) {
-item->current = i;
-return;
-}
-
-// id not found.  This shouldn't happen.
-item->current = -1;
-}
-
-static MOVFragmentStreamInfo * get_current_frag_stream_info(
-MOVFragmentIndex *frag_index)
-{
-MOVFragmentIndexItem *item;
-if (frag_index->current < 0 ||
+frag_index = mov_find_frag_index(c->frag_indices, c->nb_frag_indices, id);
+if (!frag_index ||
+frag_index->current < 0 ||
 frag_index->current >= frag_index->nb_items)
 return NULL;
 
-item = _index->item[frag_index->current];
-if (item->current >= 0 && item->current < item->nb_stream_info)
-return >stream_info[item->current];
-
-// This shouldn't happen
-return NULL;
+return _index->item[frag_index->current].stream_info;
 }
 
 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t 
offset)
@@ -1232,9 +1202,9 @@ static int search_frag_moof_offset(MOVFragmentIndex 
*frag_index, int64_t offset)
 return b;
 }
 
-static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
-{
-av_assert0(frag_stream_info);
+static int64_t get_frag_time(MOVFragmentIndex *frag_index,
+ int index, int track_id) {
+MOVFragmentStreamInfo *frag_stream_info = 
_index->item[index].stream_info;
 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
 return frag_stream_info->sidx_pts;
 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
@@ -1242,31 +1212,9 @@ static int64_t 
get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
 return frag_stream_info->tfdt_dts;
 }
 
-static int64_t get_frag_time(MOVFragmentIndex *frag_index,
- int index, int track_id)
-{
-MOVFragmentStreamInfo * frag_stre

[FFmpeg-devel] [PATCH] avformat/mov: fix hang while seek on a kind of fragmented mp4.

2019-02-22 Thread Charles Liu
1. organize fragmented information according to the tracks.
2. do NOT skip the last boxes of fragmented info.

ticket #7572

Signed-off-by: Charles Liu 
---
 libavformat/isom.h |  10 +-
 libavformat/mov.c  | 374 +
 2 files changed, 181 insertions(+), 203 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 69452cae8e..eea8fa4e8f 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -125,7 +125,7 @@ typedef struct MOVEncryptionIndex {
 } MOVEncryptionIndex;
 
 typedef struct MOVFragmentStreamInfo {
-int id;
+unsigned stsd_id;
 int64_t sidx_pts;
 int64_t first_tfra_pts;
 int64_t tfdt_dts;
@@ -136,14 +136,13 @@ typedef struct MOVFragmentStreamInfo {
 typedef struct MOVFragmentIndexItem {
 int64_t moof_offset;
 int headers_read;
-int current;
-int nb_stream_info;
-MOVFragmentStreamInfo * stream_info;
+MOVFragmentStreamInfo stream_info;
 } MOVFragmentIndexItem;
 
 typedef struct MOVFragmentIndex {
 int allocated_size;
 int complete;
+int id;  // track id
 int current;
 int nb_items;
 MOVFragmentIndexItem * item;
@@ -274,7 +273,8 @@ typedef struct MOVContext {
 int moov_retry;
 int use_mfra_for;
 int has_looked_for_mfra;
-MOVFragmentIndex frag_index;
+unsigned nb_frag_indices;
+MOVFragmentIndex *frag_indices;
 int atom_depth;
 unsigned int aax_mode;  ///< 'aax' file has been detected
 uint8_t file_key[20];
diff --git a/libavformat/mov.c b/libavformat/mov.c
index bbd588c705..a16788fd21 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1153,59 +1153,29 @@ static int mov_read_moov(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return 0; /* now go for mdat */
 }
 
-static MOVFragmentStreamInfo * get_frag_stream_info(
-MOVFragmentIndex *frag_index,
-int index,
-int id)
+static MOVFragmentIndex *mov_find_frag_index(MOVFragmentIndex *frag_indices, 
int nb_frag_indices, int track_id)
 {
-int i;
-MOVFragmentIndexItem * item;
+unsigned i;
+MOVFragmentIndex *frag_index = NULL;
 
-if (index < 0 || index >= frag_index->nb_items)
-return NULL;
-item = _index->item[index];
-for (i = 0; i < item->nb_stream_info; i++)
-if (item->stream_info[i].id == id)
-return >stream_info[i];
+for (i = 0; i < nb_frag_indices; i++)
+if (frag_indices[i].id == track_id)
+frag_index = _indices[i];
 
-// This shouldn't happen
-return NULL;
+return frag_index;
 }
 
-static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
+static MOVFragmentStreamInfo *get_current_frag_stream_info(MOVContext *c, int 
id)
 {
-int i;
-MOVFragmentIndexItem * item;
-
-if (frag_index->current < 0 ||
-frag_index->current >= frag_index->nb_items)
-return;
-
-item = _index->item[frag_index->current];
-for (i = 0; i < item->nb_stream_info; i++)
-if (item->stream_info[i].id == id) {
-item->current = i;
-return;
-}
+MOVFragmentIndex *frag_index = NULL;
 
-// id not found.  This shouldn't happen.
-item->current = -1;
-}
-
-static MOVFragmentStreamInfo * get_current_frag_stream_info(
-MOVFragmentIndex *frag_index)
-{
-MOVFragmentIndexItem *item;
-if (frag_index->current < 0 ||
+frag_index = mov_find_frag_index(c->frag_indices, c->nb_frag_indices, id);
+if (!frag_index ||
+frag_index->current < 0 ||
 frag_index->current >= frag_index->nb_items)
 return NULL;
 
-item = _index->item[frag_index->current];
-if (item->current >= 0 && item->current < item->nb_stream_info)
-return >stream_info[item->current];
-
-// This shouldn't happen
-return NULL;
+return _index->item[frag_index->current].stream_info;
 }
 
 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t 
offset)
@@ -1232,9 +1202,9 @@ static int search_frag_moof_offset(MOVFragmentIndex 
*frag_index, int64_t offset)
 return b;
 }
 
-static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
-{
-av_assert0(frag_stream_info);
+static int64_t get_frag_time(MOVFragmentIndex *frag_index,
+ int index, int track_id) {
+MOVFragmentStreamInfo *frag_stream_info = 
_index->item[index].stream_info;
 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
 return frag_stream_info->sidx_pts;
 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
@@ -1242,31 +1212,9 @@ static int64_t 
get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
 return frag_stream_info->tfdt_dts;
 }
 
-static int64_t get_frag_time(MOVFragmentIndex *frag_index,
- int index, int track_id)
-{
-MOVFragmentStreamInfo * frag_stre

[FFmpeg-devel] [PATCH] avformat/mov: fix hang while seek on a kind of fragmented mp4.

2019-02-20 Thread Charles Liu
1. organize fragmented information according to the tracks.
2. do NOT skip the last boxes of fragmented info.

ticket #7572

Signed-off-by: Charles Liu 
---
 libavformat/isom.h |  10 +-
 libavformat/mov.c  | 375 ++---
 2 files changed, 185 insertions(+), 200 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 69452cae8e..2b06f5fa58 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -125,7 +125,7 @@ typedef struct MOVEncryptionIndex {
 } MOVEncryptionIndex;
 
 typedef struct MOVFragmentStreamInfo {
-int id;
+unsigned stsd_id;
 int64_t sidx_pts;
 int64_t first_tfra_pts;
 int64_t tfdt_dts;
@@ -136,14 +136,13 @@ typedef struct MOVFragmentStreamInfo {
 typedef struct MOVFragmentIndexItem {
 int64_t moof_offset;
 int headers_read;
-int current;
-int nb_stream_info;
-MOVFragmentStreamInfo * stream_info;
+MOVFragmentStreamInfo stream_info;
 } MOVFragmentIndexItem;
 
 typedef struct MOVFragmentIndex {
 int allocated_size;
 int complete;
+int id;  // track id
 int current;
 int nb_items;
 MOVFragmentIndexItem * item;
@@ -274,7 +273,8 @@ typedef struct MOVContext {
 int moov_retry;
 int use_mfra_for;
 int has_looked_for_mfra;
-MOVFragmentIndex frag_index;
+unsigned nb_frag_indices;
+MOVFragmentIndex **frag_indices;
 int atom_depth;
 unsigned int aax_mode;  ///< 'aax' file has been detected
 uint8_t file_key[20];
diff --git a/libavformat/mov.c b/libavformat/mov.c
index bbd588c705..cd37d08299 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1153,59 +1153,29 @@ static int mov_read_moov(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return 0; /* now go for mdat */
 }
 
-static MOVFragmentStreamInfo * get_frag_stream_info(
-MOVFragmentIndex *frag_index,
-int index,
-int id)
+static MOVFragmentIndex *mov_find_frag_index(MOVFragmentIndex **frag_indices, 
int nb_frag_indices, int track_id)   // name?
 {
-int i;
-MOVFragmentIndexItem * item;
+unsigned i;
+MOVFragmentIndex *frag_index = NULL;
 
-if (index < 0 || index >= frag_index->nb_items)
-return NULL;
-item = _index->item[index];
-for (i = 0; i < item->nb_stream_info; i++)
-if (item->stream_info[i].id == id)
-return >stream_info[i];
+for (i = 0; i < nb_frag_indices; i++)
+if (frag_indices[i]->id == track_id)
+frag_index = frag_indices[i];
 
-// This shouldn't happen
-return NULL;
+return frag_index;
 }
 
-static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
+static MOVFragmentStreamInfo *get_current_frag_stream_info(MOVContext *c, int 
id)
 {
-int i;
-MOVFragmentIndexItem * item;
+MOVFragmentIndex *frag_index = NULL;
 
-if (frag_index->current < 0 ||
-frag_index->current >= frag_index->nb_items)
-return;
-
-item = _index->item[frag_index->current];
-for (i = 0; i < item->nb_stream_info; i++)
-if (item->stream_info[i].id == id) {
-item->current = i;
-return;
-}
-
-// id not found.  This shouldn't happen.
-item->current = -1;
-}
-
-static MOVFragmentStreamInfo * get_current_frag_stream_info(
-MOVFragmentIndex *frag_index)
-{
-MOVFragmentIndexItem *item;
-if (frag_index->current < 0 ||
+frag_index = mov_find_frag_index(c->frag_indices, c->nb_frag_indices, id);
+if (!frag_index ||
+frag_index->current < 0 ||
 frag_index->current >= frag_index->nb_items)
 return NULL;
 
-item = _index->item[frag_index->current];
-if (item->current >= 0 && item->current < item->nb_stream_info)
-return >stream_info[item->current];
-
-// This shouldn't happen
-return NULL;
+return _index->item[frag_index->current].stream_info;
 }
 
 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t 
offset)
@@ -1232,9 +1202,10 @@ static int search_frag_moof_offset(MOVFragmentIndex 
*frag_index, int64_t offset)
 return b;
 }
 
-static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
+static int64_t get_frag_time(MOVFragmentIndex *frag_index,
+ int index, int track_id)
 {
-av_assert0(frag_stream_info);
+MOVFragmentStreamInfo *frag_stream_info = 
_index->item[index].stream_info;
 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
 return frag_stream_info->sidx_pts;
 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
@@ -1242,31 +1213,10 @@ static int64_t 
get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
 return frag_stream_info->tfdt_dts;
 }
 
-static int64_t get_frag_time(MOVFragmentIndex *frag_index,
- int index, int track_id)
-{
-MOVFragmentStreamInf

[FFmpeg-devel] [PATCH] avformat/mov: fix hang while seek on a kind of fragmented mp4.

2019-02-03 Thread Charles Liu
Binary searching would hang if the fragment items do NOT have timestamp for the 
specified stream.

For example, a fmp4 consists of separated 'moof' boxes for each track, and 
separated 'sidx' for each segment, but no 'mfra' box.
Then every fragment item only have the timestamp for one of its tracks.

Signed-off-by: Charles Liu 
---
 libavformat/mov.c | 21 -
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 9b9739f788..35cb619e9f 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1266,7 +1266,7 @@ static int64_t get_frag_time(MOVFragmentIndex *frag_index,
 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
  AVStream *st, int64_t timestamp)
 {
-int a, b, m;
+int a, b, m, m0;
 int64_t frag_time;
 int id = -1;
 
@@ -1282,15 +1282,18 @@ static int search_frag_timestamp(MOVFragmentIndex 
*frag_index,
 b = frag_index->nb_items;
 
 while (b - a > 1) {
-m = (a + b) >> 1;
-frag_time = get_frag_time(frag_index, m, id);
-if (frag_time != AV_NOPTS_VALUE) {
-if (frag_time >= timestamp)
-b = m;
-if (frag_time <= timestamp)
-a = m;
-}
+m0 = m = (a + b) >> 1;
+
+while (m < b &&
+   (frag_time = get_frag_time(frag_index, m, id)) == 
AV_NOPTS_VALUE)
+m++;
+
+if (m < b && frag_time <= timestamp)
+a = m;
+else
+b = m0;
 }
+
 return a;
 }
 
-- 
2.20.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] lavf/mov: fix hang while seek on a kind of fragmented mp4.

2019-02-01 Thread Charles Liu
Binary searching would hang if the fragment items do NOT have timestamp for the 
specified stream.

For example, a fmp4 consists of separated 'moof' boxes for each track, and 
separated 'sidx' for each segment, but no 'mfra' box.
Then every fragment item only have the timestamp for one of its tracks.

Signed-off-by: Charles Liu 
---
 libavformat/mov.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 9b9739f788..ce1130ad07 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1266,9 +1266,8 @@ static int64_t get_frag_time(MOVFragmentIndex *frag_index,
 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
  AVStream *st, int64_t timestamp)
 {
-int a, b, m;
 int64_t frag_time;
-int id = -1;
+int i, frag = 0, id = -1;
 
 if (st) {
 // If the stream is referenced by any sidx, limit the search
@@ -1278,20 +1277,18 @@ static int search_frag_timestamp(MOVFragmentIndex 
*frag_index,
 id = st->id;
 }
 
-a = -1;
-b = frag_index->nb_items;
-
-while (b - a > 1) {
-m = (a + b) >> 1;
-frag_time = get_frag_time(frag_index, m, id);
+for (i = 0; i < frag_index->nb_items; i++) {
+frag_time = get_frag_time(frag_index, i, id);
 if (frag_time != AV_NOPTS_VALUE) {
-if (frag_time >= timestamp)
-b = m;
 if (frag_time <= timestamp)
-a = m;
+frag = i;
+else {
+break;
+}
 }
 }
-return a;
+
+return frag;
 }
 
 static int update_frag_index(MOVContext *c, int64_t offset)
-- 
2.20.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 5/5] avformat:hlsenc.c: fix the output's duration smaller than input's in sub-range mode.

2018-10-11 Thread Charles Liu
In fmp4 & sub-range mode, the output's duration always smaller than expected, 
because the size of the last #EXT-X-BYTERANGE is too small.

Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 8b3a9b78f4..f8f060d065 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -2380,6 +2380,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
 if (ret < 0) {
 goto failed;
 }
+vs->size = range_length;
 ff_format_io_close(s, >out);
 }
 
@@ -2388,8 +2389,6 @@ failed:
 if (oc->pb) {
 if (hls->segment_type != SEGMENT_TYPE_FMP4) {
 vs->size = avio_tell(vs->avf->pb) - vs->start_pos;
-} else {
-vs->size = avio_tell(vs->avf->pb);
 }
 if (hls->segment_type != SEGMENT_TYPE_FMP4)
 ff_format_io_close(s, >pb);
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 4/5] avformat:hlsenc.c: the size of init.mp4 is zero.

2018-10-11 Thread Charles Liu
The size of init.mp4 is zero in fmp4 mode, when the input duraton smaller than 
the expected segment time.

fix ticket: 7166

Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 0fd5d2a995..8b3a9b78f4 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -2348,6 +2348,25 @@ static int hls_write_trailer(struct AVFormatContext *s)
 return AVERROR(ENOMEM);
 }
 if ( hls->segment_type == SEGMENT_TYPE_FMP4) {
+if (!vs->init_range_length) {
+av_write_frame(vs->avf, NULL); /* Flush any buffered data */
+avio_flush(oc->pb);
+
+uint8_t *buffer = NULL;
+int range_length = avio_close_dyn_buf(oc->pb, );
+avio_write(vs->out, buffer, range_length);
+av_free(buffer);
+vs->init_range_length = range_length;
+avio_open_dyn_buf(>pb);
+vs->packets_written = 0;
+vs->start_pos = range_length;
+int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || 
(hls->max_seg_size > 0);
+if (!byterange_mode) {
+ff_format_io_close(s, >out);
+hlsenc_io_close(s, >out, vs->base_output_dirname);
+}
+}
+
 int range_length = 0;
 if (!(hls->flags & HLS_SINGLE_FILE)) {
 ret = hlsenc_io_open(s, >out, vs->avf->url, NULL);
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 1/5] avformat/hlsenc: fix the duration of m4s segment is unusually smaller than expected.

2018-10-11 Thread Charles Liu
In fmp4 mode, the duration of the second m4s segment is unusually smaller than 
the expected segment time.

Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 28c2dd62fc..3ccd8756f6 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -2233,10 +2233,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 }
 }
 
-if (vs->fmp4_init_mode) {
-vs->number--;
-}
-
 if (hls->segment_type == SEGMENT_TYPE_FMP4) {
 if (hls->flags & HLS_SINGLE_FILE) {
 ret = flush_dynbuf(vs, _length);
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/5] avformat:hlsenc.c: fix memory leak in fmp4 mode.

2018-10-11 Thread Charles Liu
Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 3ccd8756f6..c322b5a48f 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -2205,6 +2205,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 avio_flush(oc->pb);
 range_length = avio_close_dyn_buf(oc->pb, );
 avio_write(vs->out, buffer, range_length);
+av_free(buffer);
 vs->init_range_length = range_length;
 avio_open_dyn_buf(>pb);
 vs->packets_written = 0;
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 3/5] avformat:hlsenc.c: remove the useless variable - fmp4_init_mode.

2018-10-11 Thread Charles Liu
Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index c322b5a48f..0fd5d2a995 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -147,7 +147,6 @@ typedef struct VariantStream {
 
 char *fmp4_init_filename;
 char *base_output_dirname;
-int fmp4_init_mode;
 
 AVStream **streams;
 char codec_attr[128];
@@ -733,7 +732,6 @@ static int hls_mux_init(AVFormatContext *s, VariantStream 
*vs)
 vs->packets_written = 1;
 vs->start_pos = 0;
 vs->new_start = 1;
-vs->fmp4_init_mode = 0;
 
 if (hls->segment_type == SEGMENT_TYPE_FMP4) {
 if (hls->max_seg_size > 0) {
@@ -743,7 +741,6 @@ static int hls_mux_init(AVFormatContext *s, VariantStream 
*vs)
 
 vs->packets_written = 0;
 vs->init_range_length = 0;
-vs->fmp4_init_mode = !byterange_mode;
 set_http_options(s, , hls);
 if ((ret = avio_open_dyn_buf(>pb)) < 0)
 return ret;
@@ -2291,7 +2288,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 vs->start_pos += vs->size;
 }
 
-vs->fmp4_init_mode = 0;
 if (hls->flags & HLS_SINGLE_FILE) {
 vs->number++;
 } else if (hls->max_seg_size > 0) {
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 3/3] avformat:hlsenc.c: remove the useless variable - fmp4_init_mode.

2018-10-09 Thread Charles Liu
Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index c322b5a48f..0fd5d2a995 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -147,7 +147,6 @@ typedef struct VariantStream {
 
 char *fmp4_init_filename;
 char *base_output_dirname;
-int fmp4_init_mode;
 
 AVStream **streams;
 char codec_attr[128];
@@ -733,7 +732,6 @@ static int hls_mux_init(AVFormatContext *s, VariantStream 
*vs)
 vs->packets_written = 1;
 vs->start_pos = 0;
 vs->new_start = 1;
-vs->fmp4_init_mode = 0;
 
 if (hls->segment_type == SEGMENT_TYPE_FMP4) {
 if (hls->max_seg_size > 0) {
@@ -743,7 +741,6 @@ static int hls_mux_init(AVFormatContext *s, VariantStream 
*vs)
 
 vs->packets_written = 0;
 vs->init_range_length = 0;
-vs->fmp4_init_mode = !byterange_mode;
 set_http_options(s, , hls);
 if ((ret = avio_open_dyn_buf(>pb)) < 0)
 return ret;
@@ -2291,7 +2288,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 vs->start_pos += vs->size;
 }
 
-vs->fmp4_init_mode = 0;
 if (hls->flags & HLS_SINGLE_FILE) {
 vs->number++;
 } else if (hls->max_seg_size > 0) {
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/3] avformat:hlsenc.c: fix memory leak in fmp4 mode.

2018-10-09 Thread Charles Liu
Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 3ccd8756f6..c322b5a48f 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -2205,6 +2205,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 avio_flush(oc->pb);
 range_length = avio_close_dyn_buf(oc->pb, );
 avio_write(vs->out, buffer, range_length);
+av_free(buffer);
 vs->init_range_length = range_length;
 avio_open_dyn_buf(>pb);
 vs->packets_written = 0;
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 1/3] avformat/hlsenc: fix the duration of m4s segment is unusually smaller than expected.

2018-10-09 Thread Charles Liu
In fmp4 mode, the duration of the second m4s segment is unusually smaller than 
the expected segment time.

Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 28c2dd62fc..3ccd8756f6 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -2233,10 +2233,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 }
 }
 
-if (vs->fmp4_init_mode) {
-vs->number--;
-}
-
 if (hls->segment_type == SEGMENT_TYPE_FMP4) {
 if (hls->flags & HLS_SINGLE_FILE) {
 ret = flush_dynbuf(vs, _length);
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 3/3] avformat:hlsenc.c: remove the useless variable - fmp4_init_mode.

2018-10-09 Thread Charles Liu
Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index c322b5a48f..0fd5d2a995 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -147,7 +147,6 @@ typedef struct VariantStream {
 
 char *fmp4_init_filename;
 char *base_output_dirname;
-int fmp4_init_mode;
 
 AVStream **streams;
 char codec_attr[128];
@@ -733,7 +732,6 @@ static int hls_mux_init(AVFormatContext *s, VariantStream 
*vs)
 vs->packets_written = 1;
 vs->start_pos = 0;
 vs->new_start = 1;
-vs->fmp4_init_mode = 0;
 
 if (hls->segment_type == SEGMENT_TYPE_FMP4) {
 if (hls->max_seg_size > 0) {
@@ -743,7 +741,6 @@ static int hls_mux_init(AVFormatContext *s, VariantStream 
*vs)
 
 vs->packets_written = 0;
 vs->init_range_length = 0;
-vs->fmp4_init_mode = !byterange_mode;
 set_http_options(s, , hls);
 if ((ret = avio_open_dyn_buf(>pb)) < 0)
 return ret;
@@ -2291,7 +2288,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 vs->start_pos += vs->size;
 }
 
-vs->fmp4_init_mode = 0;
 if (hls->flags & HLS_SINGLE_FILE) {
 vs->number++;
 } else if (hls->max_seg_size > 0) {
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/2] avformat:hlsenc.c: fix memory leak in fmp4 mode.

2018-10-09 Thread Charles Liu
Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 3ccd8756f6..c322b5a48f 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -2205,6 +2205,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 avio_flush(oc->pb);
 range_length = avio_close_dyn_buf(oc->pb, );
 avio_write(vs->out, buffer, range_length);
+av_free(buffer);
 vs->init_range_length = range_length;
 avio_open_dyn_buf(>pb);
 vs->packets_written = 0;
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 1/2] avformat/hlsenc: fix the duration of m4s segment is unusually smaller than expected.

2018-10-09 Thread Charles Liu
In fmp4 mode, the duration of the second m4s segment is unusually smaller than 
the expected segment time.

Signed-off-by: Charles Liu 
---
 libavformat/hlsenc.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 28c2dd62fc..3ccd8756f6 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -2233,10 +2233,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 }
 }
 
-if (vs->fmp4_init_mode) {
-vs->number--;
-}
-
 if (hls->segment_type == SEGMENT_TYPE_FMP4) {
 if (hls->flags & HLS_SINGLE_FILE) {
 ret = flush_dynbuf(vs, _length);
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel