dvr: adjust file & add note [1/1]
PD#SWPL-18817
Problem:
New feature
Solution:
adjust file arch & add note
Verify:
Android Q + AC214
Change-Id: Ia3313ee6fc7a59f3ef18a020289cca6cacf437f2
Signed-off-by: Pengfei Liu <pengfei.liu@amlogic.com>
diff --git a/src/dvr_crypto.c b/src/dvr_crypto.c
index 9a35b9b..1d7dada 100644
--- a/src/dvr_crypto.c
+++ b/src/dvr_crypto.c
@@ -1,23 +1,25 @@
#include <stdio.h>
#include "dvr_crypto.h"
-int dvr_crypto_device_open(DVR_CryptoDeviceHandle *p_handle)
+int dvr_crypto_device_open(DVR_CryptoDeviceHandle_t *p_handle)
{
return 0;
}
-int dvr_crypto_device_run(DVR_CryptoDeviceHandle handle,
- uint8_t *buf_in, uint8_t *buf_out, DVR_CryptoParams *params)
+int dvr_crypto_device_run(DVR_CryptoDeviceHandle_t handle,
+ uint8_t *buf_in, uint8_t *buf_out, DVR_CryptoParams_t *params)
{
return 0;
}
+#if 0
int dvr_crypto_device_register(DVR_CryptoDeviceHandle handle, DVR_CryptoFunction cb, void *userdata, int is_enc)
{
return 0;
}
+#endif
-int dvr_crypto_device_close(DVR_CryptoDeviceHandle handle)
+int dvr_crypto_device_close(DVR_CryptoDeviceHandle_t handle)
{
return 0;
}
diff --git a/src/dvr_index_file.c b/src/dvr_index_file.c
deleted file mode 100644
index 258eda0..0000000
--- a/src/dvr_index_file.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <stdio.h>
-#include "dvr_index_file.h"
-
-int dvr_index_file_open(DVR_IndexFileHandle *p_handle, DVR_IndexFileOpenParams *p_params)
-{
- return 0;
-}
-
-int dvr_index_file_close(DVR_IndexFileHandle handle)
-{
- return 0;
-}
-
-int dvr_index_file_write(DVR_IndexFileHandle handle, uint64_t pcr, loff_t offset)
-{
- return 0;
-}
-
-loff_t dvr_index_file_lookup_by_time(DVR_IndexFileHandle handle, time_t time)
-{
- return 0;
-}
diff --git a/src/dvr_list_file.c b/src/dvr_list_file.c
deleted file mode 100644
index f3ed2ac..0000000
--- a/src/dvr_list_file.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <stdio.h>
-#include "dvr_list_file.h"
-
-
-int dvr_segment_list_file_store(const char *path, DVR_SegmentListInfo *p_info)
-{
- return 0;
-}
-
-int dvr_segment_list_file_load(const char *path, DVR_SegmentListInfo *info)
-{
- return 0;
-}
diff --git a/src/dvr_record.c b/src/dvr_record.c
new file mode 100644
index 0000000..89db271
--- /dev/null
+++ b/src/dvr_record.c
@@ -0,0 +1,241 @@
+#include <stdio.h>
+#include <pthread.h>
+#include "dvr_common.h"
+#include "dvr_record.h"
+#include "dvr_crypto.h"
+#include "record_device.h"
+#include "segment.h"
+#include "segment_file.h"
+
+#define MAX_DVR_RECORD_SESSION_COUNT 2
+typedef struct {
+ pthread_t thread;
+ Record_DeviceHandle_t dev_handle;
+ Segment_Handle_t segment_handle;
+ DVR_RecordState state;
+ char location[DVR_MAX_LOCATION_SIZE];
+ DVR_RecordSegmentStartParams_t segment_params;
+} DVR_RecordContext_t;
+
+static DVR_RecordContext_t record_ctx[MAX_DVR_RECORD_SESSION_COUNT] = {
+ {
+ .state = DVR_RECORD_STATE_STOPPED
+ },
+ {
+ .state = DVR_RECORD_STATE_STOPPED
+ }
+};
+
+void *record_thread(void *arg)
+{
+ DVR_RecordContext_t *p_ctx = (DVR_RecordContext_t *)arg;
+ ssize_t len;
+ uint8_t *buf;
+ int block_size = 32*1024;
+ off_t pos = 0;
+ uint64_t pts = 0;
+ int ret;
+
+ buf = malloc(block_size);
+ if (!buf) {
+ DVR_DEBUG(1, "%s, malloc failed", __func__);
+ return NULL;
+ }
+
+ while (p_ctx->state == DVR_RECORD_STATE_STARTED) {
+ len = record_device_read(p_ctx->dev_handle, buf, sizeof(buf), 1000);
+#if 0
+ ret = sw_dmx_extract_pcr(buf, len, &pts, &pos);
+ if (ret == DVR_FAILURE) {
+ get_local_pts(&pts);
+ }
+#endif
+ pos += segment_tell(p_ctx->segment_handle);
+ ret = segment_update_pts(p_ctx->segment_handle, pts, pos);
+ ret = segment_write(p_ctx->segment_handle, buf, len);
+ }
+
+ free(buf);
+ return NULL;
+}
+
+int dvr_record_open(DVR_RecordHandle_t *p_handle, DVR_RecordOpenParams_t *params)
+{
+ DVR_RecordContext_t *p_ctx;
+ Record_DeviceOpenParams_t dev_open_params;
+ int ret;
+ int i;
+
+ DVR_ASSERT(p_handle);
+ DVR_ASSERT(params);
+
+ for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
+ if (record_ctx[i].state == DVR_RECORD_STATE_STOPPED) {
+ break;
+ }
+ }
+ DVR_ASSERT(record_ctx[i].state == DVR_RECORD_STATE_STOPPED);
+ p_ctx = &record_ctx[i];
+
+ /*Process params, todo*/
+ {
+ }
+
+ memset(&dev_open_params, 0, sizeof(dev_open_params));
+ /*Process dev_open_params, todo*/
+ {
+ }
+ 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;
+
+ *p_handle = i;
+ return DVR_SUCCESS;
+}
+
+int dvr_record_close(DVR_RecordHandle_t handle)
+{
+ DVR_RecordContext_t *p_ctx;
+ int ret;
+
+ DVR_ASSERT(handle < MAX_DVR_RECORD_SESSION_COUNT);
+ p_ctx = &record_ctx[handle];
+
+ DVR_ASSERT(p_ctx->state != DVR_RECORD_STATE_STOPPED);
+
+ ret = record_device_close(p_ctx->dev_handle);
+ if (ret != DVR_SUCCESS) {
+ DVR_DEBUG(1, "%s, failed", __func__);
+ }
+
+ p_ctx->state = DVR_RECORD_STATE_STOPPED;
+ return ret;
+}
+
+int dvr_record_register_encryption(DVR_RecordHandle_t handle,
+ DVR_CryptoFunction_t cb,
+ DVR_CryptoParams_t params,
+ void *userdata)
+{
+ return DVR_SUCCESS;
+}
+
+int dvr_record_start_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params)
+{
+ DVR_RecordContext_t *p_ctx;
+ Segment_OpenParams_t open_params;
+ int ret;
+ int i;
+
+ DVR_ASSERT(handle < MAX_DVR_RECORD_SESSION_COUNT);
+ p_ctx = &record_ctx[handle];
+
+ DVR_ASSERT(p_ctx->state != DVR_RECORD_STATE_STARTED);
+ DVR_ASSERT(params);
+
+ DVR_ASSERT(strlen(params->location) < DVR_MAX_LOCATION_SIZE);
+ memset(&open_params, 0, sizeof(open_params));
+ memcpy(open_params.location, params->location, strlen(params->location));
+ open_params.segment_id = params->segment.segment_id;
+ open_params.mode = SEGMENT_MODE_WRITE;
+
+ ret = segment_open(&open_params, &p_ctx->segment_handle);
+ DVR_ASSERT(ret == DVR_SUCCESS);
+
+ /*process params, todo*/
+ {
+ memcpy(p_ctx->location, params->location, strlen(params->location));
+ memcpy(&p_ctx->segment_params, ¶ms->segment, sizeof(params->segment));
+ }
+
+ for (i = 0; i < params->segment.nb_pids; i++) {
+ ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
+ DVR_ASSERT(ret);
+ }
+
+ ret = record_device_start(p_ctx->dev_handle);
+ DVR_ASSERT(ret);
+
+ pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
+ p_ctx->state = DVR_RECORD_STATE_STARTED;
+ return DVR_SUCCESS;
+}
+
+int dvr_record_next_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, DVR_RecordSegmentInfo_t *p_info)
+{
+ DVR_RecordContext_t *p_ctx;
+ int ret;
+ int i;
+
+ DVR_ASSERT(handle < MAX_DVR_RECORD_SESSION_COUNT);
+ p_ctx = &record_ctx[handle];
+
+ DVR_ASSERT(p_ctx->state != DVR_RECORD_STATE_STARTED);
+ DVR_ASSERT(params);
+ DVR_ASSERT(p_info);
+
+ /*Stop the on going record segment*/
+ ret = record_device_stop(p_ctx->dev_handle);
+ DVR_ASSERT(ret == DVR_SUCCESS);
+
+ p_ctx->state = DVR_RECORD_STATE_STOPPED;
+ pthread_join(p_ctx->thread, NULL);
+
+ ret = segment_file_store(p_ctx->location, p_ctx->segment_params.segment_id, p_info);
+ DVR_ASSERT(ret == DVR_SUCCESS);
+
+ /*Update segment info, todo*/
+ {
+ }
+
+ /*Start the new record segment*/
+ /*process params, todo*/
+ {
+ memcpy(&p_ctx->segment_params, ¶ms->segment, sizeof(params->segment));
+ }
+
+ for (i = 0; i < params->segment.nb_pids; i++) {
+ ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
+ DVR_ASSERT(ret);
+ }
+
+ ret = record_device_start(p_ctx->dev_handle);
+ DVR_ASSERT(ret);
+
+ pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
+ p_ctx->state = DVR_RECORD_STATE_STARTED;
+ return DVR_SUCCESS;
+}
+
+int dvr_record_stop_segment(DVR_RecordHandle_t handle, DVR_RecordSegmentInfo_t *p_info)
+{
+ DVR_RecordContext_t *p_ctx;
+ int ret;
+
+ DVR_ASSERT(handle < MAX_DVR_RECORD_SESSION_COUNT);
+ p_ctx = &record_ctx[handle];
+
+ DVR_ASSERT(p_ctx->state != DVR_RECORD_STATE_STOPPED);
+ DVR_ASSERT(p_info);
+
+ ret = record_device_stop(p_ctx->dev_handle);
+ DVR_ASSERT(ret == DVR_SUCCESS);
+
+ p_ctx->state = DVR_RECORD_STATE_STOPPED;
+ pthread_join(p_ctx->thread, NULL);
+
+ ret = segment_close(p_ctx->segment_handle);
+ DVR_ASSERT(ret == DVR_SUCCESS);
+
+ /*Update segment info, todo*/
+ {
+ }
+ ret = segment_file_store(p_ctx->location, p_ctx->segment_params.segment_id, p_info);
+ DVR_ASSERT(ret == DVR_SUCCESS);
+
+ return DVR_SUCCESS;
+}
diff --git a/src/dvr_segment.c b/src/dvr_segment.c
new file mode 100644
index 0000000..16135ce
--- /dev/null
+++ b/src/dvr_segment.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include "dvr_segment.h"
+
+int dvr_segment_delete(const char *location, uint64_t segment_id)
+{
+ return 0;
+}
+
+int dvr_segment_get_list(const char *location, uint32_t *p_segment_nb, uint64_t **pp_segment_ids)
+{
+ return 0;
+}
+
+int dvr_segment_get_info(const char *location, uint64_t segment_id, DVR_SegmentInfo *p_info)
+{
+ return 0;
+}
+
+int dvr_segment_link(const char *location, uint32_t nb_segments, uint64_t *p_segment_ids)
+{
+ return 0;
+}
diff --git a/src/dvr_segment_file.c b/src/dvr_segment_file.c
deleted file mode 100644
index 2dc44a2..0000000
--- a/src/dvr_segment_file.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <stdio.h>
-#include "dvr_segment_file.h"
-
-
-int dvr_segment_file_store(const char *location, uint64_t segment_id, DVR_SegmentStoreInfo *p_info)
-{
- return 0;
-}
-
-int dvr_segment_file_load(const char *location, uint64_t segment_id, DVR_SegmentStoreInfo *p_info)
-{
- return 0;
-}
-
-int dvr_segment_file_del(const char *location, uint64_t segment_id)
-{
- return 0;
-}
-
diff --git a/src/index_file.c b/src/index_file.c
new file mode 100644
index 0000000..f08d75b
--- /dev/null
+++ b/src/index_file.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include "index_file.h"
+
+int index_file_open(Index_FileHandle_t *p_handle, Index_FileOpenParams_t *p_params)
+{
+ return 0;
+}
+
+int index_file_close(Index_FileHandle_t handle)
+{
+ return 0;
+}
+
+int index_file_write(Index_FileHandle_t handle, uint64_t pcr, loff_t offset)
+{
+ return 0;
+}
+
+loff_t index_file_lookup_by_time(Index_FileHandle_t handle, time_t time)
+{
+ return 0;
+}
diff --git a/src/list_file.c b/src/list_file.c
new file mode 100644
index 0000000..97dd42f
--- /dev/null
+++ b/src/list_file.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "list_file.h"
+
+
+int segment_list_file_store(const char *path, Segment_ListInfo *p_info)
+{
+ return 0;
+}
+
+int segment_list_file_load(const char *path, Segment_ListInfo *info)
+{
+ return 0;
+}
diff --git a/src/record_device.c b/src/record_device.c
index 9759721..5187071 100644
--- a/src/record_device.c
+++ b/src/record_device.c
@@ -1,37 +1,37 @@
#include <stdio.h>
#include "record_device.h"
-int record_device_open(Record_DeviceHandle *p_handle, Record_DeviceOpenParams *params)
+int record_device_open(Record_DeviceHandle_t *p_handle, Record_DeviceOpenParams_t *params)
{
return 0;
}
-int record_device_close(Record_DeviceHandle handle)
+int record_device_close(Record_DeviceHandle_t handle)
{
return 0;
}
-int record_device_add_pid(Record_DeviceHandle handle, int pid)
+int record_device_add_pid(Record_DeviceHandle_t handle, int pid)
{
return 0;
}
-int record_device_remove_pid(Record_DeviceHandle handle, int pid)
+int record_device_remove_pid(Record_DeviceHandle_t handle, int pid)
{
return 0;
}
-int record_device_start(Record_DeviceHandle handle)
+int record_device_start(Record_DeviceHandle_t handle)
{
return 0;
}
-int record_device_stop(Record_DeviceHandle handle)
+int record_device_stop(Record_DeviceHandle_t handle)
{
return 0;
}
-ssize_t record_device_read(Record_DeviceHandle handle, void *buf, size_t len, int timeout)
+ssize_t record_device_read(Record_DeviceHandle_t handle, void *buf, size_t len, int timeout)
{
return 0;
}
diff --git a/src/segment.c b/src/segment.c
new file mode 100644
index 0000000..a31c5dc
--- /dev/null
+++ b/src/segment.c
@@ -0,0 +1,202 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include "dvr_common.h"
+#include "segment.h"
+
+#define MAX_SEGMENT_FD_COUNT (128)
+#define MAX_SEGMENT_PATH_SIZE (DVR_MAX_LOCATION_SIZE + 32)
+typedef struct {
+ //char location[DVR_MAX_LOCATION_SIZE];
+ //uint64_t segment_id;
+ FILE *ts_fp; /**< segment ts file fd*/
+ FILE *index_fp; /**< time index file fd*/
+} Segment_Context_t;
+
+typedef enum {
+ SEGMENT_FILE_TYPE_TS,
+ SEGMENT_FILE_TYPE_INDEX,
+} Segment_FileType_t;
+
+static void segment_get_fname(char fname[MAX_SEGMENT_PATH_SIZE],
+ char location[DVR_MAX_LOCATION_SIZE],
+ uint64_t segment_id,
+ Segment_FileType_t type)
+{
+ int offset;
+
+ 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_TS)
+ strncpy(fname + offset, ".ts", 3);
+ else if (type == SEGMENT_FILE_TYPE_INDEX)
+ strncpy(fname + offset, ".idx", 4);
+}
+
+int segment_open(Segment_OpenParams_t *params, Segment_Handle_t *p_handle)
+{
+ Segment_Context_t *p_ctx;
+ char ts_fname[MAX_SEGMENT_PATH_SIZE];
+ char index_fname[MAX_SEGMENT_PATH_SIZE];
+
+ DVR_ASSERT(params);
+ DVR_ASSERT(p_handle);
+
+ DVR_DEBUG(1, "%s, location:%s, id:%d", __func__, params->location, params->segment_id);
+
+ p_ctx = malloc(sizeof(Segment_Context_t));
+ DVR_ASSERT(p_ctx);
+
+ memset(ts_fname, 0, sizeof(ts_fname));
+ segment_get_fname(ts_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_TS);
+
+ memset(index_fname, 0, sizeof(index_fname));
+ segment_get_fname(index_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_INDEX);
+
+ if (params->mode == SEGMENT_MODE_READ) {
+ p_ctx->ts_fp = fopen(ts_fname, "r");
+ p_ctx->index_fp = fopen(index_fname, "r");
+ } else if (params->mode == SEGMENT_MODE_WRITE) {
+ p_ctx->ts_fp = fopen(ts_fname, "w+");
+ p_ctx->index_fp = fopen(index_fname, "w+");
+ } else {
+ DVR_DEBUG(1, "%s, unknow mode use default", __func__);
+ p_ctx->ts_fp = fopen(ts_fname, "r");
+ p_ctx->index_fp = fopen(index_fname, "r");
+ }
+
+ if (!p_ctx->ts_fp || !p_ctx->index_fp) {
+ DVR_DEBUG(1, "%s open file failed [%p, %p], reason:%s", __func__,
+ p_ctx->ts_fp, p_ctx->index_fp, strerror(errno));
+ free(p_ctx);
+ p_handle = NULL;
+ return DVR_FAILURE;
+ }
+ p_handle = p_ctx;
+ return DVR_SUCCESS;
+}
+
+int segment_close(Segment_Handle_t handle)
+{
+ Segment_Context_t *p_ctx;
+
+ p_ctx = (Segment_Context_t *)handle;
+ DVR_ASSERT(p_ctx);
+
+ if (p_ctx->ts_fp) {
+ fclose(p_ctx->ts_fp);
+ }
+
+ if (p_ctx->index_fp) {
+ fclose(p_ctx->index_fp);
+ }
+
+ free(p_ctx);
+ return 0;
+}
+
+ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
+{
+ Segment_Context_t *p_ctx;
+
+ p_ctx = (Segment_Context_t *)handle;
+ DVR_ASSERT(p_ctx);
+ DVR_ASSERT(buf);
+ DVR_ASSERT(p_ctx->ts_fp);
+
+ return fread(p_ctx->ts_fp, 1, count, buf);
+}
+
+ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
+{
+ Segment_Context_t *p_ctx;
+
+ p_ctx = (Segment_Context_t *)handle;
+ DVR_ASSERT(p_ctx);
+ DVR_ASSERT(buf);
+ DVR_ASSERT(p_ctx->ts_fp);
+
+ return fwrite(p_ctx->ts_fp, 1, count, buf);
+}
+
+int segment_update_pts(Segment_Handle_t handle, uint64_t pts, off_t offset)
+{
+ Segment_Context_t *p_ctx;
+ char buf[256];
+
+ p_ctx = (Segment_Context_t *)handle;
+ DVR_ASSERT(p_ctx);
+ DVR_ASSERT(p_ctx->index_fp);
+
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, "{pts=%llu, offset=%llu}\n", pts, offset);
+
+ fputs(buf, p_ctx->index_fp);
+ return DVR_SUCCESS;
+}
+
+off_t segment_seek(Segment_Handle_t handle, uint64_t time)
+{
+ Segment_Context_t *p_ctx;
+ char buf[256];
+ char value[256];
+ uint64_t pts;
+ off_t offset;
+ char *p1, *p2;
+
+ p_ctx = (Segment_Context_t *)handle;
+ DVR_ASSERT(p_ctx);
+ DVR_ASSERT(p_ctx->index_fp);
+ DVR_ASSERT(p_ctx->ts_fp);
+
+ memset(buf, 0, sizeof(buf));
+ DVR_ASSERT(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
+
+ while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
+ memset(value, 0, sizeof(value));
+ if ((p1 = strstr(buf, "pts="))) {
+ p1 += 4;
+ if ((p2 = strstr(buf, ","))) {
+ memcpy(value, p1, p2 - p1);
+ }
+ pts = strtoull(value, NULL, 10);
+ }
+
+ memset(value, 0, sizeof(value));
+ if ((p1 = strstr(buf, "offset="))) {
+ p1 += 7;
+ if ((p2 = strstr(buf, "}"))) {
+ memcpy(value, p1, p2 - p1);
+ }
+ offset = strtoull(value, NULL, 10);
+ }
+
+ memset(buf, 0, sizeof(buf));
+ DVR_DEBUG(1, "pts=%llu, offset=%ld\n", pts, offset);
+ if (time < pts) {
+ DVR_ASSERT(fseeko(p_ctx->ts_fp, offset, SEEK_SET) != -1);
+ return offset;
+ }
+ }
+
+ return DVR_FAILURE;
+}
+
+off_t segment_tell(Segment_Handle_t handle)
+{
+ Segment_Context_t *p_ctx;
+
+ p_ctx = (Segment_Context_t *)handle;
+ DVR_ASSERT(p_ctx);
+ DVR_ASSERT(p_ctx->ts_fp);
+
+ return ftello(p_ctx->ts_fp);
+}
diff --git a/src/segment_file.c b/src/segment_file.c
new file mode 100644
index 0000000..e834248
--- /dev/null
+++ b/src/segment_file.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include "segment_file.h"
+
+
+int segment_file_store(const char *location, uint64_t segment_id, Segment_StoreInfo_t *p_info)
+{
+ return 0;
+}
+
+int segment_file_load(const char *location, uint64_t segment_id, Segment_StoreInfo_t *p_info)
+{
+ return 0;
+}
+
+int segment_file_del(const char *location, uint64_t segment_id)
+{
+ return 0;
+}
+