ts_indexer_test: combine index events and data for CAS. [1/1]
PD#OTT-49881
Problem:
tuner hal needs combines index events and data.
Solution:
ts indexer testapp supports it for tuner hal references.
Verify:
PC
Change-Id: I5da9e74b87228e82edb8a28396638d9d4a0dc3c4
Signed-off-by: Yahui Han <yahui.han@amlogic.com>
diff --git a/test/ts_indexer_test/ts_indexer_test.c b/test/ts_indexer_test/ts_indexer_test.c
index 8185c30..67bea94 100644
--- a/test/ts_indexer_test/ts_indexer_test.c
+++ b/test/ts_indexer_test/ts_indexer_test.c
@@ -33,26 +33,88 @@
#define INF(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)
#define ERR(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
+enum {
+ INDEX_PUSI = 0x01,
+ INDEX_IFRAME = 0x02,
+ INDEX_PTS = 0x04
+};
+
+#define has_pusi(_m_) ((_m_) & INDEX_PUSI)
+#define has_iframe(_m_) ((_m_) & INDEX_IFRAME)
+#define has_pts(_m_) ((_m_) & INDEX_PTS)
+#define MAX_CACHE_SIZE (2*1024*1024)
+
typedef struct
{
- uint8_t *ptr;
+ uint8_t *base_ptr;
+ uint8_t *last_pusi_ptr;
+ uint64_t last_pusi_offset;
+ uint64_t cnt;
uint64_t last_pts;
- uint64_t last_offset;
+ uint32_t flags;
+ uint8_t *cache_data;
+ uint64_t cache_len;
FILE *dump_file;
} ts_indexer_ctl;
static ts_indexer_ctl gControl;
+int send_data()
+{
+ ts_indexer_ctl *ctl = &gControl;
+
+ if (!has_pusi(ctl->flags)) {
+ ERR("no PUSI, should not send\n");
+ return -1;
+ }
+ //send the cache data
+ if (ctl->dump_file) {
+ INF("send %#lx bytes, PUSI: %d, IFRAME: %d, PTS: %d\n",
+ ctl->cache_len,
+ has_pusi(ctl->flags),
+ has_iframe(ctl->flags),
+ has_pts(ctl->flags));
+ fwrite(&ctl->cache_data[0], 1, ctl->cache_len, ctl->dump_file);
+ }
+
+ return 0;
+}
+
static void ts_indexer_event_cb(TS_Indexer_t *ts_indexer, TS_Indexer_Event_t *event)
{
- int write_len;
+ static int cnt = 0;
+ int margin_len;
+ ts_indexer_ctl *ctl = &gControl;
if (ts_indexer == NULL || event == NULL)
return;
+ if (!has_iframe(ctl->flags) &&
+ !has_pts(ctl->flags) &&
+ !has_pusi(ctl->flags) &&
+ event->type != TS_INDEXER_EVENT_TYPE_START_INDICATOR) {
+ INF("wait the PUSI come %d...\n", event->type);
+ return;
+ }
+
+ if (ctl->last_pusi_offset <= 0) {
+ if (event->type == TS_INDEXER_EVENT_TYPE_START_INDICATOR) {
+ ctl->last_pusi_offset = ts_indexer->offset;
+ ctl->last_pusi_ptr = ctl->base_ptr + (ts_indexer->offset - ctl->cnt);
+ INF("PUSI %d\n", cnt++);
+ return;
+ } else {
+ ERR("unexpected event: %d\n", event->type);
+ return;
+ }
+ }
+
switch (event->type) {
case TS_INDEXER_EVENT_TYPE_MPEG2_I_FRAME:
- #if 1
+ case TS_INDEXER_EVENT_TYPE_AVC_I_SLICE:
+ case TS_INDEXER_EVENT_TYPE_HEVC_IDR_W_RADL:
+ ctl->flags |= INDEX_IFRAME;
+ #if 0
INF("pid: %#x ", event->pid);
INF("TS_INDEXER_EVENT_TYPE_I_FRAME, offset: %lx, pts: %lx\n",
event->offset, event->pts);
@@ -60,33 +122,46 @@
break;
case TS_INDEXER_EVENT_TYPE_VIDEO_PTS:
- #if 1
+ ctl->flags |= INDEX_PTS;
+ #if 0
INF("PID: %#x ", event->pid);
INF("TS_INDEXER_EVENT_TYPE_VIDEO_PTS, Offset: %lx, Lastoffset: %lx, Pts: %lx\n",
event->offset, gControl.last_offset, event->pts);
- write_len = ts_indexer->offset - gControl.last_offset;
- if (gControl.dump_file) {
- fwrite(gControl.ptr, 1, write_len, gControl.dump_file);
- gControl.ptr += write_len;
- }
gControl.last_offset = ts_indexer->offset;
#endif
break;
case TS_INDEXER_EVENT_TYPE_AUDIO_PTS:
- #if 0
- INF("PID: %#x ", event->pid);
- INF("TS_INDEXER_EVENT_TYPE_AUDIO_PTS, Offset: %lx, Pts: %lx\n",
- event->offset, event->pts);
- #endif
break;
- //case TS_INDEXER_EVENT_TYPE_START_INDICATOR:
- //case TS_INDEXER_EVENT_TYPE_DISCONTINUITY_INDICATOR:
+ case TS_INDEXER_EVENT_TYPE_START_INDICATOR:
+ /*
+ * it does means this is the first PUSI on current block if there're
+ * cache data
+ */
+ if (ctl->cache_len > 0) {
+ // the length from block head to the pusi position
+ margin_len = ts_indexer->offset - ctl->cnt;
+ memcpy(&ctl->cache_data[ctl->cache_len], ctl->base_ptr, margin_len);
+ ctl->cache_len += margin_len;
+ ctl->last_pusi_ptr = ctl->base_ptr + margin_len;
+ } else {
+ // the length between the last PUSI and current PUSI
+ margin_len = ts_indexer->offset - ctl->last_pusi_offset;
+ memcpy(&ctl->cache_data[0], ctl->last_pusi_ptr, margin_len);
+ ctl->cache_len = margin_len;
+ ctl->last_pusi_ptr += margin_len;
+ }
+
+ send_data();
+ ctl->flags = INDEX_PUSI;
+ ctl->last_pusi_offset = ts_indexer->offset;
+ ctl->cache_len = 0;
+ break;
+ case TS_INDEXER_EVENT_TYPE_DISCONTINUITY_INDICATOR:
case TS_INDEXER_EVENT_TYPE_MPEG2_P_FRAME:
case TS_INDEXER_EVENT_TYPE_MPEG2_B_FRAME:
case TS_INDEXER_EVENT_TYPE_MPEG2_SEQUENCE:
- case TS_INDEXER_EVENT_TYPE_AVC_I_SLICE:
case TS_INDEXER_EVENT_TYPE_AVC_P_SLICE:
case TS_INDEXER_EVENT_TYPE_AVC_B_SLICE:
case TS_INDEXER_EVENT_TYPE_AVC_SI_SLICE:
@@ -95,10 +170,9 @@
case TS_INDEXER_EVENT_TYPE_HEVC_AUD:
case TS_INDEXER_EVENT_TYPE_HEVC_BLA_W_LP:
case TS_INDEXER_EVENT_TYPE_HEVC_BLA_W_RADL:
- case TS_INDEXER_EVENT_TYPE_HEVC_IDR_W_RADL:
case TS_INDEXER_EVENT_TYPE_HEVC_IDR_N_LP:
case TS_INDEXER_EVENT_TYPE_HEVC_TRAIL_CRA:
- INF("type: %d, offset: %#lx\n", event->type, event->offset);
+ //INF("type: %d, offset: %lx\n", event->type, event->offset);
break;
default:
@@ -128,6 +202,7 @@
int vfmt = -1;
TS_Indexer_t ts_indexer;
int block_size = 188*1024;
+ ts_indexer_ctl *ctl = &gControl;
memset(&file[0], 0, sizeof(file));
for (i = 1; i < argc; i++) {
@@ -173,31 +248,52 @@
size_t len = 0;
INF("vpid: %#x, vfmt: %d, apid:%#x\n", vpid, vfmt, apid);
- memset(&gControl, 0, sizeof(ts_indexer_ctl));
- gControl.last_pts = -1;
- gControl.last_offset = 0;
- gControl.dump_file = fopen("./dump.ts", "wb+");
- if (gControl.dump_file == NULL) {
+ memset(ctl, 0, sizeof(ts_indexer_ctl));
+ ctl->last_pts = -1;
+ ctl->last_pusi_offset = 0;
+ ctl->cache_data = malloc(MAX_CACHE_SIZE);
+ if (ctl->cache_data == NULL) {
+ ERR("malloc cache failed\n");
+ return -1;
+ }
+ ctl->dump_file = fopen("./dump.ts", "wb+");
+ if (ctl->dump_file == NULL) {
ERR("open dump file failed\n");
return -1;
}
- INF("ptr: %p ~ %p\n", &data[0], &data[0] + block_size);
while (1) {
len = fread(data, 1, block_size, f);
if (len <= 0)
break;
- gControl.ptr = &data[0];
+ ctl->base_ptr = &data[0];
ts_indexer_parse(&ts_indexer, data, len);
- if (gControl.ptr - &data[0] < len) {
- int left = len - (gControl.ptr - &data[0]);
- fwrite(gControl.ptr, 1, left, gControl.dump_file);
- gControl.last_offset += left;
+
+ int offset = ctl->cache_len;
+ /*
+ * cache the data from PUSI position to the end of the block if current
+ * block has PUSI.
+ * cache the whole block data if current block has no PUSI.
+ */
+
+ if (ctl->cache_len == 0 && ctl->last_pusi_ptr) {
+ int pusi_to_end_len = ((ctl->base_ptr + len) - ctl->last_pusi_ptr);
+ if (pusi_to_end_len > 0)
+ memcpy(&ctl->cache_data[offset], ctl->last_pusi_ptr, pusi_to_end_len);
+ ctl->cache_len += pusi_to_end_len;
+ } else {
+ memcpy(&ctl->cache_data[offset], ctl->base_ptr, len);
+ ctl->cache_len += len;
}
+ ctl->cnt += len;
+ ctl->last_pusi_ptr = NULL;
}
- fflush(gControl.dump_file);
- fclose(gControl.dump_file);
+ if (ctl->cache_data) {
+ free(ctl->cache_data);
+ }
+ fflush(ctl->dump_file);
+ fclose(ctl->dump_file);
return 0;
}