blob: 8185c307840436a98d09ba7463445523d52a6588 [file] [log] [blame]
Gong Kefa504d72023-04-18 10:23:35 +08001/**
2 * \page ts_indexer_test
3 * \section Introduction
4 * test code with ts_indexer_xxxxx APIs.
5 * It supports:
6 * \li parse pts/i-frame from MPEG2/H264/HEVC transport stream
7 *
8 * \section Usage
9 *
10 * \li ts: bitstream file path
11 * \li vpid: the pid of video bitstream with pts/i-frame
12 * \li vfmt: the video format
13 * \li apid: the pid of audio bitstream with pts
14 *
15 *
16 * parse pts/i-frame:
17 * \code
18 * ts_indexer_test [ts=] [vpid=] [vfmt=] [apid=]
19 * \endcode
20 *
21 * \endsection
22 */
23
24#ifdef _FORTIFY_SOURCE
25#undef _FORTIFY_SOURCE
26#endif
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include "ts_indexer.h"
32
33#define INF(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)
34#define ERR(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
35
Yahui Han63de7082023-07-12 18:30:10 +080036typedef struct
37{
38 uint8_t *ptr;
39 uint64_t last_pts;
40 uint64_t last_offset;
41 FILE *dump_file;
42} ts_indexer_ctl;
43
44static ts_indexer_ctl gControl;
45
Gong Kefa504d72023-04-18 10:23:35 +080046static void ts_indexer_event_cb(TS_Indexer_t *ts_indexer, TS_Indexer_Event_t *event)
47{
Yahui Han63de7082023-07-12 18:30:10 +080048 int write_len;
49
Gong Kefa504d72023-04-18 10:23:35 +080050 if (ts_indexer == NULL || event == NULL)
51 return;
52
53 switch (event->type) {
Yahui Han63de7082023-07-12 18:30:10 +080054 case TS_INDEXER_EVENT_TYPE_MPEG2_I_FRAME:
55 #if 1
Gong Kefa504d72023-04-18 10:23:35 +080056 INF("pid: %#x ", event->pid);
Yahui Han63de7082023-07-12 18:30:10 +080057 INF("TS_INDEXER_EVENT_TYPE_I_FRAME, offset: %lx, pts: %lx\n",
Gong Kefa504d72023-04-18 10:23:35 +080058 event->offset, event->pts);
Yahui Han63de7082023-07-12 18:30:10 +080059 #endif
Gong Kefa504d72023-04-18 10:23:35 +080060 break;
61
62 case TS_INDEXER_EVENT_TYPE_VIDEO_PTS:
Yahui Han53b3c502023-08-04 10:36:58 +080063 #if 1
Gong Kefa504d72023-04-18 10:23:35 +080064 INF("PID: %#x ", event->pid);
Yahui Han63de7082023-07-12 18:30:10 +080065 INF("TS_INDEXER_EVENT_TYPE_VIDEO_PTS, Offset: %lx, Lastoffset: %lx, Pts: %lx\n",
66 event->offset, gControl.last_offset, event->pts);
67 write_len = ts_indexer->offset - gControl.last_offset;
68 if (gControl.dump_file) {
Yahui Han63de7082023-07-12 18:30:10 +080069 fwrite(gControl.ptr, 1, write_len, gControl.dump_file);
70 gControl.ptr += write_len;
Yahui Han63de7082023-07-12 18:30:10 +080071 }
72 gControl.last_offset = ts_indexer->offset;
Gong Kefa504d72023-04-18 10:23:35 +080073 #endif
74 break;
75
76 case TS_INDEXER_EVENT_TYPE_AUDIO_PTS:
77 #if 0
78 INF("PID: %#x ", event->pid);
79 INF("TS_INDEXER_EVENT_TYPE_AUDIO_PTS, Offset: %lx, Pts: %lx\n",
80 event->offset, event->pts);
81 #endif
82 break;
83
Yahui Hana082ab62023-07-14 14:41:39 +080084 //case TS_INDEXER_EVENT_TYPE_START_INDICATOR:
85 //case TS_INDEXER_EVENT_TYPE_DISCONTINUITY_INDICATOR:
Yahui Han63de7082023-07-12 18:30:10 +080086 case TS_INDEXER_EVENT_TYPE_MPEG2_P_FRAME:
87 case TS_INDEXER_EVENT_TYPE_MPEG2_B_FRAME:
88 case TS_INDEXER_EVENT_TYPE_MPEG2_SEQUENCE:
89 case TS_INDEXER_EVENT_TYPE_AVC_I_SLICE:
90 case TS_INDEXER_EVENT_TYPE_AVC_P_SLICE:
91 case TS_INDEXER_EVENT_TYPE_AVC_B_SLICE:
92 case TS_INDEXER_EVENT_TYPE_AVC_SI_SLICE:
93 case TS_INDEXER_EVENT_TYPE_AVC_SP_SLICE:
94 case TS_INDEXER_EVENT_TYPE_HEVC_SPS:
95 case TS_INDEXER_EVENT_TYPE_HEVC_AUD:
96 case TS_INDEXER_EVENT_TYPE_HEVC_BLA_W_LP:
97 case TS_INDEXER_EVENT_TYPE_HEVC_BLA_W_RADL:
98 case TS_INDEXER_EVENT_TYPE_HEVC_IDR_W_RADL:
99 case TS_INDEXER_EVENT_TYPE_HEVC_IDR_N_LP:
100 case TS_INDEXER_EVENT_TYPE_HEVC_TRAIL_CRA:
Yahui Han53b3c502023-08-04 10:36:58 +0800101 INF("type: %d, offset: %#lx\n", event->type, event->offset);
Yahui Han63de7082023-07-12 18:30:10 +0800102 break;
103
Gong Kefa504d72023-04-18 10:23:35 +0800104 default:
105 break;
106 }
107
108 return;
109}
110
111static char *help_vfmt =
112 "\n\t0:TS_INDEXER_VIDEO_FORMAT_MPEG2" /**< MPEG2 video.*/
113 "\n\t1:TS_INDEXER_VIDEO_FORMAT_H264" /**< H264.*/
114 "\n\t2:TS_INDEXER_VIDEO_FORMAT_HEVC"; /**<HEVC.*/
115
116static void usage(int argc, char *argv[])
117{
118 INF("Usage: %s [ts=] [vpid=] [vfmt=] [apid=]\n", argv[0]);
119 INF("Usage: %s\n", help_vfmt);
120}
121
122int main(int argc, char **argv)
123{
124 int i;
125 char file[512];
126 int vpid = 0x1fff;
127 int apid = 0x1fff;
128 int vfmt = -1;
129 TS_Indexer_t ts_indexer;
130 int block_size = 188*1024;
131
132 memset(&file[0], 0, sizeof(file));
133 for (i = 1; i < argc; i++) {
134 if (!strncmp(argv[i], "ts=", 3))
135 sscanf(argv[i], "ts=%s", &file[0]);
136 else if (!strncmp(argv[i], "vpid=", 5))
137 sscanf(argv[i], "vpid=%i", &vpid);
138 else if (!strncmp(argv[i], "vfmt=", 5))
139 sscanf(argv[i], "vfmt=%i", &vfmt);
140 else if (!strncmp(argv[i], "apid=", 5))
141 sscanf(argv[i], "apid=%i", &apid);
142 else if (!strncmp(argv[i], "help", 4)) {
143 usage(argc, argv);
144 exit(0);
145 }
146 }
147
148 if (argc == 1 ||
Yahui Han63de7082023-07-12 18:30:10 +0800149 (vpid == 0x1fff && apid == 0x1fff))
Gong Kefa504d72023-04-18 10:23:35 +0800150 {
151 usage(argc, argv);
152 exit(0);
153 }
154
155 memset(&ts_indexer, 0, sizeof(TS_Indexer_t));
156 ts_indexer_init(&ts_indexer);
157 ts_indexer_set_video_pid(&ts_indexer, vpid);
158 ts_indexer_set_audio_pid(&ts_indexer, apid);
159 ts_indexer_set_video_format(&ts_indexer, vfmt);
160 ts_indexer_set_event_callback(&ts_indexer, ts_indexer_event_cb);
161
162 FILE *f = fopen(file, "rb");
163 if (f == NULL) {
164 ERR("open %s failed!\n", file);
165 return -1;
166 }
167
168 uint8_t *data = malloc(block_size);
169 if (data == NULL) {
170 ERR("no heap memory!\n");
171 return -1;
172 }
173
174 size_t len = 0;
175 INF("vpid: %#x, vfmt: %d, apid:%#x\n", vpid, vfmt, apid);
Yahui Han63de7082023-07-12 18:30:10 +0800176 memset(&gControl, 0, sizeof(ts_indexer_ctl));
177 gControl.last_pts = -1;
178 gControl.last_offset = 0;
179 gControl.dump_file = fopen("./dump.ts", "wb+");
180 if (gControl.dump_file == NULL) {
181 ERR("open dump file failed\n");
182 return -1;
183 }
184
185 INF("ptr: %p ~ %p\n", &data[0], &data[0] + block_size);
Gong Kefa504d72023-04-18 10:23:35 +0800186 while (1) {
187 len = fread(data, 1, block_size, f);
188 if (len <= 0)
189 break;
190
Yahui Han63de7082023-07-12 18:30:10 +0800191 gControl.ptr = &data[0];
Gong Kefa504d72023-04-18 10:23:35 +0800192 ts_indexer_parse(&ts_indexer, data, len);
Yahui Han63de7082023-07-12 18:30:10 +0800193 if (gControl.ptr - &data[0] < len) {
194 int left = len - (gControl.ptr - &data[0]);
195 fwrite(gControl.ptr, 1, left, gControl.dump_file);
196 gControl.last_offset += left;
197 }
Gong Kefa504d72023-04-18 10:23:35 +0800198 }
Yahui Han63de7082023-07-12 18:30:10 +0800199 fflush(gControl.dump_file);
200 fclose(gControl.dump_file);
Gong Kefa504d72023-04-18 10:23:35 +0800201
202 return 0;
203}