libdvr: recording the channel for 14H,play PVR video,start playing after 15S. [1/1]

PD#SWPL-66574

Problem:
Get segment info spent much time.Record
creat more than 1000 segments,we need get segment info from
more than 1000 segments dat file.

Solution:
1 Add store all segment info file and add load all segment info api.

Verify:
t5

Signed-off-by: hualing chen <hualing.chen@amlogic.com>
Change-Id: I71a74c3cdee1fe6b106fa1a0151782da0bc9c03c
diff --git a/include/dvr_segment.h b/include/dvr_segment.h
index 1a27d5a..e4aac63 100644
--- a/include/dvr_segment.h
+++ b/include/dvr_segment.h
@@ -52,6 +52,16 @@
  */
 int dvr_segment_get_info(const char *location, uint64_t segment_id, DVR_RecordSegmentInfo_t *p_info);
 
+/**\brief Get the segment's information
+ * \param[in] location The record file's location
+ * \param[in] segment_id The segment index
+ * \param[out] p_info Return the segment's information
+ * \return DVR_SUCCESS On success
+ * \return Error code On failure
+ */
+
+int dvr_segment_get_allInfo(const char *location, struct list_head *list);
+
 /**\brief Link a segment group as the record file's list
  * \param[in] location The record file's location
  * \param[in] nb_segments The number of segments
diff --git a/include/dvr_types.h b/include/dvr_types.h
index 727d73a..013af7e 100644
--- a/include/dvr_types.h
+++ b/include/dvr_types.h
@@ -22,6 +22,7 @@
 #include <assert.h>
 #include <pthread.h>
 
+#include "list.h"
 #include <android/log.h>
 
 #ifndef __ANDROID_API__
@@ -201,6 +202,7 @@
 
 /**\brief Segment store information*/
 typedef struct {
+  struct  list_head   head;         /**< Segment node.*/
   uint64_t            id;                                         /**< DVR segment id*/
   uint32_t            nb_pids;                                    /**< DVR segment number of pids*/
   DVR_StreamPid_t     pids[DVR_MAX_RECORD_PIDS_COUNT];            /**< DVR pids information*/
diff --git a/include/segment.h b/include/segment.h
index 00725ce..888c97f 100644
--- a/include/segment.h
+++ b/include/segment.h
@@ -126,6 +126,14 @@
  */
 int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info);
 
+/**\brief Store the segment all information to a file
+ * \param[in] handle, The segment handle
+ * \param[in] p_info, The segment information pointer
+ * \return DVR_SUCCESS On success
+ * \return Error code On failure
+ */
+int segment_store_allInfo(Segment_Handle_t handle, Segment_StoreInfo_t *p_info);
+
 /**\brief Load the segment information from a file
  * \param[in] handle, The segment handle
  * \param[out] p_info, The segment information pointer
@@ -134,6 +142,15 @@
  */
 int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info);
 
+/**\brief Load the segment information from a file
+ * \param[in] handle, The segment handle
+ * \param[out] p_info, The segment information pointer
+ * \return DVR_SUCCESS On success
+ * \return Error code On failure
+ */
+int segment_load_allInfo(Segment_Handle_t handle, struct list_head *list);
+
+
 /**\brief Delete the segment information file
  * \param[in] location, The record file's location
  * \param[in] segment_id, The segment's index
diff --git a/src/dvr_playback.c b/src/dvr_playback.c
index 1f07503..debc9bd 100644
--- a/src/dvr_playback.c
+++ b/src/dvr_playback.c
@@ -1402,13 +1402,15 @@
 
     pthread_mutex_lock(&player->segment_lock);
     player->ts_cache_len = real_read;
-    first_write++;
-    if (first_write == 1)
-    DVR_PB_DG(1, "----firsr write ts data");
+    //used for printf first write data time.
+    //to check change channel kpi.
+    if (first_write == 0) {
+      first_write++;
+      DVR_PB_DG(1, "----firsr write ts data");
+    }
+
     ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
     if (ret == AM_TSPLAYER_OK) {
-    DVR_PB_DG(1, "----ok write ts data");
-
       player->ts_cache_len = 0;
       pthread_mutex_unlock(&player->segment_lock);
       real_read = 0;
diff --git a/src/dvr_record.c b/src/dvr_record.c
index 1d7dd88..f1fd4bb 100644
--- a/src/dvr_record.c
+++ b/src/dvr_record.c
@@ -671,7 +671,7 @@
 
   ret = segment_store_info(p_ctx->segment_handle, p_info);
   DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
-
+  ret = segment_store_allInfo(p_ctx->segment_handle, p_info);
   DVR_DEBUG(1, "%s dump segment info, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d params->segment.nb_pids:%d",
       __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets, params->segment.nb_pids);
 
@@ -776,6 +776,8 @@
   if (ret != DVR_SUCCESS)
       goto end;
 
+  segment_store_allInfo(p_ctx->segment_handle, p_info);
+
   DVR_DEBUG(1, "%s dump segment info, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
       __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
 
diff --git a/src/dvr_segment.c b/src/dvr_segment.c
index d9d36c4..83e2845 100644
--- a/src/dvr_segment.c
+++ b/src/dvr_segment.c
@@ -192,6 +192,31 @@
   return DVR_SUCCESS;
 }
 
+int dvr_segment_get_allInfo(const char *location, struct list_head *list)
+{
+  int ret;
+  Segment_OpenParams_t open_params;
+  Segment_Handle_t segment_handle;
+
+  DVR_RETURN_IF_FALSE(location);
+  DVR_RETURN_IF_FALSE(list);
+  DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
+
+  memset(&open_params, 0, sizeof(open_params));
+  memcpy(open_params.location, location, strlen(location));
+  open_params.segment_id = 0;
+  open_params.mode = SEGMENT_MODE_READ;
+  ret = segment_open(&open_params, &segment_handle);
+  if (ret == DVR_SUCCESS) {
+    ret = segment_load_allInfo(segment_handle, list);
+  }
+  ret = segment_close(segment_handle);
+  DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
+
+  return DVR_SUCCESS;
+}
+
+
 int dvr_segment_link(const char *location, uint32_t nb_segments, uint64_t *p_segment_ids)
 {
   return dvr_segment_link_op(location, nb_segments, p_segment_ids, LSEG_OP_NEW);
diff --git a/src/dvr_wrapper.c b/src/dvr_wrapper.c
index 42564a5..e2f3526 100644
--- a/src/dvr_wrapper.c
+++ b/src/dvr_wrapper.c
@@ -1489,57 +1489,133 @@
   error = dvr_segment_get_list(ctx->playback.param_open.location, &segment_nb, &p_segment_ids);
   if (!error) {
     got_1st_seg = 0;
+    struct list_head           info_list;         /**< segment list head*/
+    INIT_LIST_HEAD(&info_list);
+
     DVR_WRAPPER_DEBUG(1, "get list segment_nb::%d",segment_nb);
-    for (i = 0; i < segment_nb; i++) {
-      DVR_RecordSegmentInfo_t seg_info;
-      DVR_PlaybackSegmentFlag_t flags;
+    //we need free info list buf when we used end.
+    error = dvr_segment_get_allInfo(ctx->playback.param_open.location, &info_list);
+    if (error) {
+          error = DVR_FAILURE;
+          DVR_WRAPPER_DEBUG(1, "fail to get all seg info (location:%s, seg:%llu), (error:%d)\n",
+            ctx->playback.param_open.location, p_segment_ids[i], error);
+          for (i = 0; i < segment_nb; i++) {
+            DVR_RecordSegmentInfo_t seg_info;
+            DVR_PlaybackSegmentFlag_t flags;
 
-      error = dvr_segment_get_info(ctx->playback.param_open.location, p_segment_ids[i], &seg_info);
-      if (error) {
-        error = DVR_FAILURE;
-        DVR_WRAPPER_DEBUG(1, "fail to get seg info (location:%s, seg:%llu), (error:%d)\n",
-          ctx->playback.param_open.location, p_segment_ids[i], error);
-        break;
-      }
-      //add check if has audio  or video pid. if not exist. not add segment to playback
-      int ii = 0;
-      int has_av = 0;
-      for (ii = 0; ii < seg_info.nb_pids; ii++) {
-        int type = (seg_info.pids[ii].type >> 24) & 0x0f;
-        if (type == DVR_STREAM_TYPE_VIDEO ||
-          type == DVR_STREAM_TYPE_AUDIO ||
-          type == DVR_STREAM_TYPE_AD) {
-         DVR_WRAPPER_DEBUG(1, "success to get seg av info \n");
-          DVR_WRAPPER_DEBUG(1, "success to get seg av info type[0x%x][%d] [%d][%d][%d]\n",(seg_info.pids[ii].type >> 24)&0x0f,seg_info.pids[ii].pid,
-          DVR_STREAM_TYPE_VIDEO,
-          DVR_STREAM_TYPE_AUDIO,
-          DVR_STREAM_TYPE_AD);
-          has_av = 1;
-          //break;
-        } else {
-          DVR_WRAPPER_DEBUG(1, "error to get seg av info type[0x%x][%d] [%d][%d][%d]\n",(seg_info.pids[ii].type >> 24)&0x0f,seg_info.pids[ii].pid,
-          DVR_STREAM_TYPE_VIDEO,
-          DVR_STREAM_TYPE_AUDIO,
-          DVR_STREAM_TYPE_AD);
+            error = dvr_segment_get_info(ctx->playback.param_open.location, p_segment_ids[i], &seg_info);
+            if (error) {
+              error = DVR_FAILURE;
+              DVR_WRAPPER_DEBUG(1, "fail to get seg info (location:%s, seg:%llu), (error:%d)\n",
+                ctx->playback.param_open.location, p_segment_ids[i], error);
+              break;
+            }
+            //add check if has audio  or video pid. if not exist. not add segment to playback
+            int ii = 0;
+            int has_av = 0;
+            for (ii = 0; ii < seg_info.nb_pids; ii++) {
+              int type = (seg_info.pids[ii].type >> 24) & 0x0f;
+              if (type == DVR_STREAM_TYPE_VIDEO ||
+                type == DVR_STREAM_TYPE_AUDIO ||
+                type == DVR_STREAM_TYPE_AD) {
+              DVR_WRAPPER_DEBUG(1, "success to get seg av info \n");
+                DVR_WRAPPER_DEBUG(1, "success to get seg av info type[0x%x][%d] [%d][%d][%d]\n",(seg_info.pids[ii].type >> 24)&0x0f,seg_info.pids[ii].pid,
+                DVR_STREAM_TYPE_VIDEO,
+                DVR_STREAM_TYPE_AUDIO,
+                DVR_STREAM_TYPE_AD);
+                has_av = 1;
+                //break;
+              } else {
+                DVR_WRAPPER_DEBUG(1, "error to get seg av info type[0x%x][%d] [%d][%d][%d]\n",(seg_info.pids[ii].type >> 24)&0x0f,seg_info.pids[ii].pid,
+                DVR_STREAM_TYPE_VIDEO,
+                DVR_STREAM_TYPE_AUDIO,
+                DVR_STREAM_TYPE_AD);
+              }
+            }
+            if (has_av == 0) {
+              DVR_WRAPPER_DEBUG(1, "fail to get seg av info \n");
+              continue;
+            } else {
+              DVR_WRAPPER_DEBUG(1, "success to get seg av info \n");
+            }
+            flags = DVR_PLAYBACK_SEGMENT_DISPLAYABLE | DVR_PLAYBACK_SEGMENT_CONTINUOUS;
+            error = wrapper_addPlaybackSegment(ctx, &seg_info, p_pids, flags);
+            if (error)
+              break;
+            /*copy the 1st segment*/
+            if (got_1st_seg == 0) {
+                seg_info_1st = seg_info;
+                got_1st_seg = 1;
+            }
+          }
+    } else {
+        for (i = 0; i < segment_nb; i++) {
+          DVR_RecordSegmentInfo_t *seg_info;
+          DVR_PlaybackSegmentFlag_t flags;
+          int found = 0;
+          list_for_each_entry(seg_info, &info_list, head)
+          {
+            if (seg_info->id == i) {
+              found = 1;
+              DVR_WRAPPER_DEBUG(1, "get segment info::%d", i);
+              break;
+            }
+          }
+          if (!found) {
+            continue;
+          }
+
+          //add check if has audio  or video pid. if not exist. not add segment to playback
+          int ii = 0;
+          int has_av = 0;
+          for (ii = 0; ii < seg_info->nb_pids; ii++) {
+            int type = (seg_info->pids[ii].type >> 24) & 0x0f;
+            if (type == DVR_STREAM_TYPE_VIDEO ||
+              type == DVR_STREAM_TYPE_AUDIO ||
+              type == DVR_STREAM_TYPE_AD) {
+            DVR_WRAPPER_DEBUG(1, "success to get seg av info \n");
+              DVR_WRAPPER_DEBUG(1, "success to get seg av info type[0x%x][%d] [%d][%d][%d]\n",(seg_info->pids[ii].type >> 24)&0x0f,seg_info->pids[ii].pid,
+              DVR_STREAM_TYPE_VIDEO,
+              DVR_STREAM_TYPE_AUDIO,
+              DVR_STREAM_TYPE_AD);
+              has_av = 1;
+              //break;
+            } else {
+              DVR_WRAPPER_DEBUG(1, "error to get seg av info type[0x%x][%d] [%d][%d][%d]\n",(seg_info->pids[ii].type >> 24)&0x0f,seg_info->pids[ii].pid,
+              DVR_STREAM_TYPE_VIDEO,
+              DVR_STREAM_TYPE_AUDIO,
+              DVR_STREAM_TYPE_AD);
+            }
+          }
+          if (has_av == 0) {
+            DVR_WRAPPER_DEBUG(1, "fail to get seg av info \n");
+            continue;
+          } else {
+            DVR_WRAPPER_DEBUG(1, "success to get seg av info \n");
+          }
+          flags = DVR_PLAYBACK_SEGMENT_DISPLAYABLE | DVR_PLAYBACK_SEGMENT_CONTINUOUS;
+          error = wrapper_addPlaybackSegment(ctx, seg_info, p_pids, flags);
+          if (error)
+            break;
+
+          /*copy the 1st segment*/
+          if (got_1st_seg == 0) {
+              seg_info_1st = *seg_info;
+              got_1st_seg = 1;
+          }
         }
-      }
-      if (has_av == 0) {
-        DVR_WRAPPER_DEBUG(1, "fail to get seg av info \n");
-        continue;
-      } else {
-        DVR_WRAPPER_DEBUG(1, "success to get seg av info \n");
-      }
-      flags = DVR_PLAYBACK_SEGMENT_DISPLAYABLE | DVR_PLAYBACK_SEGMENT_CONTINUOUS;
-      error = wrapper_addPlaybackSegment(ctx, &seg_info, p_pids, flags);
-      if (error)
-        break;
-
-      /*copy the 1st segment*/
-      if (got_1st_seg == 0) {
-          seg_info_1st = seg_info;
-          got_1st_seg = 1;
-      }
+        //free list
+        DVR_RecordSegmentInfo_t *segment = NULL;
+        DVR_RecordSegmentInfo_t *segment_tmp = NULL;
+        list_for_each_entry_safe(segment, segment_tmp, &info_list, head)
+        {
+            if (segment) {
+              list_del(&segment->head);
+              free(segment);
+            }
+        }
     }
+
     free(p_segment_ids);
 
     /* return if no segment or fail to add */
@@ -2045,24 +2121,75 @@
   int error;
   uint32_t n_ids;
   uint64_t *p_ids;
-  DVR_RecordSegmentInfo_t info;
 
-  memset(&info, 0, sizeof(info));
   error = dvr_segment_get_list(fpath, &n_ids, &p_ids);
+
   if (!error) {
      int i;
-     for (i = 0; i < n_ids; i++) {
-        error = dvr_segment_get_info(fpath, p_ids[i], &info);
-        if (!error) {
-           p_info->size += info.size;
-           p_info->time += info.duration;
-           p_info->pkts += info.nb_packets;
-        } else {
-           DVR_WRAPPER_DEBUG(1, "%s:%lld get seg info fail.\n", fpath, p_ids[i]);
-           break;
-        }
-     }
-     free(p_ids);
+     struct list_head           info_list;         /**< segment list head*/
+    INIT_LIST_HEAD(&info_list);
+
+    //we need free info list buf when we used end.
+    error = dvr_segment_get_allInfo(fpath, &info_list);
+    if (error) {
+      DVR_RecordSegmentInfo_t info;
+
+      memset(&info, 0, sizeof(info));
+      error = DVR_FAILURE;
+      DVR_WRAPPER_DEBUG(1, "fail to get seg info (location:%s, seg:%llu), (error:%d)\n",
+        fpath, 0, error);
+
+      for (i = 0; i < n_ids; i++) {
+          error = dvr_segment_get_info(fpath, p_ids[i], &info);
+          if (!error) {
+            p_info->size += info.size;
+            p_info->time += info.duration;
+            p_info->pkts += info.nb_packets;
+          } else {
+            DVR_WRAPPER_DEBUG(1, "%s:%lld get seg info fail.\n", fpath, p_ids[i]);
+            break;
+          }
+      }
+    } else {
+      DVR_WRAPPER_DEBUG(1, "get list segment_nb::%d",n_ids);
+      for (i = 0; i < n_ids; i++) {
+
+          DVR_RecordSegmentInfo_t *seg_info;
+          DVR_PlaybackSegmentFlag_t flags;
+          int found = 0;
+          list_for_each_entry(seg_info, &info_list, head)
+          {
+            if (seg_info->id == i) {
+              found = 1;
+              break;
+            }
+          }
+          if (!found) {
+              DVR_WRAPPER_DEBUG(1, "get segment info::%d error", i);
+              continue;
+          }
+
+          if (!error) {
+            p_info->size += seg_info->size;
+            p_info->time += seg_info->duration;
+            p_info->pkts += seg_info->nb_packets;
+          } else {
+            DVR_WRAPPER_DEBUG(1, "%s:%lld get seg info fail.\n", fpath, p_ids[i]);
+            break;
+          }
+      }
+      //free list
+      DVR_RecordSegmentInfo_t *segment = NULL;
+      DVR_RecordSegmentInfo_t *segment_tmp = NULL;
+      list_for_each_entry_safe(segment, segment_tmp, &info_list, head)
+      {
+          if (segment) {
+            list_del(&segment->head);
+            free(segment);
+          }
+      }
+    }
+    free(p_ids);
   } else {
      n_ids = 0;
   }
diff --git a/src/segment.c b/src/segment.c
index 3bd8938..ff47455 100644
--- a/src/segment.c
+++ b/src/segment.c
@@ -22,6 +22,7 @@
   int             ts_fd;                              /**< Segment ts file fd*/
   FILE            *index_fp;                          /**< Time index file fd*/
   FILE            *dat_fp;                            /**< Information file fd*/
+  FILE            *all_dat_fp;                            /**< Information file fd*/
   FILE            *ongoing_fp;                        /**< Ongoing file fd, used to verify timedhift mode*/
   uint64_t        first_pts;                          /**< First pts value, use for write mode*/
   uint64_t        last_pts;                           /**< Last input pts value, use for write mode*/
@@ -41,6 +42,7 @@
   SEGMENT_FILE_TYPE_INDEX,                    /**< Used for store index data*/
   SEGMENT_FILE_TYPE_DAT,                      /**< Used for store information data, such as duration etc*/
   SEGMENT_FILE_TYPE_ONGOING,                  /**< Used for store information data, such as duration etc*/
+  SEGMENT_FILE_TYPE_ALLDAT,                  /**< Used for store all information data*/
 } Segment_FileType_t;
 
 static void segment_get_fname(char fname[MAX_SEGMENT_PATH_SIZE],
@@ -53,10 +55,13 @@
   memset(fname, 0, MAX_SEGMENT_PATH_SIZE);
   strncpy(fname, location, strlen(location));
   offset = strlen(location);
-  strncpy(fname + offset, "-", 1);
-  offset += 1;
-  sprintf(fname + offset, "%04llu", segment_id);
-  offset += 4;
+  if (type != SEGMENT_FILE_TYPE_ALLDAT) {
+    strncpy(fname + offset, "-", 1);
+    offset += 1;
+    sprintf(fname + offset, "%04llu", segment_id);
+    offset += 4;
+  }
+
   if (type == SEGMENT_FILE_TYPE_TS)
     strncpy(fname + offset, ".ts", 3);
   else if (type == SEGMENT_FILE_TYPE_INDEX)
@@ -65,6 +70,9 @@
     strncpy(fname + offset, ".dat", 4);
   else if (type == SEGMENT_FILE_TYPE_ONGOING)
     strncpy(fname + offset, ".going", 6);
+  else if (type == SEGMENT_FILE_TYPE_ALLDAT)
+    strncpy(fname + offset, ".dat", 4);
+
 }
 
 static void segment_get_dirname(char dir_name[MAX_SEGMENT_PATH_SIZE],
@@ -90,6 +98,7 @@
   char ts_fname[MAX_SEGMENT_PATH_SIZE];
   char index_fname[MAX_SEGMENT_PATH_SIZE];
   char dat_fname[MAX_SEGMENT_PATH_SIZE];
+  char all_dat_fname[MAX_SEGMENT_PATH_SIZE];
   char dir_name[MAX_SEGMENT_PATH_SIZE];
   char going_name[MAX_SEGMENT_PATH_SIZE];
 
@@ -111,6 +120,10 @@
   memset(dat_fname, 0, sizeof(dat_fname));
   segment_get_fname(dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_DAT);
 
+  memset(all_dat_fname, 0, sizeof(all_dat_fname));
+  segment_get_fname(all_dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_ALLDAT);
+
+
   memset(going_name, 0, sizeof(going_name));
   segment_get_fname(going_name, params->location, params->segment_id, SEGMENT_FILE_TYPE_ONGOING);
 
@@ -126,10 +139,12 @@
     p_ctx->index_fp = fopen(index_fname, "r");
     p_ctx->dat_fp = fopen(dat_fname, "r");
     p_ctx->ongoing_fp = NULL;
+    p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
   } else if (params->mode == SEGMENT_MODE_WRITE) {
     p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
     p_ctx->index_fp = fopen(index_fname, "w+");
     p_ctx->dat_fp = fopen(dat_fname, "w+");
+    p_ctx->all_dat_fp = fopen(all_dat_fname, "a+");
     p_ctx->ongoing_fp = fopen(going_name, "w+");
     p_ctx->first_pts = ULLONG_MAX;
     p_ctx->last_pts = ULLONG_MAX;
@@ -140,6 +155,7 @@
     p_ctx->ts_fd = open(ts_fname, O_RDONLY);
     p_ctx->index_fp = fopen(index_fname, "r");
     p_ctx->dat_fp = fopen(dat_fname, "r");
+    p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
     p_ctx->ongoing_fp = NULL;
   }
 
@@ -643,6 +659,58 @@
 }
 
 /* Should consider the case of cut power, todo... */
+int segment_store_allInfo(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
+{
+  Segment_Context_t *p_ctx;
+  char buf[256];
+  uint32_t i;
+
+  p_ctx = (Segment_Context_t *)handle;
+  DVR_RETURN_IF_FALSE(p_ctx);
+  DVR_RETURN_IF_FALSE(p_ctx->all_dat_fp);
+  DVR_RETURN_IF_FALSE(p_info);
+  //seek 0, rewrite info
+  DVR_RETURN_IF_FALSE(fseek(p_ctx->all_dat_fp, 0, SEEK_END) != -1);
+
+  /*Save segment id*/
+  memset(buf, 0, sizeof(buf));
+  sprintf(buf, "id=%lld\n", p_info->id);
+  fputs(buf, p_ctx->all_dat_fp);
+
+  /*Save number of pids*/
+  memset(buf, 0, sizeof(buf));
+  sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
+  fputs(buf, p_ctx->all_dat_fp);
+
+  /*Save pid information*/
+  for (i = 0; i < p_info->nb_pids; i++) {
+    memset(buf, 0, sizeof(buf));
+    sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
+    fputs(buf, p_ctx->all_dat_fp);
+  }
+
+  /*Save segment duration*/
+  memset(buf, 0, sizeof(buf));
+  DVR_DEBUG(1, "duration store:[%ld]", p_info->duration);
+  sprintf(buf, "duration=%ld\n", p_info->duration);
+  fputs(buf, p_ctx->all_dat_fp);
+
+  /*Save segment size*/
+  memset(buf, 0, sizeof(buf));
+  sprintf(buf, "size=%zu\n", p_info->size);
+  fputs(buf, p_ctx->all_dat_fp);
+
+  /*Save number of packets*/
+  memset(buf, 0, sizeof(buf));
+  sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
+  fputs(buf, p_ctx->all_dat_fp);
+
+  fflush(p_ctx->all_dat_fp);
+  fsync(fileno(p_ctx->all_dat_fp));
+  return DVR_SUCCESS;
+}
+
+/* Should consider the case of cut power, todo... */
 int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
 {
   Segment_Context_t *p_ctx;
@@ -721,6 +789,100 @@
   return DVR_SUCCESS;
 }
 
+/* Should consider the case of cut power, todo... */
+int segment_load_allInfo(Segment_Handle_t handle, struct list_head *list)
+{
+  Segment_Context_t *p_ctx;
+  uint32_t i;
+  char buf[256];
+  char value[256];
+  char *p1, *p2;
+
+  p_ctx = (Segment_Context_t *)handle;
+  DVR_RETURN_IF_FALSE(p_ctx);
+  DVR_RETURN_IF_FALSE(list);
+
+  //first get
+  p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
+  DVR_RETURN_IF_FALSE(p1);
+
+  do {
+
+    DVR_RecordSegmentInfo_t *p_info;
+
+    p_info = malloc(sizeof(DVR_RecordSegmentInfo_t));
+    memset(p_info, 0, sizeof(DVR_RecordSegmentInfo_t));
+
+    list_add_tail(&p_info->head, list);
+
+    /*Load segment id*/
+    DVR_RETURN_IF_FALSE(p1);
+    p1 = strstr(buf, "id=");
+    DVR_RETURN_IF_FALSE(p1);
+    p_info->id = strtoull(p1 + 3, NULL, 10);
+
+    /*Save number of pids*/
+    p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
+    DVR_RETURN_IF_FALSE(p1);
+    p1 = strstr(buf, "nb_pids=");
+    DVR_RETURN_IF_FALSE(p1);
+    p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
+
+    /*Save pid information*/
+    for (i = 0; i < p_info->nb_pids; i++) {
+      p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
+      DVR_RETURN_IF_FALSE(p1);
+      memset(value, 0, sizeof(value));
+      if ((p1 = strstr(buf, "pid="))) {
+        DVR_RETURN_IF_FALSE(p1);
+        p1 += 4;
+        if ((p2 = strstr(buf, ","))) {
+          DVR_RETURN_IF_FALSE(p2);
+          memcpy(value, p1, p2 - p1);
+        }
+        p_info->pids[i].pid = strtoull(value, NULL, 10);
+      }
+
+      memset(value, 0, sizeof(value));
+      if ((p1 = strstr(buf, "type="))) {
+        DVR_RETURN_IF_FALSE(p1);
+        p1 += 5;
+        if ((p2 = strstr(buf, "}"))) {
+          DVR_RETURN_IF_FALSE(p2);
+          memcpy(value, p1, p2 - p1);
+        }
+        p_info->pids[i].type = strtoull(value, NULL, 10);
+      }
+    }
+
+    /*Save segment duration*/
+    p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
+    DVR_RETURN_IF_FALSE(p1);
+    p1 = strstr(buf, "duration=");
+    DVR_RETURN_IF_FALSE(p1);
+    p_info->duration = strtoull(p1 + 9, NULL, 10);
+    //DVR_DEBUG(1, "load info p_info->duration:%lld", p_info->duration);
+
+    /*Save segment size*/
+    p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
+    DVR_RETURN_IF_FALSE(p1);
+    p1 = strstr(buf, "size=");
+    DVR_RETURN_IF_FALSE(p1);
+    p_info->size = strtoull(p1 + 5, NULL, 10);
+
+    /*Save number of packets*/
+    p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
+    DVR_RETURN_IF_FALSE(p1);
+    p1 = strstr(buf, "nb_packets=");
+    DVR_RETURN_IF_FALSE(p1);
+    p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
+    //if reach end,exit loop
+    p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
+  } while (p1);
+
+  return DVR_SUCCESS;
+}
+
 int segment_delete(const char *location, uint64_t segment_id)
 {
   char fname[MAX_SEGMENT_PATH_SIZE];