Mercurial > pt1.oyama
comparison src/tssplitter_lite.c @ 183:27e5f99f8991
Delete ES out function. Merge Yazawa's tssplitter_lite. Add liner option.
author | Naoya OYAMA <naoya.oyama@gmail.com> |
---|---|
date | Mon, 05 May 2014 22:08:21 +0900 |
parents | 863ac6807ee3 |
children | dc0d3addfd18 |
comparison
equal
deleted
inserted
replaced
182:13f0666bd088 | 183:27e5f99f8991 |
---|---|
23 #include <string.h> | 23 #include <string.h> |
24 #include <ctype.h> | 24 #include <ctype.h> |
25 | 25 |
26 #include <fcntl.h> | 26 #include <fcntl.h> |
27 #include <sys/stat.h> | 27 #include <sys/stat.h> |
28 #include <math.h> | |
29 #include <time.h> | |
30 #include "decoder.h" | 28 #include "decoder.h" |
31 #include "recpt1.h" | 29 #include "recpt1.h" |
32 #include "tssplitter_lite.h" | 30 #include "tssplitter_lite.h" |
33 #include "ushare.h" | |
34 #include "metadata.h" | |
35 | |
36 #ifndef AV_RB32 | |
37 #define AV_RB32(x) ((((const uint8_t*)(x))[0] << 24) | \ | |
38 (((const uint8_t*)(x))[1] << 16) | \ | |
39 (((const uint8_t*)(x))[2] << 8) | \ | |
40 ((const uint8_t*)(x))[3]) | |
41 #endif | |
42 | |
43 #ifndef AV_RB24 | |
44 #define AV_RB24(x) ((((const uint8_t*)(x))[0] << 16) | \ | |
45 (((const uint8_t*)(x))[1] << 8) | \ | |
46 ((const uint8_t*)(x))[2]) | |
47 #endif | |
48 | |
49 #ifndef AV_RB16 | |
50 #define AV_RB16(x) ((((const uint8_t*)(x))[0] << 8) | ((const uint8_t*)(x))[1]) | |
51 #endif | |
52 #define MAX_SERVICE_ID ( 0xffff ) | |
53 #define LIST_DECIMAL "0123456789" | |
54 #define TSS_STREAM_TYPE_AUDIO (1) | |
55 #define TSS_STREAM_TYPE_VIDEO (2) | |
56 | |
57 //global | |
58 extern struct ushare_t *ut; | |
59 | 31 |
60 /* prototypes */ | 32 /* prototypes */ |
61 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf); | 33 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf); |
62 static int AnalyzePat(splitter *sp, unsigned char *buf); | 34 static int AnalyzePat(splitter *sp, unsigned char *buf); |
63 static int RecreatePat(splitter *sp, unsigned char *buf, int *pos); | 35 static int RecreatePat(splitter *sp, unsigned char *buf, int *pos); |
64 static char** AnalyzeSid(char *sid); | 36 static char** AnalyzeSid(char *sid); |
65 static int AnalyzePmt(splitter *sp, const uint8_t *buf, int sid, const int size); | 37 static int AnalyzePmt(splitter *sp, unsigned char *buf, unsigned char mark); |
66 static int GetCrc32(unsigned char *data, int len); | 38 static int GetCrc32(unsigned char *data, int len); |
67 static int GetPid(unsigned char *data); | 39 static int GetPid(unsigned char *data); |
68 static int parse_tot( const unsigned char* packet, time_t *t ); | |
69 //void dump_packet( const uint8_t *packet ); | |
70 static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, const uint8_t *packet); | |
71 static int DemuxTs(const uint8_t *packet, splitter *sp, const int pid); | |
72 //static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid, int random_access_indicator); | |
73 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid); | |
74 static int64_t get_pts(const uint8_t *p); | |
75 //void search_mpeg_system_header(const uint8_t *p); | |
76 static int esbuf_write(splitesbuf_t *esbuf); | |
77 static int pesbuf_packet_start_code_prefix(splitpesbuf_t *pesbuf); | |
78 static int pesbuf_empty(splitpesbuf_t *pesbuf); | |
79 void pesbuf_clear(splitpesbuf_t *pesbuf); | |
80 static int pesbuf_add(splitpesbuf_t *pesbuf, const uint8_t *data, int len); | |
81 static int esbuf_empty(splitesbuf_t *esbuf); | |
82 void esbuf_clear(splitesbuf_t *esbuf, uint64_t pts, uint64_t dts); | |
83 static int esbuf_add(splitesbuf_t *esbuf, const uint8_t *data, int len); | |
84 static int get_pmt_version(const uint8_t *p); | |
85 static int next_adts_start_code(splitesbuf_t *esbuf, int offset); | |
86 static int is_video_stream(const int pid, splitesbuf_t *esbuf); | |
87 static int is_audio_stream(const int pid, splitesbuf_t *esbuf); | |
88 static int AnalyzeAdifHeader(splitesbuf_t *esbuf); | |
89 static int get_adif_id(uint8_t *p); | |
90 static int get_adif_layer(uint8_t *p); | |
91 static int get_adif_protection_absent(uint8_t *p); | |
92 static int get_adif_profile(uint8_t *p); | |
93 static int get_adif_sampling_frequency_index(uint8_t *p); | |
94 static int get_adif_private_bit(uint8_t *p); | |
95 static int get_adif_channel_configuration(uint8_t *p); | |
96 static int get_adif_original_copy(uint8_t *p); | |
97 static int get_adif_home(uint8_t *p); | |
98 static int get_adif_copyright_idication_bit(uint8_t *p); | |
99 static int get_adif_copyright_idication_start(uint8_t *p); | |
100 static int get_adif_aac_frame_length(uint8_t *p); | |
101 static int get_adts_buffer_fullness(uint8_t *p); | |
102 static int get_adts_no_raw_data_blocks_in_frame(uint8_t *p); | |
103 //static int search_pmt_program(splitter *sp, int pid); | |
104 static int search_gop_start_code(splitesbuf_t *esbuf); | |
105 static int creat_es_file(splitter *sp, int sid, int pid, int av_flag); | |
106 static time_t cue2time(char *yyyymmddhhmiss); | |
107 static int search_pcr_pid(splitter *sp, int pid); | |
108 | 40 |
109 /** | 41 /** |
110 * サービスID解析 | 42 * サービスID解析 |
111 */ | 43 */ |
112 static char** AnalyzeSid( | 44 static char** AnalyzeSid( |
192 i++; | 124 i++; |
193 } | 125 } |
194 #if 0 | 126 #if 0 |
195 for(i=0; sid_list[i] != NULL; i++) | 127 for(i=0; sid_list[i] != NULL; i++) |
196 { | 128 { |
197 printf(stderr, "sid_list[%d]=[%s].\n",i, sid_list[i]); | 129 printf("sid_list[%d]=[%s].\n",i, sid_list[i]); |
198 } | 130 } |
199 #endif | 131 #endif |
200 return sid_list; | 132 return sid_list; |
201 } | 133 } |
202 | 134 |
203 /** | 135 /** |
204 * 初期化処理 | 136 * 初期化処理 |
205 */ | 137 */ |
206 splitter* split_startup( | 138 splitter* split_startup( |
207 char *sid, // [in] サービスID(引数で指定した文字列) | 139 char *sid // [in] サービスID(引数で指定した文字列) |
208 char *filename, // [in] 出力ESファイル名(引数で指定したファイル名) | |
209 char *arg_cue // [in] 録画開始時刻(引数で指定した文字列 YYYYMMDDHHMISS) | |
210 ) | 140 ) |
211 { | 141 { |
212 splitter* sp; | 142 splitter* sp; |
213 int i; | |
214 sp = malloc(sizeof(splitter)); | 143 sp = malloc(sizeof(splitter)); |
215 if ( sp == NULL ) | 144 if ( sp == NULL ) |
216 { | 145 { |
217 fprintf(stderr, "split_startup malloc error.\n"); | 146 fprintf(stderr, "split_startup malloc error.\n"); |
218 return NULL; | 147 return NULL; |
219 } | 148 } |
220 sp->program = malloc( sizeof(program_t) * MAX_SERVICE_ID ); | |
221 if ( sp->program == NULL ) | |
222 { | |
223 fprintf(stderr, "split_startup malloc error.\n"); | |
224 return NULL; | |
225 } | |
226 memset(sp->pids, 0, sizeof(sp->pids)); | 149 memset(sp->pids, 0, sizeof(sp->pids)); |
227 memset(sp->pmt_pids, 0, sizeof(sp->pmt_pids)); | 150 memset(sp->pmt_pids, 0, sizeof(sp->pmt_pids)); |
228 memset(sp->cat_pids, 0, sizeof(sp->cat_pids)); | |
229 memset(sp->pcr_pids, 0, sizeof(sp->pcr_pids)); | |
230 memset(sp->pcr, 0, sizeof(sp->pcr)); | |
231 | 151 |
232 sp->sid_list = NULL; | 152 sp->sid_list = NULL; |
233 sp->pat = NULL; | 153 sp->pat = NULL; |
234 sp->sid_list = AnalyzeSid(sid); | 154 sp->sid_list = AnalyzeSid(sid); |
235 if ( sp->sid_list == NULL ) | 155 if ( sp->sid_list == NULL ) |
238 return NULL; | 158 return NULL; |
239 } | 159 } |
240 sp->pat_count = 0xFF; | 160 sp->pat_count = 0xFF; |
241 sp->pmt_retain = -1; | 161 sp->pmt_retain = -1; |
242 sp->pmt_counter = 0; | 162 sp->pmt_counter = 0; |
243 sp->time_cue = 0; | 163 |
244 sp->time_tot = 0; | 164 memset(sp->section_remain, 0U, sizeof(sp->section_remain)); |
245 sp->pcr_nb = 0; | 165 memset(sp->packet_seq, 0U, sizeof(sp->packet_seq)); |
246 memset(sp->esbuf, 0, sizeof(splitesbuf_t *)*MAX_PID); | 166 |
247 memset(sp->pesbuf, 0, sizeof(splitpesbuf_t *)*MAX_PID); | |
248 memset(sp->program, 0, sizeof(program_t *)*MAX_SERVICE_ID); | |
249 for ( i=0; i < MAX_PID; i++ ) { | |
250 /* pmt_version は (N%32) の値を取るので、0 で初期化してはならない */ | |
251 sp->program[i].pmt_version = -1; | |
252 /* cue は最大値で初期化(CUE <= STCとなると録画開始するため) */ | |
253 sp->program[i].cue = INT64_MAX; | |
254 } | |
255 memset(sp->pid_sid_table, 0, sizeof(int)*MAX_PID); | |
256 sp->filename = NULL; | |
257 sp->esout = 0; | |
258 if ( filename != NULL ) { | |
259 sp->esout = 1; | |
260 sp->filename = filename; | |
261 } | |
262 if ( arg_cue != NULL ) { | |
263 sp->arg_cue = arg_cue; | |
264 } else { | |
265 sp->arg_cue = "00000000000000"; /* とりあえず最小値 */ | |
266 } | |
267 sp->split_select_finish = TSS_ERROR; | 167 sp->split_select_finish = TSS_ERROR; |
168 | |
268 return sp; | 169 return sp; |
269 } | 170 } |
270 | 171 |
271 /** | 172 /** |
272 * 落とすPIDを確定させる | 173 * 落とすPIDを確定させる |
286 /** | 187 /** |
287 * 終了処理 | 188 * 終了処理 |
288 */ | 189 */ |
289 void split_shutdown(splitter* sp) | 190 void split_shutdown(splitter* sp) |
290 { | 191 { |
291 int i = 0; | |
292 if ( sp != NULL ) { | 192 if ( sp != NULL ) { |
293 if ( sp->program != NULL ) | |
294 { | |
295 free(sp->program); | |
296 sp->program = NULL; | |
297 } | |
298 if ( sp->pat != NULL ) | 193 if ( sp->pat != NULL ) |
299 { | 194 { |
300 free(sp->pat); | 195 free(sp->pat); |
301 sp->pat = NULL; | 196 sp->pat = NULL; |
302 } | 197 } |
303 if ( sp->sid_list != NULL ) | 198 if ( sp->sid_list != NULL ) |
304 { | 199 { |
305 free(sp->sid_list); | 200 free(sp->sid_list); |
306 sp->sid_list = NULL; | 201 sp->sid_list = NULL; |
307 } | 202 } |
308 for(i=0; i < MAX_PID; i++) { | |
309 if ( sp->esbuf[i] != NULL ) { | |
310 if ( sp->esbuf[i]->fd != -1 ) { | |
311 close(sp->esbuf[i]->fd); | |
312 sp->esbuf[i]->fd = -1; | |
313 } | |
314 free(sp->esbuf[i]); | |
315 sp->esbuf[i] = NULL; | |
316 } | |
317 if ( sp->pesbuf[i] != NULL ) { | |
318 free(sp->pesbuf[i]); | |
319 sp->pesbuf[i] = NULL; | |
320 } | |
321 } | |
322 free(sp); | 203 free(sp); |
323 sp = NULL; | 204 sp = NULL; |
324 } | 205 } |
325 } | 206 } |
326 | 207 |
328 * TS 解析処理 | 209 * TS 解析処理 |
329 * | 210 * |
330 * 対象のチャンネル番号のみの PAT の再構築と出力対象 PID の抽出を行う | 211 * 対象のチャンネル番号のみの PAT の再構築と出力対象 PID の抽出を行う |
331 */ | 212 */ |
332 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf) | 213 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf) |
333 { | |
334 #if 0 | 214 #if 0 |
335 splitter *sp, // [in/out] splitter構造体 | 215 unsigned char **pat, // [out] PAT 情報(再構築後) |
336 ARIB_STD_B25_BUFFER *sbuf, // [in] pt1_drvの入力TS | 216 unsigned char* pids, // [out] 出力対象 PID 情報 |
217 char** sid_list, // [in] 出力対象サービス ID のリスト | |
218 unsigned char* pmt_pids, // [in] 出力対象PIDのPMT PID | |
219 , // [in] pt1_drvの入力TS | |
220 int* pmt_retain, // [in] 残すべきPMTの数 | |
221 int* pmt_counter // [out] 残したPMTの数 | |
337 #endif | 222 #endif |
338 | 223 { |
339 int length = sbuf->size; | 224 int length = sbuf->size; |
340 int pid; | 225 int pid; |
341 int result = TSS_ERROR; | 226 int result = TSS_ERROR; |
342 int index; | 227 int index; |
228 int analyze_result = 0; | |
343 | 229 |
344 index = 0; | 230 index = 0; |
345 while(length - index - LENGTH_PACKET > 0) { | 231 while(length - index - LENGTH_PACKET > 0) { |
346 pid = GetPid(sbuf->data + index + 1); | 232 pid = GetPid(sbuf->data + index + 1); |
347 // PAT | 233 // PAT |
348 if(PAT == pid) { | 234 if(0x0000 == pid) { |
349 result = AnalyzePat(sp, sbuf->data + index); | 235 result = AnalyzePat(sp, sbuf->data + index); |
350 if(TSS_SUCCESS != result) { | 236 if(result != TSS_SUCCESS) { |
351 /* 下位の関数内部でmalloc error発生 */ | 237 /* 下位の関数内部でmalloc error発生 */ |
352 return result; | 238 return result; |
353 } | 239 } |
354 } | 240 } |
355 | 241 |
356 // PMT | 242 // PMT |
357 /* 残すpmt_pidである場合には、pmtに書かれている | 243 /* 残すpmt_pidである場合には、pmtに書かれている |
358 * 残すべきPCR/AUDIO/VIDEO PIDを取得する */ | 244 * 残すべきPCR/AUDIO/VIDEO PIDを取得する */ |
359 if(sp->pmt_pids[pid] == 1) { | 245 if(sp->pmt_pids[pid] == 1) { |
360 /* この中にはPMT毎に一度しか入らないようにしておく */ | 246 /* この中にはPMT毎に一度しか入らないようにしておく */ |
361 sp->pmt_pids[pid]++; | 247 analyze_result = AnalyzePmt(sp, sbuf->data + index, 1); |
362 sp->pmt_counter += 1; | 248 if(TSS_SUCCESS == analyze_result) { |
363 DemuxTs(sbuf->data +index, sp, pid); /* AnalyzePmt より DemuxTs の方がアダプテーションフィールドの処理が良いので変更 */ | 249 sp->pmt_pids[pid]++; |
364 } | 250 sp->pmt_counter += 1; |
365 /* 録画する全てのPMTについて、中にあるPCR/AUDIO/VIDEOのPIDを得る */ | 251 *(sbuf->data + index + 1) = 0xff; |
252 *(sbuf->data + index + 2) = 0xff; | |
253 } | |
254 } | |
255 /* 録画する全てのPMTについて、中にあるPCR/AUDIO/VIDEOのPIDを | |
256 * 得る */ | |
366 /* pmt_counter と pmt_retain が一致する場合に条件は満たされる */ | 257 /* pmt_counter と pmt_retain が一致する場合に条件は満たされる */ |
367 if(sp->pmt_counter == sp->pmt_retain) { | 258 if(sp->pmt_counter == sp->pmt_retain) { |
368 result = TSS_SUCCESS; | 259 result = TSS_SUCCESS; |
369 break; | 260 break; |
370 } | 261 } |
375 } | 266 } |
376 | 267 |
377 return(result); | 268 return(result); |
378 } | 269 } |
379 | 270 |
271 static int RescanPID(splitter *splitter, unsigned char *buf) | |
272 { | |
273 int result = TSS_NULL; | |
274 int i; | |
275 | |
276 // clear | |
277 if (splitter->pmt_counter == splitter->pmt_retain) { | |
278 memcpy(splitter->pids, splitter->pmt_pids, sizeof(splitter->pids)); | |
279 splitter->pmt_counter = 0; | |
280 memset(splitter->section_remain, 0U, sizeof(splitter->section_remain)); | |
281 memset(splitter->packet_seq, 0U, sizeof(splitter->packet_seq)); | |
282 | |
283 fprintf(stderr, "Rescan PID \n"); | |
284 } | |
285 | |
286 if (TSS_SUCCESS == AnalyzePmt(splitter, buf, 2)) { | |
287 splitter->pmt_counter += 1; | |
288 } | |
289 | |
290 if (splitter->pmt_retain == splitter->pmt_counter) { | |
291 result = TSS_SUCCESS; | |
292 for (i = 0; MAX_PID > i; i++) { | |
293 if (splitter->pids[i] > 0) { | |
294 splitter->pids[i] -= 1; | |
295 } | |
296 } | |
297 fprintf(stderr, "Rescan PID End\n"); | |
298 } | |
299 | |
300 return result; | |
301 } | |
380 /** | 302 /** |
381 * TS 分離処理 | 303 * TS 分離処理 |
382 */ | 304 */ |
383 int split_ts( | 305 int split_ts( |
384 splitter *sp, // [in] splitterパラメータ | 306 splitter *splitter, // [in] splitterパラメータ |
385 ARIB_STD_B25_BUFFER *sbuf, // [in] 入力TS | 307 ARIB_STD_B25_BUFFER *sbuf, // [in] 入力TS |
386 splitbuf_t *dbuf // [out] 出力TS | 308 splitbuf_t *dbuf // [out] 出力TS |
387 ) | 309 ) |
388 { | 310 { |
389 int pid; | 311 int pid; |
390 unsigned char *sptr, *dptr; | 312 unsigned char *sptr, *dptr; |
391 int s_offset = 0; | 313 int s_offset = 0; |
392 int d_offset = 0; | 314 int d_offset = 0; |
393 int64_t pcr_h = 0; | 315 int result = TSS_SUCCESS; |
394 int pcr_l = 0; | 316 int pmts = 0; |
395 int ret = 0; | 317 int version = 0; |
396 int sid = 0; | |
397 program_t *program; | |
398 static int packet_nb; /* パケット受信数 */ | |
399 int i = 0; | |
400 | 318 |
401 /* 初期化 */ | 319 /* 初期化 */ |
402 dbuf->size = 0; | 320 dbuf->buffer_filled = 0; |
403 if (sbuf->size < 0) { | 321 if (sbuf->size < 0) { |
404 return TSS_ERROR; | 322 return TSS_ERROR; |
405 } | 323 } |
406 | 324 |
407 sptr = sbuf->data; | 325 sptr = sbuf->data; |
408 dptr = dbuf->buffer; | 326 dptr = dbuf->buffer; |
409 | 327 |
410 while(sbuf->size > s_offset) { | 328 while(sbuf->size > s_offset) { |
411 pid = GetPid(sptr + s_offset + 1); | 329 pid = GetPid(sptr + s_offset + 1); |
412 sid = sp->pid_sid_table[pid]; /* PIDからSIDを取得 */ | |
413 switch(pid) { | 330 switch(pid) { |
414 | 331 |
415 // PAT | 332 // PAT |
416 case PAT: | 333 case 0x0000: |
417 // 巡回カウンタカウントアップ | 334 // 巡回カウンタカウントアップ |
418 if(0xFF == sp->pat_count) { | 335 if(0xFF == splitter->pat_count) { |
419 sp->pat_count = sp->pat[3]; | 336 splitter->pat_count = splitter->pat[3]; |
420 } | 337 } |
421 else { | 338 else { |
422 sp->pat_count += 1; | 339 splitter->pat_count += 1; |
423 if(0 == sp->pat_count % 0x10) { | 340 if(0 == splitter->pat_count % 0x10) { |
424 sp->pat_count -= 0x10; | 341 splitter->pat_count -= 0x10; |
425 } | 342 } |
426 } | 343 } |
427 sp->pat[3] = sp->pat_count; | 344 splitter->pat[3] = splitter->pat_count; |
428 | 345 |
429 memcpy(dptr + d_offset, sp->pat, LENGTH_PACKET); | 346 memcpy(dptr + d_offset, splitter->pat, LENGTH_PACKET); |
430 d_offset += LENGTH_PACKET; | 347 d_offset += LENGTH_PACKET; |
431 dbuf->size += LENGTH_PACKET; | 348 dbuf->buffer_filled += LENGTH_PACKET; |
432 break; | |
433 case TOT: | |
434 /* TOT に TDTの情報全てが含まれており、実放送では TOT しか送信されない */ | |
435 /* TOT は 500msec の誤差が保証されている | |
436 * 閏秒の場合は最大1.5秒の誤差となる | |
437 */ | |
438 if ( sp->time_tot == 0 ) { | |
439 /* splitter構造体の時刻関係(TOT/CUE)のパラメータ初期化 */ | |
440 parse_tot(sptr + s_offset, &(sp->time_tot)); | |
441 sp->time_cue = cue2time(sp->arg_cue); | |
442 sp->tot_packet_nb = packet_nb; | |
443 } | |
444 break; | 349 break; |
445 default: | 350 default: |
446 /* ■時間管理に関しての実装方針■ */ | 351 if(0 != splitter->pmt_pids[pid]) { |
447 /* | 352 //PMT |
448 * ■時間関係を扱っている変数■ | 353 if ((sptr + s_offset)[1] & 0x40) { // PES開始インジケータ |
449 * PCR : 42Bit @27MHz(ServiceID(ProgramID, sid)毎に独立) | 354 // バージョンチェック |
450 * PTS : 42Bit @90KHz(ES毎に独立) | 355 for(pmts = 0; splitter->pmt_retain > pmts; pmts++) { |
451 * DTS : 42Bit @90KHz(ES毎に独立) | 356 if (splitter->pmt_version[pmts].pid == pid) { |
452 * TOT : MJD + 2進化10進数(TSに1つだけ) | 357 version = splitter->pmt_version[pmts].version; |
453 * STC : 64Bit @27MHz(ServiceID(ProgramID, sid)の現在時刻(ソースはPCR)) | 358 break; |
454 * CUE : 録画開始時刻 YYYYMMDDHHMISS (引数指定) | 359 } |
455 * | 360 } |
456 * ■STCの管理方針■ | 361 if((version != ((sptr + s_offset)[10] & 0x3e)) |
457 * PCR受信時にSTCに時間情報をコピーする | 362 ||(splitter->pmt_retain != splitter->pmt_counter)) { |
458 * 1パケットを受信すると経過する時間を加算してSTCを管理する | 363 // 再チェック |
459 * (ffmpegのmpegts.cと同じ方針) | 364 result = RescanPID(splitter, sptr + s_offset); |
460 * | 365 } |
461 * ■CUEとTOTとSTC■ | 366 } |
462 * TOTからSTCと比較するための情報を作成する。 | 367 else { |
463 * ・TOTは time_t | 368 if (splitter->pmt_retain != splitter->pmt_counter) { |
464 * ・CUEは time_t | 369 // 再チェック |
465 * ・STCは42Bitの27MHz周期の数値 | 370 result = RescanPID(splitter, sptr + s_offset); |
466 * TOT 受信時に各Program(ServiceID)のSTCを変換基準値とする | 371 } |
467 * 録画開始時(27MHz)の値の計算式は、 | 372 } |
468 * Program->CUE = STCの変換基準値 + 27e6*(ARG_CUE-TOT(秒)) | |
469 * 録画の開始確認として Program->CUE と PTS を比較すればよい | |
470 * | |
471 * ※PCR/PTS/DTSはオーバーフローしたときには34Bit目が立っていると見なすこと※ | |
472 * オーバーフロー時の処理は未実装 | |
473 */ | |
474 if ( 2 == sp->pmt_pids[pid] ) { | |
475 /* PMT の追跡 */ | |
476 DemuxTs((sptr+s_offset), sp, pid); | |
477 } | 373 } |
478 /* pids[pid] が 1 は残すパケットなので書き込む */ | 374 /* pids[pid] が 1 は残すパケットなので書き込む */ |
479 if ( (1 == sp->pids[pid]) ) { | 375 if(0 != splitter->pids[pid]) { |
480 /* PCRとSTCの処理 */ | |
481 int pcr_index; | |
482 pcr_index = search_pcr_pid(sp, pid); | |
483 if ( sp->pcr_pids[pid] == 1 && pcr_index != -1) { /* PCRか否か */ | |
484 ret = parse_pcr(&pcr_h, &pcr_l, (sptr+s_offset)); | |
485 /* | |
486 * PCR は複数 ServiceID(ProgramID)で重複利用される場合がある | |
487 * PCR を参照する複数の ServiceID(ProgramID)分ループ | |
488 */ | |
489 for (i=0; i < sp->pcr[pcr_index].sid_nb; i++) { | |
490 sid = sp->pcr[pcr_index].sid[i]; | |
491 program = &(sp->program[sid]); | |
492 /* こっから */ | |
493 if ( ret == 0 ) { /* PCR の解析に成功 */ | |
494 program->stc = pcr_h * 300 + pcr_l; /* PCR受信時にSTCを補正*/ | |
495 if ( program->pcr1 == 0 ) { | |
496 program->pcr1 = program->stc; | |
497 fprintf(stderr, "pcr1 pid[%d] sid[%d] packet_nb[%d] sid_nb[%d] i[%d]\n", | |
498 pid, sid, packet_nb, sp->pcr[pcr_index].sid_nb, i); | |
499 } else if ( program->pcr2 == 0 ) { | |
500 // fprintf(stderr, "pcr2 pid[%d] sid[%d] packet_nb[%d], p_packet_nb[%d] sid_nb[%d] i[%d]\n", | |
501 // pid, sid, packet_nb, program->pcr_packet_nb, sp->pcr[pcr_index].sid_nb, i); | |
502 program->pcr2 = program->stc; | |
503 program->pcr_incr = (program->pcr2 -program->pcr1) | |
504 /(packet_nb -program->pcr_packet_nb); | |
505 fprintf(stderr, "pcr2 pid[%d] sid[%d] pcr_incr[%llu]\n", | |
506 pid, sid, program->pcr_incr); | |
507 } else { | |
508 /* PCR処理済み */ | |
509 ; /* 得に処理無し */ | |
510 } | |
511 if ( (program->cue == INT64_MAX ) && | |
512 (sp->arg_cue != NULL) && | |
513 (sp->time_tot != 0) ) { /* 録画開始時刻指定時 */ | |
514 /* | |
515 * 録画開始時刻 = STC +(CUE -TOT)*27MHz | |
516 * +(TOT取得時から現在までのパケット数の増分)*パケットあたりの進む時間 | |
517 * -0.49秒(この数字は適当) | |
518 * TOT/STCで時間調整して、GOP先頭から出すので攻めてしまっていい気がする | |
519 */ | |
520 program->cue = program->stc | |
521 +(sp->time_cue -sp->time_tot)*27e6 | |
522 +(packet_nb -sp->tot_packet_nb)*program->pcr_incr | |
523 -(27e6*49/100); | |
524 fprintf(stderr, "STC[%llu] CUE[%llu] SID[%d]\n", | |
525 program->stc, program->cue, sid); | |
526 } | |
527 program->pcr_packet_nb = packet_nb; | |
528 program->packet_nb = packet_nb; | |
529 } else if ( program->pcr_incr ) { /* PCRの解析に失敗且つpcr_incr変数の計算済み*/ | |
530 /* STCを成長させる */ | |
531 program->stc += (packet_nb -program->packet_nb)*program->pcr_incr; | |
532 program->packet_nb = packet_nb; | |
533 } else { | |
534 ; /* STCを進める要素が揃ってません */ | |
535 } | |
536 } /* for */ | |
537 } else { /* 処理対象パケットはPCRではない */ | |
538 program = &(sp->program[sid]); | |
539 if ( program->pcr_incr ) { /* PCRを受信しない且つpcr_incr変数の計算済み */ | |
540 /* STCを成長させる */ | |
541 program->stc += (packet_nb -program->packet_nb)*program->pcr_incr; | |
542 program->packet_nb = packet_nb; | |
543 } else { /* それ以外 */ | |
544 ; /* STCを進める要素が揃ってません */ | |
545 } | |
546 } | |
547 #if 0 | |
548 // NHK Gを ALL とすると SID 1024 しか出ない...orz.. | |
549 if ( !(packet_nb % 1000) ) { | |
550 program = &(sp->program[sid]); | |
551 fprintf("STC[%llu] SID[%d]\n", program->stc, sid); | |
552 } | |
553 #endif | |
554 /* TS処理 */ | |
555 DemuxTs((sptr+s_offset), sp, pid); | |
556 memcpy(dptr + d_offset, sptr + s_offset, LENGTH_PACKET); | 376 memcpy(dptr + d_offset, sptr + s_offset, LENGTH_PACKET); |
557 d_offset += LENGTH_PACKET; | 377 d_offset += LENGTH_PACKET; |
558 dbuf->size += LENGTH_PACKET; | 378 dbuf->buffer_filled += LENGTH_PACKET; |
559 } | 379 } |
560 break; | 380 break; |
561 } /* switch */ | 381 } /* switch */ |
382 | |
562 s_offset += LENGTH_PACKET; | 383 s_offset += LENGTH_PACKET; |
563 packet_nb += 1; /* パケット受信数加算 */ | 384 } |
564 } | 385 |
565 return(TSS_SUCCESS); | 386 return result; |
566 } | 387 } |
567 | 388 |
568 /** | 389 /** |
569 * PAT 解析処理 | 390 * PAT 解析処理 |
570 * | 391 * |
571 * PAT を解析し、出力対象チャンネルが含まれているかチェックを行い、PAT を再構築する | 392 * PAT を解析し、出力対象チャンネルが含まれているかチェックを行い、PAT を再構築する |
572 */ | 393 */ |
573 static int AnalyzePat(splitter *sp, unsigned char *buf) | 394 static int AnalyzePat(splitter *sp, unsigned char *buf) |
574 #if 0 | 395 #if 0 |
396 splitter *sp | |
397 unsigned char** pat, // [out] PAT 情報(再構築後) | |
398 unsigned char* pids, // [out] 出力対象 PID 情報 | |
399 char** sid_list, // [in] 出力対象サービス ID のリスト | |
400 unsigned char* pmt_pids, // [out] サービス ID に対応する PMT の PID | |
401 int* pmt_retain // [out] 残すPMTの数 | |
402 | |
575 unsigned char* buf, // [in] 読み込んだバッファ | 403 unsigned char* buf, // [in] 読み込んだバッファ |
576 unsigned char** pat, // [out] PAT 情報(再構築後) | |
577 unsigned char* pids, // [out] 出力対象 PID 情報 | |
578 char** sid_list, // [in] 出力対象サービス ID のリスト | |
579 unsigned char* pmt_pids, // [out] サービス ID に対応する PMT の PID | |
580 int* pmt_retain // [out] 残すPMTの数 | |
581 ) | |
582 #endif | 404 #endif |
583 { | 405 { |
584 int pos[MAX_PID]; | 406 int pos[MAX_PID]; |
585 int service_id; | 407 int service_id; |
586 int i, j, k; | 408 int i, j, k; |
605 memset(pos, 0, sizeof(pos)); | 427 memset(pos, 0, sizeof(pos)); |
606 size = buf[7]; | 428 size = buf[7]; |
607 | 429 |
608 /* prescan SID/PMT */ | 430 /* prescan SID/PMT */ |
609 for(i = 13, j = 0; i < (size + 8) - 4; i = i + 4) { | 431 for(i = 13, j = 0; i < (size + 8) - 4; i = i + 4) { |
432 | |
610 pid = GetPid(&buf[i+2]); | 433 pid = GetPid(&buf[i+2]); |
611 if(pid == NIT) | 434 if(pid == 0x0010) |
612 continue; | 435 continue; |
613 avail_sids[j] = (buf[i] << 8) + buf[i+2]; | 436 |
437 avail_sids[j] = (buf[i] << 8) + buf[i+1]; | |
614 sp->avail_pmts[j] = pid; | 438 sp->avail_pmts[j] = pid; |
615 j++; | 439 j++; |
616 } | 440 } |
617 sp->num_pmts = j; | 441 sp->num_pmts = j; |
618 | 442 |
619 // 対象チャンネル判定 | 443 // 対象チャンネル判定 |
620 /* size + 8 = パケット全長 */ | 444 /* size + 8 = パケット全長 */ |
621 /* 最終 4 バイトはCRCなので飛ばす */ | 445 /* 最終 4 バイトはCRCなので飛ばす */ |
622 for(i = 13; i < (size + 8) - 4; i = i + 4) { | 446 for(i = 13; i < (size + 8) - 4; i = i + 4) { |
447 | |
623 pid = GetPid(&buf[i+2]); | 448 pid = GetPid(&buf[i+2]); |
624 if(pid == NIT) | 449 if(pid == 0x0010) |
625 continue; | 450 continue; |
626 | 451 |
627 service_id = (buf[i] << 8) + buf[i+1]; | 452 service_id = (buf[i] << 8) + buf[i+1]; |
628 p = sid_list; | 453 p = sid_list; |
629 | 454 |
630 while(*p) { | 455 while(*p) { |
631 if(service_id == atoi(*p)) { | 456 if(service_id == atoi(*p)) { |
632 /* 録画対象の pmt_pids は 1 とする */ | 457 /* 録画対象の pmt_pids は 1 とする */ |
633 /* 録画対象の pmt の pids は 1 とする */ | 458 /* 録画対象の pmt の pids は 1 とする */ |
634 /* 対応する pid_sid_table に サービスID(ProgramID) を入れる */ | |
635 pid = GetPid(&buf[i + 2]); | 459 pid = GetPid(&buf[i + 2]); |
636 *(pmt_pids+pid) = 1; | 460 *(pmt_pids+pid) = 1; |
637 *(pids+pid) = 1; | 461 *(pids+pid) = 1; |
638 pos[pid] = i; | 462 pos[pid] = i; |
639 sid_found = TRUE; | 463 sid_found = TRUE; |
464 sp->pmt_version[sp->pmt_retain].pid = pid; | |
640 sp->pmt_retain += 1; | 465 sp->pmt_retain += 1; |
641 sp->program[service_id].pmt_packet_id = pid; | |
642 sp->pid_sid_table[pid] = service_id; | |
643 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 466 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
644 p++; | 467 p++; |
645 continue; | 468 continue; |
646 } | 469 } |
647 else if(!strcasecmp(*p, "hd") || !strcasecmp(*p, "sd1")) { | 470 else if(!strcasecmp(*p, "hd") || !strcasecmp(*p, "sd1")) { |
650 pid = GetPid(&buf[i + 2]); | 473 pid = GetPid(&buf[i + 2]); |
651 *(pmt_pids+pid) = 1; | 474 *(pmt_pids+pid) = 1; |
652 *(pids+pid) = 1; | 475 *(pids+pid) = 1; |
653 pos[pid] = i; | 476 pos[pid] = i; |
654 sid_found = TRUE; | 477 sid_found = TRUE; |
478 sp->pmt_version[sp->pmt_retain].pid = pid; | |
655 sp->pmt_retain += 1; | 479 sp->pmt_retain += 1; |
656 sp->program[service_id].pmt_packet_id = pid; | |
657 sp->pid_sid_table[pid] = service_id; | |
658 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 480 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
659 } | 481 } |
660 p++; | 482 p++; |
661 continue; | 483 continue; |
662 } | 484 } |
666 pid = GetPid(&buf[i + 2]); | 488 pid = GetPid(&buf[i + 2]); |
667 *(pmt_pids+pid) = 1; | 489 *(pmt_pids+pid) = 1; |
668 *(pids+pid) = 1; | 490 *(pids+pid) = 1; |
669 pos[pid] = i; | 491 pos[pid] = i; |
670 sid_found = TRUE; | 492 sid_found = TRUE; |
493 sp->pmt_version[sp->pmt_retain].pid = pid; | |
671 sp->pmt_retain += 1; | 494 sp->pmt_retain += 1; |
672 sp->program[service_id].pmt_packet_id = pid; | |
673 sp->pid_sid_table[pid] = service_id; | |
674 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 495 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
675 } | 496 } |
676 p++; | 497 p++; |
677 continue; | 498 continue; |
678 } | 499 } |
682 pid = GetPid(&buf[i + 2]); | 503 pid = GetPid(&buf[i + 2]); |
683 *(pmt_pids+pid) = 1; | 504 *(pmt_pids+pid) = 1; |
684 *(pids+pid) = 1; | 505 *(pids+pid) = 1; |
685 pos[pid] = i; | 506 pos[pid] = i; |
686 sid_found = TRUE; | 507 sid_found = TRUE; |
508 sp->pmt_version[sp->pmt_retain].pid = pid; | |
687 sp->pmt_retain += 1; | 509 sp->pmt_retain += 1; |
688 sp->program[service_id].pmt_packet_id = pid; | |
689 sp->pid_sid_table[pid] = service_id; | |
690 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 510 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
691 } | 511 } |
692 p++; | 512 p++; |
693 continue; | 513 continue; |
694 } | 514 } |
698 if(pid == 0x1FC8) { | 518 if(pid == 0x1FC8) { |
699 *(pmt_pids+pid) = 1; | 519 *(pmt_pids+pid) = 1; |
700 *(pids+pid) = 1; | 520 *(pids+pid) = 1; |
701 pos[pid] = i; | 521 pos[pid] = i; |
702 sid_found = TRUE; | 522 sid_found = TRUE; |
523 sp->pmt_version[sp->pmt_retain].pid = pid; | |
703 sp->pmt_retain += 1; | 524 sp->pmt_retain += 1; |
704 sp->program[service_id].pmt_packet_id = pid; | |
705 sp->pid_sid_table[pid] = service_id; | |
706 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 525 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
707 } | 526 } |
708 p++; | 527 p++; |
709 continue; | 528 continue; |
710 } | 529 } |
713 pid = GetPid(&buf[i + 2]); | 532 pid = GetPid(&buf[i + 2]); |
714 *(pmt_pids+pid) = 1; | 533 *(pmt_pids+pid) = 1; |
715 *(pids+pid) = 1; | 534 *(pids+pid) = 1; |
716 pos[pid] = i; | 535 pos[pid] = i; |
717 sid_found = TRUE; | 536 sid_found = TRUE; |
537 sp->pmt_version[sp->pmt_retain].pid = pid; | |
718 sp->pmt_retain += 1; | 538 sp->pmt_retain += 1; |
719 sp->program[service_id].pmt_packet_id = pid; | |
720 sp->pid_sid_table[pid] = service_id; | |
721 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 539 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
722 break; | 540 break; |
723 } | 541 } |
542 else if(!strcasecmp(*p, "epg")) { | |
543 /* epg抽出に必要なPIDのみを保存する */ | |
544 sid_found = TRUE; | |
545 *(pids+0x11) = 1; | |
546 *(pids+0x12) = 1; | |
547 *(pids+0x26) = 1; | |
548 *(pids+0x27) = 1; | |
549 break; | |
550 } | |
724 | 551 |
725 p++; | 552 p++; |
726 } /* while */ | 553 } /* while */ |
727 } | 554 } |
728 | 555 |
729 /* if sid has been specified but no sid found, fall back to all */ | 556 /* if sid has been specified but no sid found, fall back to all */ |
730 if(*sid_list && !sid_found) { | 557 if(*sid_list && !sid_found) { |
731 for(i = 17; i < (size + 8) - 4; i = i + 4) { | 558 for(i = 13; i < (size + 8) - 4; i = i + 4) { |
559 | |
560 pid = GetPid(&buf[i+2]); | |
561 if(pid==0x0010) | |
562 continue; | |
563 | |
732 service_id = (buf[i] << 8) + buf[i+1]; | 564 service_id = (buf[i] << 8) + buf[i+1]; |
733 pid = GetPid(&buf[i + 2]); | 565 pid = GetPid(&buf[i + 2]); |
734 *(pmt_pids+pid) = 1; | 566 *(pmt_pids+pid) = 1; |
735 *(pids+pid) = 1; | 567 *(pids+pid) = 1; |
736 pos[pid] = i; | 568 pos[pid] = i; |
737 sid_found = TRUE; | 569 sid_found = TRUE; |
570 sp->pmt_version[sp->pmt_retain].pid = pid; | |
738 sp->pmt_retain += 1; | 571 sp->pmt_retain += 1; |
739 sp->program[service_id].pmt_packet_id = pid; | |
740 sp->pid_sid_table[pid] = service_id; | |
741 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 572 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
742 } | 573 } |
743 } | 574 } |
744 | 575 |
745 /* print SIDs */ | 576 /* print SIDs */ |
747 for(k=0; k < sp->num_pmts; k++) | 578 for(k=0; k < sp->num_pmts; k++) |
748 fprintf(stderr, "%d ", avail_sids[k]); | 579 fprintf(stderr, "%d ", avail_sids[k]); |
749 fprintf(stderr, "\n"); | 580 fprintf(stderr, "\n"); |
750 fprintf(stderr, "Chosen sid =%s\n", chosen_sid); | 581 fprintf(stderr, "Chosen sid =%s\n", chosen_sid); |
751 | 582 |
752 #if 0 | 583 #if 1 |
753 /* print PMTs */ | 584 /* print PMTs */ |
754 fprintf(stderr, "Available PMT = "); | 585 fprintf(stderr, "Available PMT = "); |
755 for(k=0; k < sp->num_pmts; k++) | 586 for(k=0; k < sp->num_pmts; k++) |
756 fprintf(stderr, "0x%x ", sp->avail_pmts[k]); | 587 fprintf(stderr, "0x%x ", sp->avail_pmts[k]); |
757 fprintf(stderr, "\n"); | 588 fprintf(stderr, "\n"); |
774 * | 605 * |
775 * PMT から出力対象チャンネル以外のチャンネル情報を削除し、PAT を再構築する | 606 * PMT から出力対象チャンネル以外のチャンネル情報を削除し、PAT を再構築する |
776 */ | 607 */ |
777 static int RecreatePat(splitter *sp, unsigned char *buf, int *pos) | 608 static int RecreatePat(splitter *sp, unsigned char *buf, int *pos) |
778 #if 0 | 609 #if 0 |
779 splitter *sp // [in/out] splitter | 610 splitter *sp // [in/out] |
780 unsigned char* buf, // [in] 読み込んだバッファ | |
781 int *pos // [in] 取得対象 PMT のバッファ中の位置 | 611 int *pos // [in] 取得対象 PMT のバッファ中の位置 |
782 #endif | 612 #endif |
783 { | 613 { |
784 unsigned char y[LENGTH_CRC_DATA]; | 614 unsigned char y[LENGTH_CRC_DATA]; |
785 int crc; | 615 int crc; |
793 // チャンネルによって変わらない部分 | 623 // チャンネルによって変わらない部分 |
794 for (i = 0; i < LENGTH_PAT_HEADER - 4; i++) | 624 for (i = 0; i < LENGTH_PAT_HEADER - 4; i++) |
795 { | 625 { |
796 y[i] = buf[i + 5]; | 626 y[i] = buf[i + 5]; |
797 } | 627 } |
628 | |
798 // NIT | 629 // NIT |
799 y[LENGTH_PAT_HEADER-4] = 0x00; | 630 y[LENGTH_PAT_HEADER-4] = 0x00; |
800 y[LENGTH_PAT_HEADER-3] = 0x00; | 631 y[LENGTH_PAT_HEADER-3] = 0x00; |
801 y[LENGTH_PAT_HEADER-2] = 0xe0; | 632 y[LENGTH_PAT_HEADER-2] = 0xe0; |
802 y[LENGTH_PAT_HEADER-1] = 0x10; | 633 y[LENGTH_PAT_HEADER-1] = 0x10; |
634 | |
803 // チャンネルによって変わる部分 | 635 // チャンネルによって変わる部分 |
804 for (i = 0; i < MAX_PID; i++) | 636 for (i = 0; i < MAX_PID; i++) |
805 { | 637 { |
806 if(pos[i] != 0) | 638 if(pos[i] != 0) |
807 { | 639 { |
842 (sp->pat)[8 + LENGTH_PAT_HEADER + pid_num*4] = (crc ) & 0xFF; | 674 (sp->pat)[8 + LENGTH_PAT_HEADER + pid_num*4] = (crc ) & 0xFF; |
843 | 675 |
844 return(TSS_SUCCESS); | 676 return(TSS_SUCCESS); |
845 } | 677 } |
846 | 678 |
847 | |
848 /** | 679 /** |
849 * PMT 解析処理 | 680 * PMT 解析処理 |
850 * | 681 * |
851 * PMT を解析し、保存対象の PID を特定する | 682 * PMT を解析し、保存対象の PID を特定する |
852 * TSヘッダとアダプテーションフィールドの処理は DemuxTs に一任するので、 | 683 */ |
853 * この内部では、セクションデータの先頭ポインタをもらってくる | 684 static int AnalyzePmt(splitter *sp, unsigned char *buf, unsigned char mark) |
854 */ | |
855 static int AnalyzePmt(splitter *sp, const uint8_t *buf, int sid, const int size) | |
856 #if 0 | 685 #if 0 |
857 unsigned char* buf, // [in] セクション先頭 | 686 unsigned char* buf, // [in] 読み込んだバッファ |
858 unsigned char* pids) // [out] 出力対象 PID 情報 | 687 unsigned char* pids // [out] 出力対象 PID 情報 |
859 #endif | 688 #endif |
860 { | 689 { |
861 unsigned char Nall; | 690 unsigned char Nall; |
862 unsigned char N; | 691 unsigned char N; |
863 int pcr; | 692 int pcr; |
864 int epid; | 693 int epid; |
865 int av_flag = 0; | 694 int pid; |
866 int i = 0; | 695 int retry_count = 0; |
867 int j = 0; | 696 int count; |
868 int pcr_found = 0; | 697 int payload_offset; // offset to payload |
869 /* デバッグ用 PMT情報表示 */ | 698 |
870 #define PmtDebug (1) | 699 pid = GetPid(&buf[1]); |
871 | 700 if (buf[1] & 0x40) { // PES開始インジケータ |
872 #ifdef PmtDebug | 701 sp->section_remain[pid] = ((buf[6] & 0x0F) << 8) + buf[7] + 3; // セクションサイズ取得(ヘッダ込) |
873 printf("AnalyzePmt start. Tree List enable.\n"); | 702 payload_offset = 5; |
874 printf("SID[%d][0x%04x]\n", sid, sid); | 703 |
875 #endif | 704 for (count = 0; sp->pmt_retain > count; count++) { |
876 | 705 if (sp->pmt_version[count].pid == pid) { |
877 // Nall = ((buf[2] & 0x0F) << 4) + buf[3]; | 706 sp->pmt_version[count].version = buf[10] & 0x3e; |
878 Nall = ((buf[2] & 0x0F) << 8) + buf[3]; | 707 } |
879 // ここで受け取るのはTSパケットではなく、セクションの先頭ポインタであるのでsizeで見る | 708 } |
880 // if(Nall > LENGTH_PACKET) | 709 // PCR, 番組情報が先頭からはみ出ることはないだろう |
881 // Nall = LENGTH_PACKET - 8; /* xxx workaround --yaz */ | 710 |
882 if(Nall > size) | 711 // PCR |
883 Nall = size -8; | 712 pcr = GetPid(&buf[payload_offset + 8]); |
884 | 713 sp->pids[pcr] = mark; |
885 /* get version */ | 714 |
886 sp->program[sid].pmt_version = get_pmt_version(buf); | 715 // ECM |
887 #ifdef PmtDebug | 716 N = ((buf[payload_offset + 10] & 0x0F) << 8) + buf[payload_offset + 11] + payload_offset + 12; // ES情報開始点 |
888 printf(" pmt_version[%02x]\n", sp->program[sid].pmt_version); | 717 int p = payload_offset + 12; |
889 #endif | 718 |
890 | 719 while(p < N) { |
891 // PCR | 720 uint32_t ca_pid; |
892 pcr = GetPid(&buf[9]); | 721 uint32_t tag; |
893 sp->pids[pcr] = 1; | 722 uint32_t len; |
894 sp->program[sid].pcr_packet_id = pcr; | 723 |
895 sp->pid_sid_table[pcr] = sid; /* PCRは重複する可能性があるので方式がよろしくない */ | 724 tag = buf[p]; |
896 sp->pcr_pids[pcr] = 1; | 725 len = buf[p+1]; |
897 | 726 p += 2; |
898 /* PCRの重複チェック(複数ServiceID(ProgramID)) */ | 727 |
899 for( i=0; i < sp->pcr_nb; i++ ) { | 728 if(tag == 0x09 && len >= 4 && p+len <= N) { |
900 if ( sp->pcr[i].pid == pcr ) { | 729 ca_pid = ((buf[p+2] << 8) | buf[p+3]) & 0x1fff; |
901 /* 発見 */ | 730 sp->pids[ca_pid] = mark; |
902 for ( j=0; j < sp->pcr[i].sid_nb; j++ ) { | 731 } |
903 /* 同一SIDが既に登録されているか確認 */ | 732 p += len; |
904 if ( sp->pcr[i].sid[j] == sid ) { | 733 } |
905 pcr_found = 1; | 734 } |
906 break; | 735 else { |
907 } | 736 if (sp->section_remain[pid] == 0) return TSS_ERROR; // セクション先頭が飛んでいる |
908 } | 737 if ((buf[3] & 0x0F) != ((sp->packet_seq[pid] + 1) & 0x0F)) return TSS_ERROR; // パケットカウンタが飛んだ |
909 if ( pcr_found ) { | 738 payload_offset = 4; |
910 /* 同一SIDが既に登録されている */ | 739 N = payload_offset; |
911 #ifdef PmtDebug | 740 } |
912 printf(" same sid found pcr[%d] sid[%d]\n", pcr, sid); | 741 sp->packet_seq[pid] = buf[3] & 0x0F; // 巡回カウンタ |
913 #endif | 742 |
914 break; | 743 Nall = sp->section_remain[pid]; |
915 } | 744 if(Nall > LENGTH_PACKET - payload_offset) |
916 /* 重複PCR発見 */ | 745 Nall = LENGTH_PACKET - payload_offset; |
917 #ifdef PmtDebug | |
918 printf(" same pcr found pcr[%d] sid[%d] sid_nb[%d], i[%d]\n", pcr, sid, sp->pcr[i].sid_nb, i); | |
919 #endif | |
920 sp->pcr[i].sid[sp->pcr[i].sid_nb] = sid; | |
921 sp->pcr[i].sid_nb += 1; | |
922 pcr_found = 1; | |
923 break; | |
924 } | |
925 } | |
926 | |
927 if ( ! pcr_found ) { | |
928 /* PCR管理領域更新 */ | |
929 #ifdef PmtDebug | |
930 printf(" new pcr found pcr[%d] sid[%d], pcr_nb[%d]\n", pcr, sid, sp->pcr_nb); | |
931 #endif | |
932 sp->pcr[sp->pcr_nb].pid = pcr; | |
933 sp->pcr[sp->pcr_nb].sid[0] = sid; | |
934 sp->pcr[sp->pcr_nb].sid_nb = 1; | |
935 sp->pcr_nb += 1; | |
936 } | |
937 #ifdef PmtDebug | |
938 printf(" PCR PacketID[%d][0x%04x]\n", pcr, pcr); | |
939 #endif | |
940 | |
941 // N = ((buf[11] & 0x0F) << 4) + buf[12] + 16 + 1; | |
942 N = ((buf[11] & 0x0F) << 8) + buf[12] + 12 + 1; | |
943 // printf("NAll[%d] N[%d]\n", Nall, N); | |
944 | |
945 // ECM | |
946 //int p = 17; | |
947 int p = 13; | |
948 while(p < N) { | |
949 if ( p > size -4) { | |
950 break; | |
951 } | |
952 uint32_t cat_pid; | |
953 uint32_t tag; | |
954 uint32_t len; | |
955 | |
956 tag = buf[p]; | |
957 len = buf[p+1]; | |
958 p += 2; | |
959 | |
960 if(tag == 0x09 && len >= 4 && p+len <= N) { | |
961 // ca_pid = ((buf[p+2] << 8) | buf[p+3]) & 0x1fff; | |
962 cat_pid = (AV_RB16(buf+p+2)) & 0x1fff; | |
963 sp->pids[cat_pid] = 1; | |
964 sp->cat_pids[cat_pid] = 1; | |
965 sp->pid_sid_table[cat_pid] = sid; /* CATも複数ServiceIDで重複がある */ | |
966 #ifdef PmtDebug | |
967 fprintf(stderr, " CAT PacketID[%d][0x%04x]\n", cat_pid, cat_pid); | |
968 #endif | |
969 } | |
970 p += len; | |
971 } | |
972 | |
973 /* | |
974 * ISO/IEC 13818-1:2000(E) Table 2-29 - Stream type assignments | |
975 * Value Desctiption | |
976 * 0x00 ITU-T | ISO/IEC Reserved | |
977 * 0x01 ISO/IEC 11172 Video | |
978 * 0x02 ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream | |
979 * 0x03 ISO/IEC 11172 Audio | |
980 * 0x04 ISO/IEC 13818-3 Audio | |
981 * 0x05 ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private_sections | |
982 * 0x06 ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing private data | |
983 * 0x07 ISO/IEC 13522 MHEG | |
984 * 0x08 ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Annex A DSM-CC | |
985 * 0x09 ITU-T Rec. H.222.1 | |
986 * 0x0A ISO/IEC 13818-6 type A | |
987 * 0x0B ISO/IEC 13818-6 type B | |
988 * 0x0C ISO/IEC 13818-6 type C | |
989 * 0x0D ISO/IEC 13818-6 type D | |
990 * 0x0E ITU-T Rec. H.222.0 | ISO/IEC 13818-1 auxiliary | |
991 * 0x0F ISO/IEC 13818-7 Audio with ADTS transport syntax | |
992 * 0x10 ISO/IEC 14496-2 Visual | |
993 * 0x11 ISO/IEC 14496-3 Audio with the LATM transport syntax as defined in ISO/IEC 14496-3 / AMD 1 | |
994 * 0x12 ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in PES packets | |
995 * 0x13 ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in ISO/IEC14496_sections. | |
996 * 0x14 ISO/IEC 13818-6 Synchronized Download Protocol | |
997 * 0x15-0x7F ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Reserved | |
998 * 0x80-0xFF User Private | |
999 * | |
1000 */ | |
1001 | 746 |
1002 // ES PID | 747 // ES PID |
1003 while (N < Nall + 8 - 4) { | 748 while (N <= Nall + payload_offset - 5) |
1004 av_flag = 0; | 749 { |
1005 // ストリーム種別が 0x0D(type D)は出力対象外 | 750 // ストリーム種別が 0x0D(type D)は出力対象外 |
1006 if (0x0D != buf[N]) { | 751 if (0x0D != buf[N]) |
752 { | |
1007 epid = GetPid(&buf[N + 1]); | 753 epid = GetPid(&buf[N + 1]); |
1008 sp->pids[epid] = 1; | 754 sp->pids[epid] = mark; |
1009 sp->pid_sid_table[epid] = sid; | 755 } |
1010 if ( buf[N] == 0x02 ) { /* 13818-2 Video */ | |
1011 sp->program[sid].video[sp->program[sid].video_nb] = epid; | |
1012 sp->program[sid].video_nb += 1; | |
1013 av_flag = TSS_STREAM_TYPE_VIDEO; | |
1014 #ifdef PmtDebug | |
1015 fprintf(stderr, " VIDEO PacketID[%d][0x%04x] StreamType[0x%02x]\n", epid, epid, buf[N]); | |
1016 #endif | |
1017 } else if ( (buf[N] == 0x04) || (buf[N] == 0x0f) ) { | |
1018 /* 13818-3 Audio or 13818-7 Audio with ADTS transport syntax */ | |
1019 sp->program[sid].audio[sp->program[sid].audio_nb] = epid; | |
1020 sp->program[sid].audio_nb += 1; | |
1021 av_flag = TSS_STREAM_TYPE_AUDIO; | |
1022 #ifdef PmtDebug | |
1023 fprintf(stderr, " AUDIO PacketID[%d][0x%04x] StreamType[0x%02x]\n", epid, epid, buf[N]); | |
1024 #endif | |
1025 } else { | |
1026 #ifdef PmtDebug | |
1027 fprintf (stderr, " OTHER PacketID[%d][0x%04x] StreamType[0x%02x]\n", epid, epid, buf[N]); | |
1028 #endif | |
1029 ; /* A/V どちらでもないものはとりあえずスルー */ | |
1030 } | |
1031 if ( av_flag && sp->esout ) { | |
1032 /* ESバッファはNULLか? */ | |
1033 if ( sp->esbuf[epid] == NULL ) { | |
1034 sp->esbuf[epid] = malloc(sizeof(splitesbuf_t)); | |
1035 if ( sp->esbuf[epid] == NULL ) { | |
1036 fprintf(stderr, "malloc error\n"); | |
1037 return TSS_NULL; | |
1038 } | |
1039 sp->esbuf[epid]->size = 0; | |
1040 sp->esbuf[epid]->Program = &(sp->program[sid]); | |
1041 sp->esbuf[epid]->fd = -1; | |
1042 if ( creat_es_file(sp, sid, epid, av_flag) ) { | |
1043 return TSS_ERROR; | |
1044 } | |
1045 } | |
1046 /* PESバッファはNULLか? */ | |
1047 if ( sp->pesbuf[epid] == NULL ) { | |
1048 sp->pesbuf[epid] = malloc(sizeof(splitpesbuf_t)); | |
1049 if ( sp->pesbuf[epid] == NULL ) { | |
1050 fprintf(stderr, "malloc error\n"); | |
1051 return TSS_NULL; | |
1052 } | |
1053 sp->pesbuf[epid]->size = 0; | |
1054 sp->pesbuf[epid]->Program = &(sp->program[sid]); | |
1055 } | |
1056 } | |
1057 } | |
1058 // N += 4 + (((buf[N + 3]) & 0x0F) << 4) + buf[N + 4] + 1; | |
1059 N += 4 + (((buf[N + 3]) & 0x0F) << 8) + buf[N + 4] + 1; | 756 N += 4 + (((buf[N + 3]) & 0x0F) << 8) + buf[N + 4] + 1; |
1060 } | 757 retry_count++; |
1061 #ifdef PmtDebug | 758 if(retry_count > Nall) { |
1062 printf("AnalyzePmt finish.\n"); | 759 return TSS_ERROR; |
1063 #endif | 760 } |
1064 return TSS_SUCCESS; | 761 } |
762 sp->section_remain[pid] -= Nall; | |
763 | |
764 if (sp->section_remain[pid] > 0) | |
765 return SECTION_CONTINUE; | |
766 else | |
767 return TSS_SUCCESS; | |
1065 } | 768 } |
1066 | 769 |
1067 /** | 770 /** |
1068 * CRC 計算 | 771 * CRC 計算 |
1069 */ | 772 */ |
1082 char x; | 785 char x; |
1083 x = data[i]; | 786 x = data[i]; |
1084 | 787 |
1085 for (j = 0; j < 8; j++) | 788 for (j = 0; j < 8; j++) |
1086 { | 789 { |
1087 | |
1088 bit = (x >> (7 - j)) & 0x1; | 790 bit = (x >> (7 - j)) & 0x1; |
1089 | |
1090 c = 0; | 791 c = 0; |
1091 if (crc & 0x80000000) | 792 if (crc & 0x80000000) |
1092 { | 793 { |
1093 c = 1; | 794 c = 1; |
1094 } | 795 } |
1095 | |
1096 crc = crc << 1; | 796 crc = crc << 1; |
1097 | |
1098 if (c ^ bit) | 797 if (c ^ bit) |
1099 { | 798 { |
1100 crc ^= 0x04C11DB7; | 799 crc ^= 0x04C11DB7; |
1101 } | 800 } |
1102 | |
1103 crc &= 0xFFFFFFFF; | 801 crc &= 0xFFFFFFFF; |
1104 } | 802 } |
1105 } | 803 } |
1106 | 804 |
1107 return crc; | 805 return crc; |
1113 static int GetPid( | 811 static int GetPid( |
1114 unsigned char* data) // [in] 取得対象データのポインタ | 812 unsigned char* data) // [in] 取得対象データのポインタ |
1115 { | 813 { |
1116 return ((data[0] & 0x1F) << 8) + data[1]; | 814 return ((data[0] & 0x1F) << 8) + data[1]; |
1117 } | 815 } |
1118 | |
1119 /* return the 90kHz PCR and the extension for the 27MHz PCR. return | |
1120 (-1) if not available */ | |
1121 static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, | |
1122 const uint8_t *packet) | |
1123 { | |
1124 int afc, len, flags; | |
1125 const uint8_t *p; | |
1126 unsigned int v; | |
1127 | |
1128 afc = (packet[3] >> 4) & 3; | |
1129 if (afc <= 1) | |
1130 return -1; | |
1131 p = packet + 4; | |
1132 len = p[0]; | |
1133 p++; | |
1134 if (len == 0) | |
1135 return -1; | |
1136 flags = *p++; | |
1137 len--; | |
1138 if (!(flags & 0x10)) | |
1139 return -1; | |
1140 if (len < 6) | |
1141 return -1; | |
1142 v = AV_RB32(p); | |
1143 *ppcr_high = ((int64_t)v << 1) | (p[4] >> 7); | |
1144 *ppcr_low = ((p[4] & 1) << 8) | p[5]; | |
1145 return 0; | |
1146 } | |
1147 | |
1148 /* pesbufが空か判定 (ret. 0:not empty / 1: empty) */ | |
1149 static int pesbuf_empty(splitpesbuf_t *pesbuf){ | |
1150 return pesbuf->size == 0; | |
1151 } | |
1152 | |
1153 /* pesbufをクリア */ | |
1154 void pesbuf_clear(splitpesbuf_t *pesbuf){ | |
1155 pesbuf->size = 0; | |
1156 } | |
1157 | |
1158 /* pesbufにデータを追加 (ret. 0:success / -1:error) */ | |
1159 static int pesbuf_add(splitpesbuf_t *pesbuf, const uint8_t *data, int len){ | |
1160 if(pesbuf->size + len > sizeof pesbuf->buffer){ | |
1161 return -1; | |
1162 } | |
1163 memcpy(pesbuf->buffer +pesbuf->size, data, len); | |
1164 pesbuf->size += len; | |
1165 return 0; | |
1166 } | |
1167 | |
1168 /* pesbufから、PESの先頭(packet_start_code_prefix)を探す */ | |
1169 /* (ret. >=0:offset / -1: error) */ | |
1170 static int pesbuf_packet_start_code_prefix(splitpesbuf_t *pesbuf){ | |
1171 uint8_t packet_start_code_prefix[3] = {0x00, 0x00, 0x01}; | |
1172 int i = 0; | |
1173 | |
1174 /* 小さすぎる */ | |
1175 if(pesbuf->size < sizeof packet_start_code_prefix){ | |
1176 return -1; | |
1177 } | |
1178 /* 先頭で探す */ | |
1179 if(!memcmp(pesbuf->buffer + i, packet_start_code_prefix, sizeof packet_start_code_prefix)){ | |
1180 return 0; | |
1181 } | |
1182 | |
1183 #if 0 | |
1184 /* 先頭以外からも探す場合は、ここのコードを有効化する。 */ | |
1185 /* ただし、MPEG-Videoのstart_codeと同じなので、深追いしない方がいいと思う... */ | |
1186 for(i = 0; i < pesbuf->size - sizeof packet_start_code_prefix; i++){ | |
1187 if(!memcmp(pesbuf->buffer + i, packet_start_code_prefix, sizeof packet_start_code_prefix)){ | |
1188 return i; | |
1189 } | |
1190 } | |
1191 #endif | |
1192 | |
1193 return -1; | |
1194 } | |
1195 | |
1196 /** | |
1197 * TSの解析とDemuxを行う | |
1198 */ | |
1199 static int DemuxTs(const uint8_t *packet, splitter *sp, const int pid) | |
1200 { | |
1201 /* | |
1202 * PES先頭までの長さは | |
1203 * 4byte : continity counter | |
1204 * 27,28bit が adaptation fileld制御 | |
1205 * (01:ペイロードのみ, 10:adaptation fileldのみ、11:adaptation fileld+payload、00:reserved) | |
1206 * ペイロード長 = 188 - TS header(4byte) -adaptation field長 -1 | |
1207 */ | |
1208 /* ありがとう */ | |
1209 | |
1210 int payload_offset; /* ペイロードオフセット(=パケット先頭からのバイト数) */ | |
1211 int payload_length; /* ペイロード長 */ | |
1212 int pes_started; | |
1213 int adaptation_field_control; | |
1214 int payload_unit_start_indicator; | |
1215 // int random_access_indicator = 0; | |
1216 int sid = sp->pid_sid_table[pid]; /* SIDをPIDから引いているが、PCRとCATは重複しているので注意*/ | |
1217 | |
1218 payload_offset = LENGTH_TS_HEADER; | |
1219 | |
1220 if ( sp->pesbuf[pid] == NULL ) { | |
1221 pes_started = 0; /* malloc走る前(セクション解析だったら呼んで良い) */ | |
1222 } else { | |
1223 pes_started = !pesbuf_empty(sp->pesbuf[pid]); /* PES蓄積開始済み */ | |
1224 } | |
1225 | |
1226 /* adaptation_field_controlおよびadaptation_fieldを処理する */ | |
1227 adaptation_field_control = (packet[3] & 0x30) >> 4; | |
1228 if ( adaptation_field_control == 0x02 || adaptation_field_control == 0x00) { | |
1229 /* ペイロードなしの場合 */ | |
1230 return 0; /* 別にエラーではない */ | |
1231 } else if ( adaptation_field_control == 0x03 ) { | |
1232 /* アダプテーションフィールド+ペイロードの場合 */ | |
1233 if ( packet[LENGTH_TS_HEADER] != 0 ) { | |
1234 // random_access_indicator = (packet[5] & 0x40) >> 6; | |
1235 } | |
1236 /* ペイロード開始位置 = TSヘッダ長 + アダプテーションフィールド長 + 1 */ | |
1237 payload_offset += packet[LENGTH_TS_HEADER] + 1; | |
1238 } else { | |
1239 /* ペイロードのみ */ | |
1240 ; /* 特に処理なし */ | |
1241 } | |
1242 | |
1243 /* ペイロード長を出す */ | |
1244 payload_length = LENGTH_PACKET - payload_offset; | |
1245 if( payload_length <= 0 ){ /* payload長が0以下の場合 */ | |
1246 return -1; /* エラーにすべきかは微妙なところ */ | |
1247 } | |
1248 | |
1249 /* payload_unit_start_indicatorを処理(1) */ | |
1250 payload_unit_start_indicator = (packet[1] & 0x40) >> 6; | |
1251 /* (sectionの場合は、ここでpointer_fieldの処理などを行い、payload_offsetに反映する) */ | |
1252 if ( sp->pmt_pids[pid] == 2 ) { /* PID が録画対象の PMT であるか? */ | |
1253 if ( get_pmt_version(packet+payload_offset) != sp->program[sid].pmt_version ) { | |
1254 /* pmt versionに差分あり */ | |
1255 fprintf(stderr, "pmt version diff found pmt_pid[%d]" | |
1256 " old_version[0x%02x]" | |
1257 " new_version[0x%02x].\n", | |
1258 pid, | |
1259 sp->program[sid].pmt_version, | |
1260 get_pmt_version(packet+payload_offset)); | |
1261 AnalyzePmt(sp, packet +payload_offset, sid, payload_length); | |
1262 /* payload 何byte処理したか等管理するべき */ | |
1263 } | |
1264 return 0; /* PMT の場合は処理終わり */ | |
1265 } | |
1266 if ( !sp->esout ) { | |
1267 /* ES出力しない場合はPES蓄積不要 */ | |
1268 return 0; | |
1269 } | |
1270 if ( sp->cat_pids[pid] == 1 ) { | |
1271 return 0; /* CATは蓄積しない */ | |
1272 } | |
1273 if ( sp->pesbuf[pid] == NULL ) { | |
1274 /* PES蓄積不要である場合も蓄積しない */ | |
1275 return 0; | |
1276 } | |
1277 | |
1278 /* payload_unit_start_indicatorを処理(2) */ | |
1279 /* 必要に応じ、蓄積済みPESの処理と、PES蓄積開始を行う */ | |
1280 if( payload_unit_start_indicator ){ | |
1281 /* PES開始 */ | |
1282 if ( pes_started ) { | |
1283 /* バッファにデータがあればPES終端なので処理してクリア */ | |
1284 // pes2es(sp->pesbuf[pid], sp->esbuf[pid], pid, random_access_indicator); | |
1285 pes2es(sp->pesbuf[pid], sp->esbuf[pid], pid); | |
1286 pesbuf_clear(sp->pesbuf[pid]); | |
1287 } | |
1288 else { | |
1289 pes_started = 1; | |
1290 } | |
1291 } | |
1292 | |
1293 /* PES蓄積処理 */ | |
1294 if ( pes_started ){ | |
1295 /* PES蓄積開始済み(これからPES蓄積開始を含む)なら、payloadをPESとして追加 */ | |
1296 pesbuf_add(sp->pesbuf[pid], packet + payload_offset, payload_length); | |
1297 } | |
1298 /* おつかれさまでした */ | |
1299 return 0; | |
1300 } | |
1301 | |
1302 #if 0 | |
1303 未使用なため削除 | |
1304 /* PMT_PID から Program(Service ID)を確定させる */ | |
1305 static int search_pmt_program(splitter *sp, int pid) | |
1306 { | |
1307 /* この関数は大変遅いのでなるべく使用しない */ | |
1308 int i; | |
1309 for ( i = 0; i < MAX_SERVICE_ID; i++ ) { | |
1310 if ( sp->program[i].pmt_packet_id == pid ) { | |
1311 return i; | |
1312 } | |
1313 } | |
1314 return -1; | |
1315 } | |
1316 #endif | |
1317 | |
1318 /* esbufが空か判定 (ret. 0:not empty / 1: empty) */ | |
1319 static int esbuf_empty(splitesbuf_t *esbuf){ | |
1320 return esbuf->size == 0; | |
1321 } | |
1322 | |
1323 /* esbufをクリア */ | |
1324 void esbuf_clear(splitesbuf_t *esbuf, uint64_t pts, uint64_t dts){ | |
1325 esbuf->size = 0; | |
1326 esbuf->pts = pts; | |
1327 esbuf->dts = dts; | |
1328 } | |
1329 | |
1330 /* esbufにデータを追加 (ret. 0:success / -1:error) */ | |
1331 static int esbuf_add(splitesbuf_t *esbuf, const uint8_t *data, int len){ | |
1332 if(esbuf->size + len > sizeof esbuf->buffer){ | |
1333 return -1; | |
1334 } | |
1335 memcpy(esbuf->buffer +esbuf->size, data, len); | |
1336 esbuf->size += len; | |
1337 return 0; | |
1338 } | |
1339 | |
1340 /* | |
1341 * PESを解析してESを出力する | |
1342 */ | |
1343 //static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid, int random_access_indicator) | |
1344 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid) | |
1345 { | |
1346 int len_pesh = 0; | |
1347 int code = 0; | |
1348 int flags = 0; | |
1349 int len_pes = 0; | |
1350 int len_pesh_supposed = 0; | |
1351 int pes_extension_flags = 0; | |
1352 int pes_extension_flags2 = 0; | |
1353 int program_packet_sequence_counter_flag = 0; | |
1354 int es_rate = 0; | |
1355 const uint8_t *p = pesbuf->buffer; | |
1356 const uint8_t *p_end = pesbuf->buffer +pesbuf->size; | |
1357 int original_stuffing_length = 0; | |
1358 int data_alignment_indicator = false; | |
1359 int es_started; | |
1360 int payload_offset = 0; | |
1361 int payload_length = 0; | |
1362 int audio_lipsync_offset = 0; | |
1363 int i = 0; | |
1364 int64_t audio_pts = 0; | |
1365 int adts_freq = 0; | |
1366 int64_t adts_frame_time = 0; | |
1367 int gop_start = -1; | |
1368 | |
1369 /* ありがとう */ | |
1370 /* ありがとうとコメントを書くと、 | |
1371 * 動作がよくなる | |
1372 * バグが減る | |
1373 * バイナリサイズが小さくなる | |
1374 * 画質がよくなる | |
1375 * 音質がよくなる | |
1376 */ | |
1377 if ( esbuf == NULL ) { | |
1378 return -1; /* malloc走る前この関数は呼んじゃダメです */ | |
1379 } else { | |
1380 es_started = !esbuf_empty(esbuf); /* ES蓄積開始済み */ | |
1381 } | |
1382 | |
1383 payload_offset = pesbuf_packet_start_code_prefix(pesbuf); | |
1384 if ( payload_offset == -1 ) { | |
1385 return -1; | |
1386 } | |
1387 p += payload_offset; | |
1388 /* http://dvd.sourceforge.net/dvdinfo/pes-hdr.html | |
1389 * | |
1390 * Stream ID : type : extension present? | |
1391 * (1011 1101) 0xBD : Private stream 1 (non MPEG audio, subpictures) : YES | |
1392 * (1011 1110) 0xBE : Padding stream : NO | |
1393 * (1011 1111) 0xBF : Private stream 2 (navigation data) : NO | |
1394 * (110x xxxx) 0xC0 - 0xDF : MPEG-1 or MPEG-2 audio stream number x xxxx : YES | |
1395 * (1110 xxxx) 0xE0 - 0xEF : MPEG-1 or MPEG-2 video stream number xxxx : YES | |
1396 * note: DVD allows only 8 audio streams/DVD allows only 1 video stream | |
1397 */ | |
1398 /* http://www2.arib.or.jp/johomem/pdf/2009/2009_0088.pdf | |
1399 * | |
1400 * 0xBC : プログラムストリームマップ | |
1401 * 0xBD : プライベートストリーム1 | |
1402 * 0xBE : パディングストリーム | |
1403 * 0xBF : プライベートストリーム2 | |
1404 * 0xC0 - 0xDF : ISO/IEC 13318 3、ISO/IEC 11172 3、ISO/IEC 13318 7 or ISO/IEC 14496 3 audio xxxx | |
1405 * 0xE0 - 0xEF : ITU-T H.262、ISO/IEC 11172 2、ISO/IEC 14496 2 or ITU-T H264映像ストリーム | |
1406 * 0xF0 : ECMストリーム | |
1407 * 0xF1 : EMMストリーム | |
1408 * 0xF2 : ITU-T勧告H.222.0 Annex A 又は ISO/IEC 13318 6 のDSMCCストリーム | |
1409 * 0xF3 : ISO/IEC 13522ストリーム | |
1410 * 0xF4 : ITU-T勧告 H.222.1 type A | |
1411 * 0xF5 : ITU-T勧告 H.222.1 type B | |
1412 * 0xF6 : ITU-T勧告 H.222.1 type C | |
1413 * 0xF7 : ITU-T勧告 H.222.1 type D | |
1414 * 0xF8 : ITU-T勧告 H.222.1 type E | |
1415 * 0xF9 : 補助ストリーム | |
1416 * 0xFA : ISO/IEC 14496 1SLパケット化ストリーム | |
1417 * 0xFB : ISO/IEC 14496 1フレックスマックスストリーム | |
1418 * 0xFC : メタデータストリーム | |
1419 * 0xFD : 拡張ストリームID | |
1420 * 0xFE : 未定義 | |
1421 * 0xFF : プログラムストリームディレクトリ | |
1422 */ | |
1423 /* 上記より、ここでは | |
1424 * MPEG-1 or MPEG-2 audio stream と | |
1425 * MPEG-1 or MPEG-2 video stream と | |
1426 * Private stream 1 と | |
1427 * 0xFD(拡張ストリームID)を抽出する | |
1428 * ?0xBF Private stream 2 落としてるけどよいの? | |
1429 * >多分よくない。ffmpegではここに入る前に PRIVATE_STREAM2 のコードが入っている | |
1430 */ | |
1431 code = (p[3] &0xff) | 0x100; | |
1432 if ( !((code >= 0x1c0 && code <= 0x1df) || | |
1433 (code >= 0x1e0 && code <= 0x1ef) || | |
1434 (code == 0x1bd) || (code == 0x1fd))) { | |
1435 return -1; | |
1436 } | |
1437 /* PES のデータ長 */ | |
1438 /* 動画のストリームである場合には、ES長は不定となるので0が許容される */ | |
1439 len_pes = AV_RB16(p+4); | |
1440 /* PESヘッダ拡張部(byte 6) */ | |
1441 flags = p[6] & 0xff; | |
1442 if ( flags & 0x04 ) { | |
1443 data_alignment_indicator = true; | |
1444 /* data alignment indicator */ | |
1445 /* video start code or audio syncword. */ | |
1446 /* おそらくここで区切るとピクチャ単位 */ | |
1447 //printf("data alignment indicator found pid[%d].\n", pid); | |
1448 } | |
1449 flags = p[7] & 0xff; | |
1450 /* PESヘッダデータ長(byte 8) */ | |
1451 len_pesh = p[8] & 0xff; | |
1452 p += LENGTH_PES_HEADER; | |
1453 payload_offset += LENGTH_PES_HEADER +len_pesh; | |
1454 if ( p +payload_offset >= p_end ) { | |
1455 /* PESヘッダ長すぎます */ | |
1456 return -1; | |
1457 } | |
1458 | |
1459 /* flags | |
1460 * +---------------------------------------------------+ | |
1461 * name |byte 7(flags) | | |
1462 * +-----+-----+-----+------+----------+----+----------+ | |
1463 * Bit |76 |5 |4 |3 |2 |1 |0 | | |
1464 * +-----+-----+-----+------+----------+----+----------+ | |
1465 * field|PTS |ESCR |ES |DSM |additional|PES |PES | | |
1466 * name |DTS |FLAG |RATE |Trick |copy info |CRC |Extension | | |
1467 * |flag | |flag |mode |flag |flag|flag | | |
1468 * +-----+-----+-----+------+----------+----+----------+ | |
1469 * Data |5,5 |6 |3 |1 |1 |2 |1 |(24) | |
1470 * byte | | | | | | | | | |
1471 * +-----+-----+-----+------+----------+----+----------+ | |
1472 */ | |
1473 if ( flags & PTS_FLAG ) { | |
1474 if ( p +LENGTH_PTS >= p_end ) { | |
1475 return -1; | |
1476 } | |
1477 pesbuf->pts = get_pts(p); | |
1478 p += LENGTH_PTS; | |
1479 len_pesh_supposed += LENGTH_PTS; | |
1480 } | |
1481 if ( flags & DTS_FLAG ) { | |
1482 if ( p +LENGTH_PTS >= p_end ) { | |
1483 return -1; | |
1484 } | |
1485 pesbuf->dts = get_pts(p); | |
1486 p += LENGTH_PTS; | |
1487 len_pesh_supposed += LENGTH_PTS; | |
1488 } | |
1489 if ( flags & ESCR_FLAG ) { | |
1490 p += 6; | |
1491 len_pesh_supposed += 6; | |
1492 } | |
1493 if ( flags & ES_RATE_FLAG ) { | |
1494 es_rate = AV_RB24(p); | |
1495 es_rate = (es_rate >>1) & 0x3fffff; | |
1496 es_rate = es_rate * 50; | |
1497 fprintf(stderr, "pid[%d] es_rate[%d]Byte/Sec.\n", pid, es_rate); | |
1498 p += 3; | |
1499 len_pesh_supposed += 3; | |
1500 } | |
1501 if ( flags & DSM_TRICK_MODE_FLAG ) { | |
1502 p += 1; | |
1503 len_pesh_supposed += 1; | |
1504 } | |
1505 if ( flags & COPY_INFO_FLAG ) { | |
1506 p += 1; | |
1507 len_pesh_supposed += 1; | |
1508 } | |
1509 if ( flags & CRC_FLAG ) { | |
1510 p += 2; | |
1511 len_pesh_supposed += 2; | |
1512 } | |
1513 if ( flags & EXTENSION_FLAG ) { | |
1514 /* PES Extension flag | |
1515 * +------------------------------------------------------------------+ | |
1516 * name |PES Extension flag | | |
1517 * +-----------+-----------+----------------+------+---+--------------+ | |
1518 * bit |7 |6 |5 |4 |321|0 | | |
1519 * +-----------+-----------+----------------+------+---+--------------+ | |
1520 * field|PES private|pack header|program |P-STD |111|PES extension | | |
1521 * name |data flag |field flag |packet |buffer| |flag2 | | |
1522 * | | |sequence counter|flag | | | | |
1523 * +-----------+-----------+----------------+------+---+--------------+ | |
1524 * Data |16 |1 |2 |2 | |1 |(23) | |
1525 * byte | | | | | | | | |
1526 * +-----------+-----------+----------------+------+---+--------------+ | |
1527 */ | |
1528 if ( p >= p_end ) { | |
1529 return -1; | |
1530 } | |
1531 pes_extension_flags = *p & 0xff; | |
1532 p += 1; | |
1533 len_pesh_supposed += 1; | |
1534 if ( pes_extension_flags & PES_PRIVATE_DATA_FLAG ) { | |
1535 p += 16; | |
1536 len_pesh_supposed += 16; | |
1537 } | |
1538 if ( pes_extension_flags & PACK_HEADER_FIELD_FLAG ) { | |
1539 p += 1; | |
1540 len_pesh_supposed += 1; | |
1541 } | |
1542 if ( pes_extension_flags & PROGRAM_PACKET_SEQUENCE_COUNTER ) { | |
1543 if ( p >= p_end ) { | |
1544 return -1; | |
1545 } | |
1546 program_packet_sequence_counter_flag = *p & 0xff; | |
1547 original_stuffing_length = program_packet_sequence_counter_flag & 0x3f; | |
1548 p += 2; | |
1549 len_pesh_supposed += 2; | |
1550 } | |
1551 if ( pes_extension_flags & PSTD_BUFFER_FLAG ) { | |
1552 p += 2; | |
1553 len_pesh_supposed += 2; | |
1554 } | |
1555 if ( pes_extension_flags & PES_EXTENSION_FLAG2 ) { | |
1556 /* PES Extension flag2 | |
1557 * +------------------------------------------------------------------+ | |
1558 * name |PES Extension flag2 | | |
1559 * +------+-----------------------------------------------------------+ | |
1560 * bit |7 |6543210 | | |
1561 * +------+-----------------------------------------------------------+ | |
1562 * field|marker|PES_extension_field_length | | |
1563 * name |bit | | | |
1564 * |'1' | | | |
1565 * +------+-----------------------------------------------------------+ | |
1566 * Data |- |0 <= N <= 127 |(127) | |
1567 * byte | | | | |
1568 * +------+-----------------------------------------------------------+ | |
1569 */ | |
1570 if ( p >= p_end ) { | |
1571 return -1; | |
1572 } | |
1573 pes_extension_flags2 = *p & 0x7f; | |
1574 p += 1; | |
1575 len_pesh_supposed += 1; | |
1576 | |
1577 p += pes_extension_flags2; | |
1578 len_pesh_supposed += pes_extension_flags2; | |
1579 } | |
1580 } | |
1581 if ( pid != 6417 && pid != 6418 ) { | |
1582 // printf("es start? pid[%d]\n", pid); | |
1583 } | |
1584 /* ES蓄積管理処理 */ | |
1585 payload_length = pesbuf->size -payload_offset; | |
1586 // if ( data_alignment_indicator ) { /* data_alignment_indicator 区切りでESを出力する */ | |
1587 if ( es_started ) { /* ES にデータが蓄積されている */ | |
1588 /* | |
1589 * ビデオをファイル出力し始める条件(1. 2. を満たすこと) | |
1590 * 1. ESにGOP先頭を含む | |
1591 * 2. PTSがCUEの時刻を過ぎていること( CUE <= PTS ) | |
1592 */ | |
1593 if ( (is_video_stream(pid, esbuf) == 0) && !(esbuf->started) ) { | |
1594 /* VIDEO0 を同期の基準とする */ | |
1595 gop_start = search_gop_start_code(esbuf); | |
1596 if ( (gop_start != -1) && /* ESバッファにGOP_START_CODEが存在するか? */ | |
1597 (esbuf->Program->cue <= esbuf->pts*300) ) { /* CUEを過ぎている? */ | |
1598 /* 該当ストリームをファイル出力開始する */ | |
1599 esbuf->started = 1; | |
1600 esbuf->Program->video_start = 1; | |
1601 esbuf->Program->video_pts = esbuf->pts; | |
1602 fprintf(stderr, "video stream. pid[%d] v_pts[%llu].\n", pid, esbuf->pts); | |
1603 } else { | |
1604 /* GOP先頭を含まないものはクリア */ | |
1605 esbuf_clear(esbuf, pesbuf->pts, pesbuf->dts); | |
1606 } | |
1607 } else if ( (is_video_stream(pid, esbuf) != -1) && !(esbuf->started) ) { | |
1608 /* VIDEO0 以外のものはVIDEO0 が開始するまでクリア */ | |
1609 if ( !(esbuf->Program->video_start) ) { | |
1610 /* | |
1611 * VIDEO0 が始まってない場合、 | |
1612 * VIDEON は常にクリア | |
1613 */ | |
1614 esbuf_clear(esbuf, pesbuf->pts, pesbuf->dts); | |
1615 } else { | |
1616 /* | |
1617 * VIDEO0 が始まっている場合、 | |
1618 * VIDEON の録画を開始 | |
1619 */ | |
1620 esbuf->started = 1; | |
1621 } | |
1622 } | |
1623 /* | |
1624 * オーディオをファイル出力し始める条件(1. 2. を満たすこと) | |
1625 * 1. 動画の蓄積は開始されている | |
1626 * 2. 動画のGOPの1番目のIピクチャのPTSとオーディオのPTSを比較して以下のどちらかを満たすこと | |
1627 * 2.1. 差分が11msec以内(1024*90k/AACのサンプリング周波数) | |
1628 * 1024 : ADTSデータの1フレームのサンプル数 | |
1629 * 90k : PTSの周波数 | |
1630 * 2.2. 過ぎている(過ぎている場合はオーディオESの蓄積の継続と次のGOP狙いにする?) | |
1631 * #動画よりオーディオ側の方が先にESバッファの蓄積を始めるハズなので気にすること無いかなぁ… | |
1632 */ | |
1633 else if ( (is_audio_stream(pid, esbuf) != -1) && !(esbuf->started) ) { | |
1634 if ( !(esbuf->Program->video_start) ) { | |
1635 /* | |
1636 * VIDEO が始まってない場合、 | |
1637 * ESバッファの余裕がある限り、オーディオをESバッファに蓄積し続ける | |
1638 */ | |
1639 if ( esbuf->size + payload_length > sizeof esbuf->buffer ){ | |
1640 /* 溢れそうになったらクリア */ | |
1641 esbuf_clear(esbuf, pesbuf->pts, pesbuf->dts); | |
1642 } | |
1643 } else if ( esbuf->Program->video_start ) { /* video 蓄積が開始されている?*/ | |
1644 fprintf(stderr, "audio stream. pid[%d] a_pts[%llu] v_pts[%llu] size[%d].\n", pid, esbuf->pts, esbuf->Program->video_pts, esbuf->size); | |
1645 audio_lipsync_offset = 0; | |
1646 audio_pts = esbuf->pts; | |
1647 adts_freq = AnalyzeAdifHeader(esbuf); | |
1648 adts_frame_time = (int64_t)((float)1024*90000/adts_freq); /* PTSは90KHz */ | |
1649 /* オーディオをフレーム単位で捨ててPTSを進める */ | |
1650 while ( (esbuf->Program->video_pts > audio_pts +adts_frame_time/2) ) { | |
1651 /* オーディオデータを捨てると audio_pts は1フレーム分大きくなる */ | |
1652 i = next_adts_start_code(esbuf, audio_lipsync_offset); /* 次のAACのデータを取得 */ | |
1653 if ( i != -1 ) { /* AACデータの終端か? */ | |
1654 audio_lipsync_offset += i; | |
1655 } else { | |
1656 /* バッファ終端まで進めたが、オーディオPTSの方が古い場合ESバッファはクリアする */ | |
1657 esbuf_clear(esbuf, pesbuf->pts, pesbuf->dts); | |
1658 break; | |
1659 } | |
1660 fprintf(stderr, "audio stream drop. pid[%d] pts[%llu].\n", pid, audio_pts); | |
1661 audio_pts += adts_frame_time; /* AACの1フレーム分、時間を進める */ | |
1662 } | |
1663 if ( (esbuf->Program->video_pts <= audio_pts +adts_frame_time/2) ) { | |
1664 fprintf(stderr, "lipsync start. v_pts[%llu] a_pts[%llu].\n", esbuf->Program->video_pts, audio_pts); | |
1665 memmove(esbuf->buffer +audio_lipsync_offset, | |
1666 esbuf->buffer, | |
1667 esbuf->size -audio_lipsync_offset); | |
1668 esbuf->size -= audio_lipsync_offset; | |
1669 esbuf->started = 1; /* オーディオのファイル出力を有効化 */ | |
1670 } | |
1671 } else { | |
1672 ; /* 該当するものは無いはず */ | |
1673 } | |
1674 } else { | |
1675 /* 得に処理なし */ | |
1676 ; | |
1677 } | |
1678 /* バッファをファイルに出力してクリア */ | |
1679 if ( esbuf->started ) { /* 該当ストリームはファイル出力の有効化をされている? */ | |
1680 esbuf_write(esbuf); | |
1681 esbuf_clear(esbuf, pesbuf->pts, pesbuf->dts); | |
1682 } | |
1683 } else { | |
1684 /* ES蓄積を新たに開始 */ | |
1685 es_started = 1; | |
1686 esbuf->pts = pesbuf->pts; | |
1687 esbuf->dts = pesbuf->dts; | |
1688 } | |
1689 //} | |
1690 | |
1691 /* ES蓄積処理 */ | |
1692 if ( es_started ) { | |
1693 /* ES蓄積開始済み(これからES蓄積開始を含む)なら、payloadをESとして追加 */ | |
1694 esbuf_add(esbuf, pesbuf->buffer +payload_offset, payload_length); | |
1695 } | |
1696 /* お疲れさまでした */ | |
1697 return 0; | |
1698 } | |
1699 | |
1700 /* Program の N 番目の AUDIO STREAM であるかを返却する */ | |
1701 static int is_audio_stream(const int pid, splitesbuf_t *esbuf) | |
1702 { | |
1703 int i = 0; | |
1704 program_t* program = esbuf->Program; | |
1705 while (i < program->audio_nb) | |
1706 { | |
1707 if (program->audio[i] == pid) { | |
1708 return i; | |
1709 } | |
1710 i++; | |
1711 } | |
1712 return -1; | |
1713 } | |
1714 | |
1715 /* Program の N 番目の VIDEO STREAM であるかを返却する */ | |
1716 static int is_video_stream(const int pid, splitesbuf_t *esbuf) | |
1717 { | |
1718 int i = 0; | |
1719 program_t* program = esbuf->Program; | |
1720 while (i < program->video_nb) | |
1721 { | |
1722 if (program->video[i] == pid) { | |
1723 return i; | |
1724 } | |
1725 i++; | |
1726 } | |
1727 return -1; | |
1728 } | |
1729 | |
1730 /* | |
1731 * ESをファイル出力する | |
1732 * エラーハンドリングしてないね… | |
1733 */ | |
1734 static int esbuf_write(splitesbuf_t *esbuf) | |
1735 { | |
1736 int remain = esbuf->size; | |
1737 while(remain > 0) | |
1738 { | |
1739 remain -= write(esbuf->fd, esbuf->buffer+(esbuf->size-remain), remain); | |
1740 } | |
1741 return 0; | |
1742 } | |
1743 | |
1744 #if 0 | |
1745 未使用なため駆除 | |
1746 /* | |
1747 * packet dump | |
1748 */ | |
1749 void dump_packet( const uint8_t *packet ) | |
1750 { | |
1751 int i = 0; | |
1752 uint8_t *p = (uint8_t*)packet; | |
1753 char tmp[17]; | |
1754 | |
1755 printf("HEADER 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F <ASCII>\n"); | |
1756 while(i < LENGTH_PACKET) { | |
1757 if ( (i%16) == 0 ) { | |
1758 printf("0x%04X ", i); | |
1759 } | |
1760 printf("%02x ", *(p+i)); | |
1761 if ( isprint(*(p+i)) ){ | |
1762 tmp[i%16] = *(p+i); | |
1763 } | |
1764 else { | |
1765 tmp[i%16] = '.'; | |
1766 } | |
1767 if ((i%16) == 15) { | |
1768 tmp[sizeof(tmp)-1] = '\0'; | |
1769 printf(" %s\n", tmp); | |
1770 } | |
1771 i++; | |
1772 } | |
1773 putchar('\n'); | |
1774 } | |
1775 #endif | |
1776 | |
1777 /* | |
1778 * TOT の JST_time を解析する | |
1779 */ | |
1780 static int parse_tot( const unsigned char* packet, time_t *t ) | |
1781 { | |
1782 /* 注意事項 | |
1783 * 本当は TOT が有効かどうかをチェックするべきですがしていません | |
1784 * サマータイム関係は無視しています | |
1785 */ | |
1786 struct tm tm; | |
1787 time_t t2; | |
1788 int k; | |
1789 uint8_t *p = (uint8_t*)packet; | |
1790 unsigned int MJD; | |
1791 tm.tm_wday = 0; | |
1792 tm.tm_yday = 0; | |
1793 tm.tm_isdst = 0; | |
1794 | |
1795 p += 8; | |
1796 MJD = (*(p) & 0xff) <<8; | |
1797 p++; | |
1798 MJD |= *(p) & 0xff; | |
1799 | |
1800 /* ARIB STD-B10 第2部 付録C の公式より MJD to YYYYMMDD */ | |
1801 tm.tm_year = (int)floor((MJD - 15078.2)/365.25); | |
1802 tm.tm_mon = (int)floor((MJD - 14956.1 - floor(tm.tm_year * 365.25))/30.6001); | |
1803 tm.tm_mday = MJD - 14956 - floor(tm.tm_year * 365.25) - floor(tm.tm_mon * 30.6001); | |
1804 if ( tm.tm_mon == 14 || tm.tm_mon == 15 ) | |
1805 k = 1; | |
1806 else | |
1807 k = 0; | |
1808 tm.tm_year += k; | |
1809 tm.tm_mon = tm.tm_mon -1 - k * 12; | |
1810 tm.tm_mon--; | |
1811 | |
1812 /* HHMISSは2進化10進数 */ | |
1813 p++; | |
1814 tm.tm_hour = ((*p & 0xf0) >>4)*10 + (*p & 0x0f); | |
1815 p++; | |
1816 tm.tm_min = ((*p & 0xf0) >>4)*10 + (*p & 0x0f); | |
1817 p++; | |
1818 tm.tm_sec = ((*p & 0xf0) >>4)*10 + (*p & 0x0f); | |
1819 | |
1820 *t = mktime(&tm); | |
1821 time(&t2); | |
1822 | |
1823 return TRUE; | |
1824 } | |
1825 | |
1826 static int64_t get_pts(const uint8_t *p) | |
1827 { | |
1828 int64_t pts = (int64_t)((p[0] >> 1) & 0x07) << 30; | |
1829 pts |= (AV_RB16(p + 1) >> 1) << 15; | |
1830 pts |= AV_RB16(p + 3) >> 1; | |
1831 return pts; | |
1832 } | |
1833 | |
1834 static int get_pmt_version(const uint8_t *p) | |
1835 { | |
1836 return ((p[6] >> 1) & 0x1f); | |
1837 } | |
1838 | |
1839 #if 0 | |
1840 未使用なため駆除 | |
1841 void search_mpeg_system_header(const uint8_t *packet) | |
1842 { | |
1843 int i; | |
1844 uint8_t *p = (uint8_t*)packet; | |
1845 i = 0; | |
1846 for( i=0; i < LENGTH_PACKET-4; i++) { | |
1847 if( p[i] == 0x00 && p[i+1] == 0x00 && p[i+2] == 0x01 && p[i+3] == 0xb8 ){ | |
1848 dump_packet(packet ); | |
1849 } | |
1850 } | |
1851 } | |
1852 #endif | |
1853 | |
1854 /* | |
1855 * この関数では、現在の仕様では、先頭位置の「次の」ADTS start codeまでの長さを返却する | |
1856 * ret == 0 : 仕様上あり得ない(esbuf先頭はヘッダ先頭であるため) | |
1857 * ret > 0 : 見つかった場合 | |
1858 * ret == -1 : 見つからなかった場合 | |
1859 */ | |
1860 static int next_adts_start_code(splitesbuf_t *esbuf, int offset) | |
1861 { | |
1862 /* | |
1863 * start code prefix のうち、先頭12bit は 1 固定 | |
1864 */ | |
1865 uint16_t adts_start_code = 0xfff0; | |
1866 int i = offset +1; | |
1867 uint16_t startcode = 0; | |
1868 | |
1869 /* 小さすぎる */ | |
1870 if(esbuf->size -offset < sizeof(adts_start_code)){ | |
1871 return -1; | |
1872 } | |
1873 for(; i < esbuf->size - sizeof(adts_start_code); i++) { | |
1874 startcode = AV_RB16(esbuf->buffer+i); | |
1875 if( startcode == adts_start_code ) { /* 該当位置から12bit連続1が立っているか? */ | |
1876 return (i-offset); | |
1877 } | |
1878 } | |
1879 return -1; | |
1880 } | |
1881 | |
1882 /* ADIF HEADER解析 */ | |
1883 static int AnalyzeAdifHeader(splitesbuf_t *esbuf) | |
1884 { | |
1885 int id = 0; /* 0:MPEG-4 1:MPEG-2 */ | |
1886 int layer = 0; /* 常に 0x00 */ | |
1887 int protection_absent = 0; /* 保護属性 0:保護なし 1:保護あり */ | |
1888 int profile = 0; /* 00:MAIN 01:LC 10:SSR 11:(reserved) */ | |
1889 int sampling_frequency_index = 0; /* サンプリング周波数テーブル値 */ | |
1890 int private_bit = 0; /* private bit */ | |
1891 int channel_configuration = 0; /* チャンネル数 */ | |
1892 int original_copy = 0; | |
1893 int home = 0; /* homeってなに? */ | |
1894 int copyright_identification_bit = 0; /* 著作権証明ビット */ | |
1895 int copyright_identification_start = 0; /* 著作権証明開始ビット */ | |
1896 int aac_frame_length = 0; /* AACフレーム長 */ | |
1897 int adts_buffer_fullness = 0; /* ADTSバッファ残量 */ | |
1898 int no_raw_data_blocks_in_frame = 0; /* データブロックまでの残量 */ | |
1899 /* | |
1900 * サンプリング周波数テーブル(ヘッダのsampling_frequency_indexが添字) | |
1901 * 単位:Hz | |
1902 */ | |
1903 int sampling_frequency_table[16] = | |
1904 { | |
1905 96000, | |
1906 88200, | |
1907 64000, | |
1908 48000, | |
1909 44100, | |
1910 32000, | |
1911 24000, | |
1912 22050, | |
1913 16000, | |
1914 12000, | |
1915 11025, | |
1916 8000, | |
1917 -1, | |
1918 -1, | |
1919 -1, | |
1920 -1 | |
1921 }; | |
1922 | |
1923 uint8_t *p = esbuf->buffer; | |
1924 if ( esbuf->size < 8 ) { | |
1925 return -1; | |
1926 } | |
1927 | |
1928 id = get_adif_id(p+1); | |
1929 layer = get_adif_layer(p+1); | |
1930 protection_absent = get_adif_protection_absent(p+1); | |
1931 profile = get_adif_profile(p+2); | |
1932 sampling_frequency_index = get_adif_sampling_frequency_index(p+2); | |
1933 private_bit = get_adif_private_bit(p+2); | |
1934 channel_configuration = get_adif_channel_configuration(p+3); | |
1935 original_copy = get_adif_original_copy(p+3); | |
1936 home = get_adif_home(p+3); | |
1937 copyright_identification_bit = get_adif_copyright_idication_bit(p+3); | |
1938 copyright_identification_start = get_adif_copyright_idication_start(p+3); | |
1939 aac_frame_length = get_adif_aac_frame_length(p+3); | |
1940 adts_buffer_fullness = get_adts_buffer_fullness(p+5); | |
1941 no_raw_data_blocks_in_frame = get_adts_no_raw_data_blocks_in_frame(p+5); | |
1942 | |
1943 /* | |
1944 * とりあえず return は サンプリング周波数としておく | |
1945 * 本当は取得した情報を構造体にして返却する方がいいのだろうけど、 | |
1946 * 利用する予定もないので取得するだけにしておく | |
1947 */ | |
1948 return sampling_frequency_table[sampling_frequency_index]; | |
1949 } | |
1950 | |
1951 static int get_adif_id(uint8_t *p) | |
1952 { | |
1953 return ((*p & 0x08) >>3); | |
1954 } | |
1955 | |
1956 static int get_adif_layer(uint8_t *p) | |
1957 { | |
1958 return ((*p & 0x06) >>1); | |
1959 } | |
1960 | |
1961 static int get_adif_protection_absent(uint8_t *p) | |
1962 { | |
1963 return (*p & 0x01); | |
1964 } | |
1965 | |
1966 static int get_adif_profile(uint8_t *p) | |
1967 { | |
1968 return ((*p & 0xc0) >>6); | |
1969 } | |
1970 | |
1971 static int get_adif_sampling_frequency_index(uint8_t *p) | |
1972 { | |
1973 return ((*p & 0x3c) >>2); | |
1974 } | |
1975 | |
1976 static int get_adif_private_bit(uint8_t *p) | |
1977 { | |
1978 return ((*p & 0x02) >>1); | |
1979 } | |
1980 | |
1981 static int get_adif_channel_configuration(uint8_t *p) | |
1982 { | |
1983 return ((*p & 0x01) <<2 | (*(p+1) & 0xc0 >>6) ); | |
1984 } | |
1985 | |
1986 static int get_adif_original_copy(uint8_t *p) | |
1987 { | |
1988 return (*p & 0x20 >>5 ); | |
1989 } | |
1990 | |
1991 static int get_adif_home(uint8_t *p) | |
1992 { | |
1993 return (*p & 0x10 >>4 ); | |
1994 } | |
1995 | |
1996 static int get_adif_copyright_idication_bit(uint8_t *p) | |
1997 { | |
1998 return (*p & 0x08 >>3 ); | |
1999 } | |
2000 | |
2001 static int get_adif_copyright_idication_start(uint8_t *p) | |
2002 { | |
2003 return (*p & 0x04 >>2 ); | |
2004 } | |
2005 | |
2006 static int get_adif_aac_frame_length(uint8_t *p) | |
2007 { | |
2008 return ( ((*p & 0x02) <<11) || ((*(p+1) & 0xff) <<3) || ((*(p+2) & 0xe0) >>5) ); | |
2009 } | |
2010 | |
2011 static int get_adts_buffer_fullness(uint8_t *p) | |
2012 { | |
2013 return ( ((*p & 0x1f) <<6) || ((*(p+1) &0xfc) >>2)); | |
2014 } | |
2015 | |
2016 static int get_adts_no_raw_data_blocks_in_frame(uint8_t *p) | |
2017 { | |
2018 return (*p & 0x03); | |
2019 } | |
2020 | |
2021 #define GOP_START_CODE (0x000001b8) | |
2022 /* GOP START CODE を検索する */ | |
2023 static int search_gop_start_code(splitesbuf_t *esbuf) | |
2024 { | |
2025 uint32_t gop_start_code = GOP_START_CODE; | |
2026 int i; | |
2027 | |
2028 /* 小さすぎる */ | |
2029 if ( esbuf->size < sizeof gop_start_code ){ | |
2030 return -1; | |
2031 } | |
2032 for(i = 0; i < esbuf->size - sizeof gop_start_code; i++) { | |
2033 if ( (AV_RB32(esbuf->buffer +i)) == gop_start_code ) { | |
2034 return i; | |
2035 } | |
2036 } | |
2037 return -1; | |
2038 } | |
2039 | |
2040 /* ES 出力するファイルを作成する */ | |
2041 static int creat_es_file(splitter *sp, int sid, int pid, int av_flag) | |
2042 { | |
2043 /* | |
2044 * 出力ESファイルの命名規則は以下とする | |
2045 * | |
2046 * ファイル名のベースは --es オプションの引数 | |
2047 * 以下の形式で命名して、ファイルオープンまで実施する。 | |
2048 * ファイル名prefix_SID_AVのプログラム内番号.m2v | |
2049 * ファイル名prefix_SID_AVのプログラム内番号.aac | |
2050 * | |
2051 * !!注意!! | |
2052 * MPEG-2/MPEG-4 AAC 以外のオーディオが来た場合の処理が未実装 | |
2053 */ | |
2054 | |
2055 char filename[PATH_MAX]; | |
2056 int size = 0; | |
2057 char *suffix = NULL; | |
2058 int av_nb = 0; | |
2059 char suffix_a[] = "aac"; | |
2060 char suffix_v[] = "m2v"; | |
2061 filename[0] = '\0'; | |
2062 | |
2063 /* ちょっとこの辺のコードイケてないので後から直すかも */ | |
2064 if ( av_flag == TSS_STREAM_TYPE_VIDEO ) { | |
2065 suffix = suffix_v; | |
2066 av_nb = sp->program[sid].video_nb -1; | |
2067 } else if ( av_flag == TSS_STREAM_TYPE_AUDIO ){ | |
2068 suffix = suffix_a; | |
2069 av_nb = sp->program[sid].audio_nb -1; | |
2070 } else { | |
2071 /* ここはありえない */ | |
2072 return -1; | |
2073 } | |
2074 size = strlen(sp->filename); | |
2075 | |
2076 if ( size +16 < sizeof(filename) ) { | |
2077 snprintf(filename, sizeof(filename), "%s_%05d_%02d.%s", sp->filename, sid, av_nb, suffix); | |
2078 filename[PATH_MAX-1] = '\0'; | |
2079 } else { | |
2080 /* ファイル名つけられなくて困るでござるの巻 */ | |
2081 return -1; | |
2082 } | |
2083 umask(0133); | |
2084 if ( !(sp->esbuf[pid]->fd = open(filename, O_CREAT|O_APPEND|O_RDWR, 00644)) ) { | |
2085 fprintf(stderr, "cannot open es out file. file[%s].\n", filename); | |
2086 return -1; | |
2087 } | |
2088 return 0; | |
2089 } | |
2090 | |
2091 static time_t cue2time(char *yyyymmddhhmiss) | |
2092 { | |
2093 struct tm cue_tm; | |
2094 time_t cue_time; | |
2095 char *p; | |
2096 int i, j; | |
2097 char str_yyyy[5]; | |
2098 char str_mm[3]; | |
2099 char str_dd[3]; | |
2100 char str_hh[3]; | |
2101 char str_mi[3]; | |
2102 char str_ss[3]; | |
2103 str_yyyy[0] = '\0'; | |
2104 str_mm[0] = '\0'; | |
2105 str_dd[0] = '\0'; | |
2106 str_hh[0] = '\0'; | |
2107 str_mi[0] = '\0'; | |
2108 str_ss[0] = '\0'; | |
2109 | |
2110 p = yyyymmddhhmiss; | |
2111 i = strlen(p); | |
2112 j = strspn(p, LIST_DECIMAL); | |
2113 if ( i != j && i != 14 ) { | |
2114 /* 数字以外混ぜるな */ | |
2115 return -1; | |
2116 } | |
2117 strncpy(str_yyyy, yyyymmddhhmiss, 4); | |
2118 strncpy(str_mm, yyyymmddhhmiss+4, 2); | |
2119 strncpy(str_dd, yyyymmddhhmiss+6, 2); | |
2120 strncpy(str_hh, yyyymmddhhmiss+8, 2); | |
2121 strncpy(str_mi, yyyymmddhhmiss+10, 2); | |
2122 strncpy(str_ss, yyyymmddhhmiss+12, 2); | |
2123 str_yyyy[4] = '\0'; | |
2124 str_mm[2] = '\0'; | |
2125 str_dd[2] = '\0'; | |
2126 str_hh[2] = '\0'; | |
2127 str_mi[2] = '\0'; | |
2128 str_ss[2] = '\0'; | |
2129 | |
2130 cue_tm.tm_sec = atoi(str_ss); | |
2131 cue_tm.tm_min = atoi(str_mi); | |
2132 cue_tm.tm_hour = atoi(str_hh); | |
2133 cue_tm.tm_mday = atoi(str_dd); | |
2134 cue_tm.tm_mon = atoi(str_mm)-1; | |
2135 cue_tm.tm_year = atoi(str_yyyy)-1900; | |
2136 cue_tm.tm_isdst = -1; | |
2137 cue_time = mktime(&cue_tm); | |
2138 return cue_time; | |
2139 } | |
2140 | |
2141 /* PCR の PID を検索する */ | |
2142 static int search_pcr_pid(splitter *sp, int pid) | |
2143 { | |
2144 int i; | |
2145 for ( i=0; i < MAX_SERVICES; i++ ) { | |
2146 if ( sp->pcr[i].pid == pid ) { | |
2147 return i; | |
2148 } | |
2149 } | |
2150 return -1; | |
2151 } |