dvr: implement clear pullvod record [1/1]
PD#SWPL-18817
Problem:
New feature
Solution:
implement clear pullvod record and
add PCR time index
Verify:
Android Q + AC214
Change-Id: Ib16a7990bd901d82132e72ac18792763e4226ba3
Signed-off-by: pengfei.liu <pengfei.liu@amlogic.com>
diff --git a/src/dvr_record.c b/src/dvr_record.c
index 7a32fbf..7360d3f 100644
--- a/src/dvr_record.c
+++ b/src/dvr_record.c
@@ -10,6 +10,22 @@
#include "segment.h"
#define MAX_DVR_RECORD_SESSION_COUNT 2
+
+/**\brief DVR index file type*/
+typedef enum {
+ DVR_INDEX_TYPE_PCR, /**< DVR index file use pcr*/
+ DVR_INDEX_TYPE_LOCAL_CLOCK, /**< DVR index file use local clock*/
+ DVR_INDEX_TYPE_INVALID /**< DVR index file type invalid type*/
+} DVR_IndexType_t;
+
+/**\brief DVR VOD context*/
+typedef struct {
+ pthread_mutex_t mutex; /**< VOD mutex lock*/
+ pthread_cond_t cond; /**< VOD condition*/
+ void *buffer; /**< VOD buffer*/
+ uint32_t buf_len; /**< VOD buffer len*/
+} DVR_VodContext_t;
+
/**\brief DVR record context*/
typedef struct {
pthread_t thread; /**< DVR thread handle*/
@@ -22,6 +38,8 @@
size_t notification_size; /**< DVR record nogification size*/
DVR_RecordEventFunction_t event_notify_fn; /**< DVR record event notify function*/
void *event_userdata; /**< DVR record event userdata*/
+ //DVR_VodContext_t vod; /**< DVR record vod context*/
+ int is_vod; /**< Indicate current mode is VOD record mode*/
} DVR_RecordContext_t;
static DVR_RecordContext_t record_ctx[MAX_DVR_RECORD_SESSION_COUNT] = {
@@ -33,17 +51,106 @@
}
};
+//#define USE_TEST_DATA
+#ifdef USE_TEST_DATA
+static int test_data_read(uint8_t *buf, int len)
+{
+ int i;
+ for (i = 0; i < len; i++) {
+ buf[i] = i % 0xff;
+ }
+ usleep(50*1000);
+ return len;
+}
+#endif
+
+static int record_save_pcr(DVR_RecordContext_t *p_ctx, uint8_t *buf, loff_t pos)
+{
+ uint8_t *p = buf;
+ int len;
+ uint8_t afc;
+ uint64_t pcr = 0;
+ int has_pcr = 0;
+ int pid;
+ int adp_field_len;
+
+ pid = ((p[1] & 0x1f) << 8) | p[2];
+ if (pid == 0x1fff)
+ return has_pcr;
+
+ //scramble = p[3] >> 6;
+ //cc = p[3] & 0x0f;
+ afc = (p[3] >> 4) & 0x03;
+
+ p += 4;
+ len = 184;
+
+ if (afc & 2) {
+ adp_field_len = p[0];
+ /* Skip adaptation len */
+ p++;
+ len--;
+ /* Parse pcr field, see 13818 spec table I-2-6,adaptation_field */
+ if (p[0] & 0x10 && len >= 6) {
+ /* get pcr value,pcr is 33bit value */
+ pcr = (((uint64_t)(p[1])) << 25)
+ | (((uint64_t)p[2]) << 17)
+ | (((uint64_t)(p[3])) << 9)
+ | (((uint64_t)p[4]) << 1)
+ | ((((uint64_t)p[5]) & 0x80) >> 7);
+ has_pcr = 1;
+ }
+
+ p += adp_field_len;
+ len -= adp_field_len;
+
+ if (len < 0) {
+ DVR_DEBUG(1, "parser pcr: illegal adaptation field length");
+ return 0;
+ }
+ }
+
+ if (has_pcr) {
+ segment_update_pts(p_ctx->segment_handle, pcr/90, pos);
+ }
+ return has_pcr;
+}
+
+static int record_do_pcr_index(DVR_RecordContext_t *p_ctx, uint8_t *buf, int len)
+{
+ uint8_t *p = buf;
+ int left = len;
+ loff_t pos;
+ int has_pcr = 0;
+
+ pos = segment_tell_position(p_ctx->segment_handle);
+ while (left >= 188) {
+ if (*p == 0x47) {
+ has_pcr |= record_save_pcr(p_ctx, p, pos);
+ p += 188;
+ left -= 188;
+ pos += 188;
+ } else {
+ p++;
+ left --;
+ pos++;
+ }
+ }
+ return has_pcr;
+}
+
void *record_thread(void *arg)
{
DVR_RecordContext_t *p_ctx = (DVR_RecordContext_t *)arg;
ssize_t len;
uint8_t *buf;
int block_size = 256*1024;
- off_t pos = 0;
- uint64_t pts = 0;
+ loff_t pos = 0;
int ret;
struct timespec start_ts, end_ts;
DVR_RecordStatus_t record_status;
+ int has_pcr;
+ int index_type = DVR_INDEX_TYPE_INVALID;
buf = (uint8_t *)malloc(block_size);
if (!buf) {
@@ -53,33 +160,59 @@
clock_gettime(CLOCK_MONOTONIC, &start_ts);
while (p_ctx->state == DVR_RECORD_STATE_STARTED) {
+ /* data from dmx, normal dvr case */
+#ifdef USE_TEST_DATA
+ len = test_data_read(buf, block_size);
+#else
len = record_device_read(p_ctx->dev_handle, buf, block_size, 1000);
+#endif
if (len == DVR_FAILURE) {
usleep(10*1000);
continue;
}
-#if 0
- ret = sw_dmx_extract_pcr(buf, len, &pts, &pos);
- if (ret == DVR_FAILURE) {
- get_local_pts(&pts);
+ /* got data from device, record it */
+ pos = segment_tell_position(p_ctx->segment_handle);
+ has_pcr = record_do_pcr_index(p_ctx, buf, len);
+ if (has_pcr == 0 && index_type == DVR_INDEX_TYPE_INVALID) {
+ clock_gettime(CLOCK_MONOTONIC, &end_ts);
+ if ((end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
+ (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) > 40) {
+ /* PCR interval threshlod > 40 ms*/
+ DVR_DEBUG(1, "%s use local clock time index", __func__);
+ index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
+ }
+ } else if (has_pcr && index_type == DVR_INDEX_TYPE_INVALID){
+ DVR_DEBUG(1, "%s use pcr time index", __func__);
+ index_type = DVR_INDEX_TYPE_PCR;
}
-#endif
- pos += segment_tell_position(p_ctx->segment_handle);
- ret = segment_update_pts(p_ctx->segment_handle, pts, pos);
ret = segment_write(p_ctx->segment_handle, buf, len);
+
+ /* Update segment info */
p_ctx->segment_info.size += len;
+ /*Duration need use pcr to calculate, todo...*/
+ if (index_type == DVR_INDEX_TYPE_PCR) {
+ p_ctx->segment_info.duration = segment_tell_time(p_ctx->segment_handle);
+ } else if (index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
+ clock_gettime(CLOCK_MONOTONIC, &end_ts);
+ p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
+ (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000);
+ segment_update_pts(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
+ } else {
+ DVR_DEBUG(1, "%s can NOT do time index", __func__);
+ }
+ p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
/*Event notification*/
if (p_ctx->notification_size &&
p_ctx->event_notify_fn &&
- !(p_ctx->segment_info.size % p_ctx->notification_size)) {
+ !(p_ctx->segment_info.size % p_ctx->notification_size) &&
+ p_ctx->segment_info.duration > 0) {
memset(&record_status, 0, sizeof(record_status));
- clock_gettime(CLOCK_MONOTONIC, &end_ts);
+ //clock_gettime(CLOCK_MONOTONIC, &end_ts);
record_status.state = p_ctx->state;
record_status.info.id = p_ctx->segment_info.id;
- record_status.info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
- (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000);
+ record_status.info.duration = p_ctx->segment_info.duration;
record_status.info.size = p_ctx->segment_info.size;
record_status.info.nb_packets = p_ctx->segment_info.size/188;
p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
@@ -88,11 +221,6 @@
}
}
- clock_gettime(CLOCK_MONOTONIC, &end_ts);
- /*Duration need use pcr to calculate, todo...*/
- p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
- (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000);
- p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
free((void *)buf);
DVR_DEBUG(1, "exit %s", __func__);
return NULL;
@@ -130,13 +258,20 @@
#endif
memset((void *)&dev_open_params, 0, sizeof(dev_open_params));
- dev_open_params.dmx_dev_id = params->dmx_dev_id;
- dev_open_params.buf_size = 256*1024;
+ if (params->data_from_memory) {
+ /* data from memory, VOD case */
+ p_ctx->is_vod = 1;
+ } else {
+ p_ctx->is_vod = 0;
+ /* data from dmx, normal dvr case */
+ dev_open_params.dmx_dev_id = params->dmx_dev_id;
+ dev_open_params.buf_size = 256*1024;
- ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
- if (ret != DVR_SUCCESS) {
- DVR_DEBUG(1, "%s, open record devices failed", __func__);
- return DVR_FAILURE;
+ ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
+ if (ret != DVR_SUCCESS) {
+ DVR_DEBUG(1, "%s, open record devices failed", __func__);
+ return DVR_FAILURE;
+ }
}
p_ctx->state = DVR_RECORD_STATE_OPENED;
@@ -161,9 +296,13 @@
DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
- ret = record_device_close(p_ctx->dev_handle);
- if (ret != DVR_SUCCESS) {
- DVR_DEBUG(1, "%s, failed", __func__);
+ if (p_ctx->is_vod) {
+ ret = DVR_SUCCESS;
+ } else {
+ ret = record_device_close(p_ctx->dev_handle);
+ if (ret != DVR_SUCCESS) {
+ DVR_DEBUG(1, "%s, failed", __func__);
+ }
}
p_ctx->state = DVR_RECORD_STATE_CLOSED;
@@ -220,15 +359,19 @@
memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
}
- for (i = 0; i < params->segment.nb_pids; i++) {
- ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
+ if (!p_ctx->is_vod) {
+ /* normal dvr case */
+ for (i = 0; i < params->segment.nb_pids; i++) {
+ ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
+ DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
+ }
+ ret = record_device_start(p_ctx->dev_handle);
DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
}
- ret = record_device_start(p_ctx->dev_handle);
- DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
p_ctx->state = DVR_RECORD_STATE_STARTED;
- pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
+ if (!p_ctx->is_vod)
+ pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
return DVR_SUCCESS;
}
@@ -252,6 +395,7 @@
//DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
DVR_RETURN_IF_FALSE(params);
DVR_RETURN_IF_FALSE(p_info);
+ DVR_RETURN_IF_FALSE(!p_ctx->is_vod);
/*Stop the on going record segment*/
//ret = record_device_stop(p_ctx->dev_handle);
@@ -340,11 +484,17 @@
DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
DVR_RETURN_IF_FALSE(p_info);
- ret = record_device_stop(p_ctx->dev_handle);
- DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
-
p_ctx->state = DVR_RECORD_STATE_STOPPED;
- pthread_join(p_ctx->thread, NULL);
+ if (p_ctx->is_vod) {
+ p_ctx->segment_info.duration = segment_tell_time(p_ctx->segment_handle);
+ p_ctx->segment_info.duration = 10*1000; //debug, should delete it
+ } else {
+ ret = record_device_stop(p_ctx->dev_handle);
+ DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
+ //p_ctx->state = DVR_RECORD_STATE_STOPPED;
+ pthread_join(p_ctx->thread, NULL);
+ }
+
/*Update segment info*/
memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
@@ -364,6 +514,7 @@
{
DVR_RecordContext_t *p_ctx;
uint32_t i;
+ int ret;
p_ctx = (DVR_RecordContext_t *)handle;
for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
@@ -374,6 +525,64 @@
DVR_RETURN_IF_FALSE(params);
DVR_RETURN_IF_FALSE(p_resume_size);
- DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
+ DVR_DEBUG(1, "%s , current state:%d, resume size:%lld", __func__, p_ctx->state, *p_resume_size);
+ ret = dvr_record_start_segment(handle, params);
+ DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
+
+ p_ctx->segment_info.size = *p_resume_size;
+
+ return DVR_SUCCESS;
+}
+
+int dvr_record_get_status(DVR_RecordHandle_t handle, DVR_RecordStatus_t *p_status)
+{
+ DVR_RecordContext_t *p_ctx;
+ int i;
+
+ p_ctx = (DVR_RecordContext_t *)handle;
+ for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
+ if (p_ctx == &record_ctx[i])
+ break;
+ }
+ DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
+ DVR_RETURN_IF_FALSE(p_status);
+
+ //lock
+ p_status->state = p_ctx->state;
+ p_status->info.id = p_ctx->segment_info.id;
+ p_status->info.duration = p_ctx->segment_info.duration;
+ p_status->info.size = p_ctx->segment_info.size;
+ p_status->info.nb_packets = p_ctx->segment_info.size/188;
+
+ return DVR_SUCCESS;
+}
+
+int dvr_record_write(DVR_RecordHandle_t handle, void *buffer, uint32_t len)
+{
+ DVR_RecordContext_t *p_ctx;
+ uint32_t i;
+ off_t pos = 0;
+ int ret;
+ int has_pcr;
+
+ p_ctx = (DVR_RecordContext_t *)handle;
+ for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
+ if (p_ctx == &record_ctx[i])
+ break;
+ }
+ DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
+ DVR_RETURN_IF_FALSE(buffer);
+ DVR_RETURN_IF_FALSE(len);
+
+ pos = segment_tell_position(p_ctx->segment_handle);
+ has_pcr = record_do_pcr_index(p_ctx, buffer, len);
+ if (has_pcr == 0) {
+ /* Pull VOD record shoud use PCR time index */
+ DVR_DEBUG(1, "%s has no pcr, can NOT do time index", __func__);
+ }
+ ret = segment_write(p_ctx->segment_handle, buffer, len);
+ p_ctx->segment_info.size += len;
+ p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
+
return DVR_SUCCESS;
}
diff --git a/src/record_device.c b/src/record_device.c
index b5f33e1..c9af2b7 100644
--- a/src/record_device.c
+++ b/src/record_device.c
@@ -125,9 +125,9 @@
break;
}
DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
- DVR_RETURN_IF_FALSE(p_ctx->state != RECORD_DEVICE_STATE_CLOSED);
pthread_mutex_lock(&p_ctx->lock);
+ DVR_RETURN_IF_FALSE_WITH_UNLOCK(p_ctx->state != RECORD_DEVICE_STATE_CLOSED, &p_ctx->lock);
close(p_ctx->fd);
p_ctx->state = RECORD_DEVICE_STATE_CLOSED;
pthread_mutex_unlock(&p_ctx->lock);
@@ -145,22 +145,21 @@
p_ctx = (Record_DeviceContext_t *)handle;
DVR_RETURN_IF_FALSE(p_ctx);
+ DVR_RETURN_IF_FALSE(pid != DVR_INVALID_PID);
for (i = 0; i < MAX_RECORD_DEVICE_COUNT; i++) {
if (p_ctx == &record_ctx[i])
break;
}
DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
- DVR_RETURN_IF_FALSE(p_ctx->state != RECORD_DEVICE_STATE_CLOSED);
- DVR_RETURN_IF_FALSE(pid != DVR_INVALID_PID);
-
+ pthread_mutex_lock(&p_ctx->lock);
+ DVR_RETURN_IF_FALSE_WITH_UNLOCK(p_ctx->state != RECORD_DEVICE_STATE_CLOSED, &p_ctx->lock);
for (i = 0; i < DVR_MAX_RECORD_PIDS_COUNT; i++) {
if (p_ctx->streams[i].pid == DVR_INVALID_PID)
break;
}
- DVR_RETURN_IF_FALSE(p_ctx->streams[i].pid == DVR_INVALID_PID);
+ DVR_RETURN_IF_FALSE_WITH_UNLOCK(p_ctx->streams[i].pid == DVR_INVALID_PID, &p_ctx->lock);
- pthread_mutex_lock(&p_ctx->lock);
p_ctx->streams[i].pid = pid;
snprintf(dev_name, sizeof(dev_name), "/dev/dvb0.demux%d", p_ctx->dmx_dev_id);
fd = open(dev_name, O_RDWR);
@@ -205,24 +204,23 @@
p_ctx = (Record_DeviceContext_t *)handle;
DVR_RETURN_IF_FALSE(p_ctx);
+ DVR_RETURN_IF_FALSE(pid != DVR_INVALID_PID);
for (i = 0; i < MAX_RECORD_DEVICE_COUNT; i++) {
if (p_ctx == &record_ctx[i])
break;
}
DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
- DVR_RETURN_IF_FALSE(p_ctx->state != RECORD_DEVICE_STATE_CLOSED);
- DVR_RETURN_IF_FALSE(pid != DVR_INVALID_PID);
-
+ pthread_mutex_lock(&p_ctx->lock);
+ DVR_RETURN_IF_FALSE_WITH_UNLOCK(p_ctx->state != RECORD_DEVICE_STATE_CLOSED, &p_ctx->lock);
for (i = 0; i < DVR_MAX_RECORD_PIDS_COUNT; i++) {
if (p_ctx->streams[i].pid == pid)
break;
}
- DVR_RETURN_IF_FALSE(p_ctx->streams[i].pid == pid);
+ DVR_RETURN_IF_FALSE_WITH_UNLOCK(p_ctx->streams[i].pid == pid, &p_ctx->lock);
- pthread_mutex_lock(&p_ctx->lock);
fd = p_ctx->streams[i].fid;
- DVR_RETURN_IF_FALSE(fd != -1);
+ DVR_RETURN_IF_FALSE_WITH_UNLOCK(fd != -1, &p_ctx->lock);
if (p_ctx->streams[i].is_start == DVR_TRUE) {
ret = ioctl(fd, DMX_STOP, 0);
@@ -257,13 +255,14 @@
}
DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
+ pthread_mutex_lock(&p_ctx->lock);
if (p_ctx->state != RECORD_DEVICE_STATE_OPENED &&
p_ctx->state != RECORD_DEVICE_STATE_STOPPED) {
+ pthread_mutex_unlock(&p_ctx->lock);
DVR_DEBUG(1, "%s, %d, wrong state:%d", __func__, __LINE__,p_ctx->state);
return DVR_FAILURE;
}
- pthread_mutex_lock(&p_ctx->lock);
for (i = 0; i < DVR_MAX_RECORD_PIDS_COUNT; i++) {
if (p_ctx->streams[i].fid != -1 &&
p_ctx->streams[i].pid != DVR_INVALID_PID &&
@@ -310,12 +309,13 @@
}
DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
+ pthread_mutex_lock(&p_ctx->lock);
if (p_ctx->state != RECORD_DEVICE_STATE_STARTED) {
DVR_DEBUG(1, "%s, %d, wrong state:%d", __func__, __LINE__,p_ctx->state);
+ pthread_mutex_unlock(&p_ctx->lock);
return DVR_FAILURE;
}
- pthread_mutex_lock(&p_ctx->lock);
for (i = 0; i < DVR_MAX_RECORD_PIDS_COUNT; i++) {
if (p_ctx->streams[i].fid != -1 &&
p_ctx->streams[i].pid != DVR_INVALID_PID &&
diff --git a/src/segment.c b/src/segment.c
index 8503472..9bf4c12 100644
--- a/src/segment.c
+++ b/src/segment.c
@@ -19,6 +19,7 @@
FILE *dat_fp; /**< Information file fd*/
uint64_t first_pts; /**< First pts value, use for write mode*/
uint64_t last_pts; /**< Last pts value, use for write mode*/
+ uint64_t cur_time; /**< Current time save in index file */
} Segment_Context_t;
/**\brief Segment file type*/
@@ -187,20 +188,24 @@
DVR_RETURN_IF_FALSE(p_ctx->index_fp);
if (p_ctx->first_pts == ULLONG_MAX) {
+ DVR_DEBUG(1, "%s first pcr:%llu", __func__, pts);
p_ctx->first_pts = pts;
}
memset(buf, 0, sizeof(buf));
if (p_ctx->last_pts == ULLONG_MAX) {
/*Last pts is init value*/
sprintf(buf, "{time=%llu, offset=%lld}\n", pts - p_ctx->first_pts, offset);
+ p_ctx->cur_time = pts - p_ctx->first_pts;
} else {
/*Last pts has valid value*/
if (pts - p_ctx->last_pts > MAX_PTS_THRESHOLD) {
/*Current pts has a transition*/
- sprintf(buf, "{time=%llu, offset=%lld}\n", p_ctx->last_pts - p_ctx->first_pts, offset);
+ DVR_DEBUG(1, "Current pts has a transition, [%llu, %llu, %llu]",
+ p_ctx->first_pts, p_ctx->last_pts, pts);
} else {
/*This is a normal pts, record it*/
- sprintf(buf, "{time=%llu, offset=%lld}\n", pts - p_ctx->first_pts, offset);
+ p_ctx->cur_time += (pts - p_ctx->last_pts);
+ sprintf(buf, "{time=%llu, offset=%lld}\n", p_ctx->cur_time, offset);
}
}
@@ -309,7 +314,7 @@
}
memset(buf, 0, sizeof(buf));
- DVR_DEBUG(1, "time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
+ //DVR_DEBUG(1, "time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
if (position < offset) {
return pts;
}
@@ -318,6 +323,7 @@
return DVR_FAILURE;
}
+/* Should consider the case of cut power, todo... */
int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
{
Segment_Context_t *p_ctx;
@@ -366,6 +372,7 @@
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;