comparison recpt1/tssplitter_lite.c @ 122:4009737ea899

add es output arg: add start_time arg:
author Naoya OYAMA <naoya.oyama@gmail.com>
date Wed, 05 May 2010 20:43:43 +0900
parents e915d31c5bd9
children
comparison
equal deleted inserted replaced
121:e915d31c5bd9 122:4009737ea899
46 46
47 #ifndef AV_RB16 47 #ifndef AV_RB16
48 #define AV_RB16(x) ((((const uint8_t*)(x))[0] << 8) | ((const uint8_t*)(x))[1]) 48 #define AV_RB16(x) ((((const uint8_t*)(x))[0] << 8) | ((const uint8_t*)(x))[1])
49 #endif 49 #endif
50 #define MAX_SERVICE_ID ( 0xffff ) 50 #define MAX_SERVICE_ID ( 0xffff )
51 #define LIST_DECIMAL "0123456789"
52 #define TSS_STREAM_TYPE_AUDIO (1)
53 #define TSS_STREAM_TYPE_VIDEO (2)
51 54
52 /* prototypes */ 55 /* prototypes */
53 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf); 56 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf);
54 static int AnalyzePat(splitter *sp, unsigned char *buf); 57 static int AnalyzePat(splitter *sp, unsigned char *buf);
55 static int RecreatePat(splitter *sp, unsigned char *buf, int *pos); 58 static int RecreatePat(splitter *sp, unsigned char *buf, int *pos);
56 static char** AnalyzeSid(char *sid); 59 static char** AnalyzeSid(char *sid);
57 static int AnalyzePmt(splitter *sp, const uint8_t *buf, int sid, const int size); 60 static int AnalyzePmt(splitter *sp, const uint8_t *buf, int sid, const int size);
58 static int GetCrc32(unsigned char *data, int len); 61 static int GetCrc32(unsigned char *data, int len);
59 static int GetPid(unsigned char *data); 62 static int GetPid(unsigned char *data);
60 static int parse_tot( const unsigned char* packet, time_t *t ); 63 static int parse_tot( const unsigned char* packet, time_t *t );
61 void dump_packet( const uint8_t *packet ); 64 //void dump_packet( const uint8_t *packet );
62 static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, const uint8_t *packet); 65 static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, const uint8_t *packet);
63 static int DemuxTs(const uint8_t *packet, splitter *sp, const int pid, int *random_access); 66 static int DemuxTs(const uint8_t *packet, splitter *sp, const int pid);
64 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid, int random_access_indicator); 67 //static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid, int random_access_indicator);
68 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid);
65 static int64_t get_pts(const uint8_t *p); 69 static int64_t get_pts(const uint8_t *p);
66 void search_mpeg_system_header(const uint8_t *p); 70 //void search_mpeg_system_header(const uint8_t *p);
67 int esbuf_write(splitesbuf_t *esbuf); 71 static int esbuf_write(splitesbuf_t *esbuf);
68 //void forward_stc(timespec *stc, timespec offset);
69 static int pesbuf_packet_start_code_prefix(splitpesbuf_t *pesbuf); 72 static int pesbuf_packet_start_code_prefix(splitpesbuf_t *pesbuf);
70 static int pesbuf_empty(splitpesbuf_t *pesbuf); 73 static int pesbuf_empty(splitpesbuf_t *pesbuf);
71 void pesbuf_clear(splitpesbuf_t *pesbuf); 74 void pesbuf_clear(splitpesbuf_t *pesbuf);
72 static int pesbuf_add(splitpesbuf_t *pesbuf, const uint8_t *data, int len); 75 static int pesbuf_add(splitpesbuf_t *pesbuf, const uint8_t *data, int len);
73 static int esbuf_empty(splitesbuf_t *esbuf); 76 static int esbuf_empty(splitesbuf_t *esbuf);
74 void esbuf_clear(splitesbuf_t *esbuf); 77 void esbuf_clear(splitesbuf_t *esbuf, uint64_t pts, uint64_t dts);
75 static int esbuf_add(splitesbuf_t *esbuf, const uint8_t *data, int len); 78 static int esbuf_add(splitesbuf_t *esbuf, const uint8_t *data, int len);
76 static int get_pmt_version(const uint8_t *p); 79 static int get_pmt_version(const uint8_t *p);
77 static int esbuf_adts_start_code_prefix(splitesbuf_t *esbuf, int offset); 80 static int next_adts_start_code(splitesbuf_t *esbuf, int offset);
78 static int is_video_stream(const int pid, splitesbuf_t *esbuf); 81 static int is_video_stream(const int pid, splitesbuf_t *esbuf);
79 static int is_audio_stream(const int pid, splitesbuf_t *esbuf); 82 static int is_audio_stream(const int pid, splitesbuf_t *esbuf);
80 static int AnalyzeAdifHeader(splitesbuf_t *esbuf); 83 static int AnalyzeAdifHeader(splitesbuf_t *esbuf);
81 static int get_adif_id(uint8_t *p); 84 static int get_adif_id(uint8_t *p);
82 static int get_adif_layer(uint8_t *p); 85 static int get_adif_layer(uint8_t *p);
90 static int get_adif_copyright_idication_bit(uint8_t *p); 93 static int get_adif_copyright_idication_bit(uint8_t *p);
91 static int get_adif_copyright_idication_start(uint8_t *p); 94 static int get_adif_copyright_idication_start(uint8_t *p);
92 static int get_adif_aac_frame_length(uint8_t *p); 95 static int get_adif_aac_frame_length(uint8_t *p);
93 static int get_adts_buffer_fullness(uint8_t *p); 96 static int get_adts_buffer_fullness(uint8_t *p);
94 static int get_adts_no_raw_data_blocks_in_frame(uint8_t *p); 97 static int get_adts_no_raw_data_blocks_in_frame(uint8_t *p);
95 static int search_pmt_program(splitter *sp, int pid); 98 //static int search_pmt_program(splitter *sp, int pid);
96 static int search_gop_start_code(splitesbuf_t *esbuf); 99 static int search_gop_start_code(splitesbuf_t *esbuf);
97 //static int creat_filename(char *base, char *filename, int sid, int epid, int av_flag ,splitesbuf_t *esbuf); 100 static int creat_es_file(splitter *sp, int sid, int pid, int av_flag);
98 static int creat_filename(splitter *sp, int sid, int pid, int av_flag); 101 static time_t cue2time(char *yyyymmddhhmiss);
102 static int search_pcr_pid(splitter *sp, int pid);
99 103
100 /** 104 /**
101 * サービスID解析 105 * サービスID解析
102 */ 106 */
103 static char** AnalyzeSid( 107 static char** AnalyzeSid(
194 /** 198 /**
195 * 初期化処理 199 * 初期化処理
196 */ 200 */
197 splitter* split_startup( 201 splitter* split_startup(
198 char *sid, // [in] サービスID(引数で指定した文字列) 202 char *sid, // [in] サービスID(引数で指定した文字列)
199 char *filename // [in] 出力ESファイル名(引数で指定したファイル名) 203 char *filename, // [in] 出力ESファイル名(引数で指定したファイル名)
204 char *arg_cue // [in] 録画開始時刻(引数で指定した文字列 YYYYMMDDHHMISS)
200 ) 205 )
201 { 206 {
202 splitter* sp; 207 splitter* sp;
203 int i; 208 int i;
204 sp = malloc(sizeof(splitter)); 209 sp = malloc(sizeof(splitter));
213 fprintf(stderr, "split_startup malloc error.\n"); 218 fprintf(stderr, "split_startup malloc error.\n");
214 return NULL; 219 return NULL;
215 } 220 }
216 memset(sp->pids, 0, sizeof(sp->pids)); 221 memset(sp->pids, 0, sizeof(sp->pids));
217 memset(sp->pmt_pids, 0, sizeof(sp->pmt_pids)); 222 memset(sp->pmt_pids, 0, sizeof(sp->pmt_pids));
223 memset(sp->cat_pids, 0, sizeof(sp->cat_pids));
224 memset(sp->pcr_pids, 0, sizeof(sp->pcr_pids));
225 memset(sp->pcr, 0, sizeof(sp->pcr));
218 226
219 sp->sid_list = NULL; 227 sp->sid_list = NULL;
220 sp->pat = NULL; 228 sp->pat = NULL;
221 sp->sid_list = AnalyzeSid(sid); 229 sp->sid_list = AnalyzeSid(sid);
222 if ( sp->sid_list == NULL ) 230 if ( sp->sid_list == NULL )
225 return NULL; 233 return NULL;
226 } 234 }
227 sp->pat_count = 0xFF; 235 sp->pat_count = 0xFF;
228 sp->pmt_retain = -1; 236 sp->pmt_retain = -1;
229 sp->pmt_counter = 0; 237 sp->pmt_counter = 0;
230 // sp->STC_timespec.tv_sec = 0; 238 sp->time_cue = 0;
231 // sp->STC_timespec.tv_nsec = 0; 239 sp->time_tot = 0;
232 // sp->tot_offset.tv_sec = 0; 240 sp->pcr_nb = 0;
233 // sp->tot_offset.tv_nsec = 0;
234 sp->cue_time = -1;
235 sp->stc = 0;
236 sp->status = 1;
237 memset(sp->esbuf, 0, sizeof(splitesbuf_t *)*MAX_PID); 241 memset(sp->esbuf, 0, sizeof(splitesbuf_t *)*MAX_PID);
238 memset(sp->pesbuf, 0, sizeof(splitpesbuf_t *)*MAX_PID); 242 memset(sp->pesbuf, 0, sizeof(splitpesbuf_t *)*MAX_PID);
239 memset(sp->program, 0, sizeof(program_t *)*MAX_SERVICE_ID); 243 memset(sp->program, 0, sizeof(program_t *)*MAX_SERVICE_ID);
240 for ( i=0; i < MAX_PID; i++ ) { 244 for ( i=0; i < MAX_PID; i++ ) {
241 /* pmt_version は (N%32) の値を取るので、0 で初期化してはならない */ 245 /* pmt_version は (N%32) の値を取るので、0 で初期化してはならない */
242 sp->program[i].pmt_version = -1; 246 sp->program[i].pmt_version = -1;
247 /* cue は最大値で初期化(CUE <= STCとなると録画開始するため) */
248 sp->program[i].cue = INT64_MAX;
243 } 249 }
244 memset(sp->pid_sid_table, 0, sizeof(int)*MAX_PID); 250 memset(sp->pid_sid_table, 0, sizeof(int)*MAX_PID);
245 // sp->filename = filename;
246 if ( filename != NULL ) { 251 if ( filename != NULL ) {
247 sp->esout = 1; 252 sp->esout = 1;
248 sp->filename = filename; 253 sp->filename = filename;
254 }
255 if ( arg_cue != NULL ) {
256 sp->arg_cue = arg_cue;
257 } else {
258 sp->arg_cue = "00000000000000"; /* とりあえず最小値 */
249 } 259 }
250 return sp; 260 return sp;
251 } 261 }
252 262
253 /** 263 /**
268 /** 278 /**
269 * 終了処理 279 * 終了処理
270 */ 280 */
271 void split_shutdown(splitter* sp) 281 void split_shutdown(splitter* sp)
272 { 282 {
283 int i = 0;
273 if ( sp != NULL ) { 284 if ( sp != NULL ) {
274 if ( sp->pat != NULL ) 285 if ( sp->pat != NULL )
275 { 286 {
276 free(sp->pat); 287 free(sp->pat);
277 sp->pat = NULL; 288 sp->pat = NULL;
278 } 289 }
279 if ( sp->sid_list != NULL ) 290 if ( sp->sid_list != NULL )
280 { 291 {
281 free(sp->sid_list); 292 free(sp->sid_list);
282 sp->sid_list = NULL; 293 sp->sid_list = NULL;
294 }
295 for(i=0; i < MAX_PID; i++) {
296 if ( sp->esbuf[i] != NULL ) {
297 if ( sp->esbuf[i]->fd != -1 ) {
298 close(sp->esbuf[i]->fd);
299 sp->esbuf[i]->fd = -1;
300 }
301 free(sp->esbuf[i]);
302 sp->esbuf[i] = NULL;
303 }
304 if ( sp->pesbuf[i] != NULL ) {
305 free(sp->pesbuf[i]);
306 sp->pesbuf[i] = NULL;
307 }
283 } 308 }
284 free(sp); 309 free(sp);
285 sp = NULL; 310 sp = NULL;
286 } 311 }
287 } 312 }
292 * 対象のチャンネル番号のみの PAT の再構築と出力対象 PID の抽出を行う 317 * 対象のチャンネル番号のみの PAT の再構築と出力対象 PID の抽出を行う
293 */ 318 */
294 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf) 319 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf)
295 { 320 {
296 #if 0 321 #if 0
297 unsigned char **pat, // [out] PAT 情報(再構築後) 322 splitter *sp, // [in/out] splitter構造体
298 unsigned char* pids, // [out] 出力対象 PID 情報 323 ARIB_STD_B25_BUFFER *sbuf, // [in] pt1_drvの入力TS
299 char** sid_list, // [in] 出力対象サービス ID のリスト
300 unsigned char* pmt_pids, // [in] 出力対象PIDのPMT PID
301 , // [in] pt1_drvの入力TS
302 int* pmt_retain, // [in] PMTの落とすべき数
303 int* pmt_counter // [out] PMTの落とした数
304 #endif 324 #endif
305 325
306 int length = sbuf->size; 326 int length = sbuf->size;
307 int pid; 327 int pid;
308 int result = TSS_ERROR; 328 int result = TSS_ERROR;
311 index = 0; 331 index = 0;
312 while(length - index - LENGTH_PACKET > 0) { 332 while(length - index - LENGTH_PACKET > 0) {
313 pid = GetPid(sbuf->data + index + 1); 333 pid = GetPid(sbuf->data + index + 1);
314 // PAT 334 // PAT
315 if(PAT == pid) { 335 if(PAT == pid) {
316 dump_packet(sbuf->data + index);
317 result = AnalyzePat(sp, sbuf->data + index); 336 result = AnalyzePat(sp, sbuf->data + index);
318 if(TSS_SUCCESS != result) { 337 if(TSS_SUCCESS != result) {
319 /* 下位の関数内部でmalloc error発生 */ 338 /* 下位の関数内部でmalloc error発生 */
320 return result; 339 return result;
321 } 340 }
323 342
324 // PMT 343 // PMT
325 /* 残すpmt_pidである場合には、pmtに書かれている 344 /* 残すpmt_pidである場合には、pmtに書かれている
326 * 残すべきPCR/AUDIO/VIDEO PIDを取得する */ 345 * 残すべきPCR/AUDIO/VIDEO PIDを取得する */
327 if(sp->pmt_pids[pid] == 1) { 346 if(sp->pmt_pids[pid] == 1) {
328 /*
329 * program(番組)とServiceID をベースに管理することにしているので、
330 * pmt_pidsとかもう必要ないかも…
331 */
332 /* この中にはPMT毎に一度しか入らないようにしておく */ 347 /* この中にはPMT毎に一度しか入らないようにしておく */
333 int random_access;
334 //AnalyzePmt(sp, sbuf->data + index, pid);
335 //AnalyzePmt(sp, sbuf->data + index +4, pid, LENGTH_PACKET-4);
336 sp->pmt_pids[pid]++; 348 sp->pmt_pids[pid]++;
337 sp->pmt_counter += 1; 349 sp->pmt_counter += 1;
338 DemuxTs(sbuf->data +index, sp, pid, &random_access); /* AnalyzePmt より DemuxTs の方がアダプテーションフィールドの処理が良いので変更 */ 350 DemuxTs(sbuf->data +index, sp, pid); /* AnalyzePmt より DemuxTs の方がアダプテーションフィールドの処理が良いので変更 */
339 } 351 }
340 /* 録画する全てのPMTについて、中にあるPCR/AUDIO/VIDEOのPIDを 352 /* 録画する全てのPMTについて、中にあるPCR/AUDIO/VIDEOのPIDを得る */
341 * 得る */
342 /* pmt_counter と pmt_retain が一致する場合に条件は満たされる */ 353 /* pmt_counter と pmt_retain が一致する場合に条件は満たされる */
343 if(sp->pmt_counter == sp->pmt_retain) { 354 if(sp->pmt_counter == sp->pmt_retain) {
344 result = TSS_SUCCESS; 355 result = TSS_SUCCESS;
345 break; 356 break;
346 } 357 }
355 366
356 /** 367 /**
357 * TS 分離処理 368 * TS 分離処理
358 */ 369 */
359 int split_ts( 370 int split_ts(
360 splitter *splitter, // [in] splitterパラメータ 371 splitter *sp, // [in] splitterパラメータ
361 ARIB_STD_B25_BUFFER *sbuf, // [in] 入力TS 372 ARIB_STD_B25_BUFFER *sbuf, // [in] 入力TS
362 splitbuf_t *dbuf // [out] 出力TS 373 splitbuf_t *dbuf // [out] 出力TS
363 ) 374 )
364 { 375 {
365 int pid; 376 int pid;
366 unsigned char *sptr, *dptr; 377 unsigned char *sptr, *dptr;
367 int s_offset = 0; 378 int s_offset = 0;
368 int d_offset = 0; 379 int d_offset = 0;
369 int64_t pcr; 380 int64_t pcr_h = 0;
370 int64_t pcr_h; 381 int pcr_l = 0;
371 int pcr_l; 382 int ret = 0;
372 struct timespec tot_timespec; 383 int sid = 0;
373 struct timespec local_timespec; 384 program_t *program;
374 int len_pes; 385 static int packet_nb; /* パケット受信数 */
375 int random_access; 386 int i = 0;
376 int sid;
377 387
378 /* 初期化 */ 388 /* 初期化 */
379 dbuf->size = 0; 389 dbuf->size = 0;
380 if (sbuf->size < 0) { 390 if (sbuf->size < 0) {
381 return TSS_ERROR; 391 return TSS_ERROR;
382 } 392 }
383 393
384 sptr = sbuf->data; 394 sptr = sbuf->data;
385 dptr = dbuf->buffer; 395 dptr = dbuf->buffer;
386 #if 0
387 /* TOT受信済みであるなら、STC を成長させる */
388 if ( sp->tot_offset.tv_nsec != 0 && sp->tot_offset.tv_sec != 0) {
389 forward_stc(&(sp->STC_timespec), sp->tot_offset);
390 }
391 #endif
392 396
393 while(sbuf->size > s_offset) { 397 while(sbuf->size > s_offset) {
394 pid = GetPid(sptr + s_offset + 1); 398 pid = GetPid(sptr + s_offset + 1);
395 sid = splitter->pid_sid_table[pid]; 399 sid = sp->pid_sid_table[pid]; /* PIDからSIDを取得 */
396 switch(pid) { 400 switch(pid) {
397 401
398 // PAT 402 // PAT
399 case PAT: 403 case PAT:
400 // 巡回カウンタカウントアップ 404 // 巡回カウンタカウントアップ
401 if(0xFF == splitter->pat_count) { 405 if(0xFF == sp->pat_count) {
402 splitter->pat_count = splitter->pat[3]; 406 sp->pat_count = sp->pat[3];
403 } 407 }
404 else { 408 else {
405 splitter->pat_count = (splitter->pat_count + 1) % 16; 409 sp->pat_count += 1;
410 if(0 == sp->pat_count % 0x10) {
411 sp->pat_count -= 0x10;
412 }
406 } 413 }
407 splitter->pat[3] = splitter->pat_count; 414 sp->pat[3] = sp->pat_count;
408 415
409 memcpy(dptr + d_offset, splitter->pat, LENGTH_PACKET); 416 memcpy(dptr + d_offset, sp->pat, LENGTH_PACKET);
410 d_offset += LENGTH_PACKET; 417 d_offset += LENGTH_PACKET;
411 dbuf->size += LENGTH_PACKET; 418 dbuf->size += LENGTH_PACKET;
412 break; 419 break;
413 case TOT: 420 case TOT:
414 /* TOT に TDTの情報全てが含まれており、実放送では TOT しか送信されない */ 421 /* TOT に TDTの情報全てが含まれており、実放送では TOT しか送信されない */
415 /* TOT は 500msec の誤差が保証されている 422 /* TOT は 500msec の誤差が保証されている
416 * 閏秒の場合は最大1.5秒の誤差となる 423 * 閏秒の場合は最大1.5秒の誤差となる
417 */ 424 */
418 #if 0 425 if ( sp->time_tot == 0 ) {
419 if ( sp->tot_offset.tv_nsec != 0 && sp->tot_offset.tv_sec != 0 ) { 426 /* splitter構造体の時刻関係(TOT/CUE)のパラメータ初期化 */
420 parse_tot(sptr + s_offset, &(tot_timespec.tv_sec)); 427 parse_tot(sptr + s_offset, &(sp->time_tot));
421 clock_gettime(CLOCK_REALTIME, &local_timespec); 428 sp->time_cue = cue2time(sp->arg_cue);
422 429 sp->tot_packet_nb = packet_nb;
423 /* TOT をSystem Time Clock(STC)に入れる */
424 sp->STC_timespec.tv_sec = tot_timespec.tv_sec;
425 sp->STC_timespec.tv_nsec = tot_timespec.tv_nsec;
426
427 /* TOT と localtime の差分を sp->tot_offset に入れる */
428 sp->tot_offset.tv_sec = tot_timespec.tv_sec - local_timespec.tv_sec;
429 sp->tot_offset.tv_nsec = tot_timespec.tv_nsec - local_timespec.tv_nsec;
430 }
431 #endif
432 /* STC が既にあるならTOT受信時に頭出し時刻を決定する */
433 /* 59秒9990 あたりを頭出し時刻に設定でよいかな */
434 if ( splitter->stc != 0 && splitter->cue_time == -1) {
435 /* TOT から cue_time を計算する */
436 /* えいや。で、59秒9990固定決め打ち */
437 parse_tot(sptr + s_offset, &(tot_timespec.tv_sec));
438 //cue_second = ((tot_timespec.tv_sec % 60) - 59);
439 splitter->cue_time = splitter->stc + (((59 - (tot_timespec.tv_sec % 60))*(27*1000*1000)) + floor((27*1000*1000)*0.999));
440 //printf("stc[%lld]. cue_time[%lld].\n", splitter->stc, splitter->cue_time);
441
442 } else {
443 /* TOT受診時にSTCが存在しないならTOTは捨てる */
444 } 430 }
445 break; 431 break;
446 default: 432 default:
447 /* 時間管理に関しての実装方針 */ 433 /* ■時間管理に関しての実装方針■ */
448 /* 434 /*
449 * 時間関係を扱っている変数のまとめ 435 * ■時間関係を扱っている変数■
450 * PCR : 42Bit @27MHz(プログラム毎に独立) 436 * PCR : 42Bit @27MHz(ServiceID(ProgramID, sid)毎に独立)
451 * PTS : 42Bit @90KHz(SYSTEM ID(ES)毎に独立) 437 * PTS : 42Bit @90KHz(ES毎に独立)
452 * DTS : 42Bit @90KHz(SYSTEM ID(ES)毎に独立) 438 * DTS : 42Bit @90KHz(ES毎に独立)
453 * TOT : MJD + 2進化10進数(ストリームに一つだけ) 439 * TOT : MJD + 2進化10進数(TSに1つだけ)
454 * STC : 64Bit @27MHz(システムローカル時刻(ソースはTOT)) 440 * STC : 64Bit @27MHz(ServiceID(ProgramID, sid)の現在時刻(ソースはPCR))
441 * CUE : 録画開始時刻 YYYYMMDDHHMISS (引数指定)
455 * 442 *
456 * STC と TOT の関連だけ計算出来るようにしておいて、 443 * ■STCの管理方針■
457 * 出力するようにする/しないの判定は全体的に、 444 * PCR受信時にSTCに時間情報をコピーする
458 * STCからTOTを使って出した時刻情報とする。かなぁ。 445 * 1パケットを受信すると経過する時間を加算してSTCを管理する
459 * PCR/PTS/DTSはオーバーフローしたときには34Bit目が立っていると見なすこと 446 * (ffmpegのmpegts.cと同じ方針)
447 *
448 * ■CUEとTOTとSTC■
449 * TOTからSTCと比較するための情報を作成する。
450 * ・TOTは time_t
451 * ・CUEは time_t
452 * ・STCは42Bitの27MHz周期の数値
453 * TOT 受信時に各Program(ServiceID)のSTCを変換基準値とする
454 * 録画開始時(27MHz)の値の計算式は、
455 * Program->CUE = STCの変換基準値 + 27e6*(ARG_CUE-TOT(秒))
456 * 録画の開始確認として Program->CUE と PTS を比較すればよい
457 *
458 * ※PCR/PTS/DTSはオーバーフローしたときには34Bit目が立っていると見なすこと※
459 * オーバーフロー時の処理は未実装
460 */ 460 */
461 // if ( 1 == splitter->pmt_pids[pid] ) { 461 if ( 2 == sp->pmt_pids[pid] ) {
462 if ( 2 == splitter->pmt_pids[pid] ) {
463 /* PMT の追跡 */ 462 /* PMT の追跡 */
464 int random_access; 463 DemuxTs((sptr+s_offset), sp, pid);
465 DemuxTs((sptr+s_offset), splitter, pid, &random_access);
466 } 464 }
467 /* pids[pid] が 1 は残すパケットなので書き込む */ 465 /* pids[pid] が 1 は残すパケットなので書き込む */
468 if ( 1 == splitter->pids[pid] ) { 466 if ( (1 == sp->pids[pid]) ) {
469 len_pes = 0; 467 /* PCRとSTCの処理 */
470 random_access = 0; 468 int pcr_index;
471 /* PCR 解析テスト */ 469 pcr_index = search_pcr_pid(sp, pid);
472 if (parse_pcr(&pcr_h, &pcr_l, (sptr+s_offset)) == 0){ 470 if ( sp->pcr_pids[pid] == 1 && pcr_index != -1) { /* PCRか否か */
473 pcr = pcr_h * 300 + pcr_l; 471 ret = parse_pcr(&pcr_h, &pcr_l, (sptr+s_offset));
474 /* PCR の種にするものは、Program の PCR として指定されたPacketIDのものとすること */ 472 /*
475 /* STC は PCR を種にする */ 473 * PCR は複数 ServiceID(ProgramID)で重複利用される場合がある
476 splitter->stc = pcr; 474 * PCR を参照する複数の ServiceID(ProgramID)分ループ
477 // printf("PID[%d] pcr_h=[%llx] pcr_l=[%d] PCR[%f]\n",pid, pcr_h, pcr_l, ((double)pcr/(90000*300))); 475 */
478 } 476 for (i=0; i < sp->pcr[pcr_index].sid_nb; i++) {
479 /* TS処理 */ 477 sid = sp->pcr[pcr_index].sid[i];
480 if (DemuxTs((sptr+s_offset), splitter, pid, &random_access) == 0 ) { 478 program = &(sp->program[sid]);
481 #if 0 479 /* こっから */
482 /* とりあえずやっつけ */ 480 if ( ret == 0 ) { /* PCR の解析に成功 */
483 /* パケットの画面表示時刻(pts) >= 録画開始時刻(cue_time) となった場合に録画開始 */ 481 program->stc = pcr_h * 300 + pcr_l; /* PCR受信時にSTCを補正*/
484 // if ( ((pts*300) >= splitter->cue_time) && (splitter->cue_time != -1)) { 482 if ( program->pcr1 == 0 ) {
485 if ( ((splitter->esbuf[pid].pts) >= splitter->program[sid].cue_time) && (splitter->program[sid].cue_time != -1)) { 483 program->pcr1 = program->stc;
486 splitter->cue_time = 0; 484 printf("pcr1 pid[%d] sid[%d] packet_nb[%d] sid_nb[%d] i[%d]\n",
487 splitter->status = 0; 485 pid, sid, packet_nb, sp->pcr[pcr_index].sid_nb, i);
488 clock_gettime(CLOCK_REALTIME, &local_timespec); 486 } else if ( program->pcr2 == 0 ) {
489 printf("start recording. time_sec[%d] nsec[%d].\n", local_timespec.tv_sec%60, local_timespec.tv_nsec); 487 // printf("pcr2 pid[%d] sid[%d] packet_nb[%d], p_packet_nb[%d] sid_nb[%d] i[%d]\n",
490 } 488 // pid, sid, packet_nb, program->pcr_packet_nb, sp->pcr[pcr_index].sid_nb, i);
491 #endif 489 program->pcr2 = program->stc;
492 } 490 program->pcr_incr = (program->pcr2 -program->pcr1)
493 //search_mpeg_system_header(sptr+s_offset); 491 /(packet_nb -program->pcr_packet_nb);
494 /* 492 printf("pcr2 pid[%d] sid[%d] pcr_incr[%llu]\n",
495 * STCが cue_time を経過したら録画開始 493 pid, sid, program->pcr_incr);
496 */ 494 } else {
497 if ( splitter->cue_time != -1 && splitter->cue_time <= splitter->stc ) { 495 /* PCR処理済み */
498 memcpy(dptr + d_offset, sptr + s_offset, LENGTH_PACKET); 496 ; /* 得に処理無し */
499 d_offset += LENGTH_PACKET; 497 }
500 dbuf->size += LENGTH_PACKET; 498 if ( (program->cue == INT64_MAX ) &&
501 if ( splitter->status ) { 499 (sp->arg_cue != NULL) &&
502 struct timespec local_timespec; 500 (sp->time_tot != 0) ) { /* 録画開始時刻指定時 */
503 clock_gettime(CLOCK_REALTIME, &local_timespec); 501 /*
504 printf("start recording. time_sec[%d] nsec[%d].\n", local_timespec.tv_sec%60, local_timespec.tv_nsec); 502 * 録画開始時刻 = STC +(CUE -TOT)*27MHz
505 splitter->status = 0; 503 * +(TOT取得時から現在までのパケット数の増分)*パケットあたりの進む時間
504 * -0.49秒(この数字は適当)
505 * TOT/STCで時間調整して、GOP先頭から出すので攻めてしまっていい気がする
506 */
507 program->cue = program->stc
508 +(sp->time_cue -sp->time_tot)*27e6
509 +(packet_nb -sp->tot_packet_nb)*program->pcr_incr
510 -(27e6*49/100);
511 printf("STC[%llu] CUE[%llu] SID[%d]\n",
512 program->stc, program->cue, sid);
513 }
514 program->pcr_packet_nb = packet_nb;
515 program->packet_nb = packet_nb;
516 } else if ( program->pcr_incr ) { /* PCRの解析に失敗且つpcr_incr変数の計算済み*/
517 /* STCを成長させる */
518 program->stc += (packet_nb -program->packet_nb)*program->pcr_incr;
519 program->packet_nb = packet_nb;
520 } else {
521 ; /* STCを進める要素が揃ってません */
522 }
523 } /* for */
524 } else { /* 処理対象パケットはPCRではない */
525 program = &(sp->program[sid]);
526 if ( program->pcr_incr ) { /* PCRを受信しない且つpcr_incr変数の計算済み */
527 /* STCを成長させる */
528 program->stc += (packet_nb -program->packet_nb)*program->pcr_incr;
529 program->packet_nb = packet_nb;
530 } else { /* それ以外 */
531 ; /* STCを進める要素が揃ってません */
506 } 532 }
507 } 533 }
534 #if 0
535 // NHK Gを ALL とすると SID 1024 しか出ない...orz..
536 if ( !(packet_nb % 1000) ) {
537 program = &(sp->program[sid]);
538 printf("STC[%llu] SID[%d]\n", program->stc, sid);
539 }
540 #endif
541 /* TS処理 */
542 DemuxTs((sptr+s_offset), sp, pid);
543 memcpy(dptr + d_offset, sptr + s_offset, LENGTH_PACKET);
544 d_offset += LENGTH_PACKET;
545 dbuf->size += LENGTH_PACKET;
508 } 546 }
509 break; 547 break;
510 } /* switch */ 548 } /* switch */
511
512 s_offset += LENGTH_PACKET; 549 s_offset += LENGTH_PACKET;
513 } 550 packet_nb += 1; /* パケット受信数加算 */
514 551 }
515 return(TSS_SUCCESS); 552 return(TSS_SUCCESS);
516 } 553 }
517 554
518 /** 555 /**
519 * PAT 解析処理 556 * PAT 解析処理
572 609
573 while(*p) { 610 while(*p) {
574 if(service_id == atoi(*p)) { 611 if(service_id == atoi(*p)) {
575 /* 録画対象の pmt_pids は 1 とする */ 612 /* 録画対象の pmt_pids は 1 とする */
576 /* 録画対象の pmt の pids は 1 とする */ 613 /* 録画対象の pmt の pids は 1 とする */
614 /* 対応する pid_sid_table に サービスID(ProgramID) を入れる */
577 pid = GetPid(&buf[i + 2]); 615 pid = GetPid(&buf[i + 2]);
578 *(pmt_pids+pid) = 1; 616 *(pmt_pids+pid) = 1;
579 *(pids+pid) = 1; 617 *(pids+pid) = 1;
580 pos[pid] = i; 618 pos[pid] = i;
581 sid_found = TRUE; 619 sid_found = TRUE;
780 (sp->pat)[8 + LENGTH_PAT_HEADER + pid_num*4] = (crc ) & 0xFF; 818 (sp->pat)[8 + LENGTH_PAT_HEADER + pid_num*4] = (crc ) & 0xFF;
781 819
782 return(TSS_SUCCESS); 820 return(TSS_SUCCESS);
783 } 821 }
784 822
823
785 /** 824 /**
786 * PMT 解析処理 825 * PMT 解析処理
787 * 826 *
788 * PMT を解析し、保存対象の PID を特定する 827 * PMT を解析し、保存対象の PID を特定する
789 * TSヘッダとアダプテーションフィールドの処理は DemuxTs に一任するので、 828 * TSヘッダとアダプテーションフィールドの処理は DemuxTs に一任するので、
798 unsigned char Nall; 837 unsigned char Nall;
799 unsigned char N; 838 unsigned char N;
800 int pcr; 839 int pcr;
801 int epid; 840 int epid;
802 int av_flag = 0; 841 int av_flag = 0;
842 int i = 0;
843 int j = 0;
844 int pcr_found = 0;
845 /* デバッグ用 PMT情報表示 */
846 #define PmtDebug (1)
847
848 #ifdef PmtDebug
849 printf("AnalyzePmt start. Tree List enable.\n");
850 printf("SID[%d][0x%04x]\n", sid, sid);
851 #endif
803 852
804 // Nall = ((buf[2] & 0x0F) << 4) + buf[3]; 853 // Nall = ((buf[2] & 0x0F) << 4) + buf[3];
805 Nall = ((buf[2] & 0x0F) << 8) + buf[3]; 854 Nall = ((buf[2] & 0x0F) << 8) + buf[3];
855 // ここで受け取るのはTSパケットではなく、セクションの先頭ポインタであるのでsizeで見る
856 // if(Nall > LENGTH_PACKET)
857 // Nall = LENGTH_PACKET - 8; /* xxx workaround --yaz */
858 if(Nall > size)
859 Nall = size -8;
806 860
807 /* get version */ 861 /* get version */
808 sp->program[sid].pmt_version = get_pmt_version(buf); 862 sp->program[sid].pmt_version = get_pmt_version(buf);
863 #ifdef PmtDebug
864 printf(" pmt_version[%02x]\n", sp->program[sid].pmt_version);
865 #endif
809 866
810 // PCR 867 // PCR
811 pcr = GetPid(&buf[9]); 868 pcr = GetPid(&buf[9]);
812 sp->pids[pcr] = 1; 869 sp->pids[pcr] = 1;
813 sp->program[sid].pcr_packet_id = pcr; 870 sp->program[sid].pcr_packet_id = pcr;
871 sp->pid_sid_table[pcr] = sid; /* PCRは重複する可能性があるので方式がよろしくない */
872 sp->pcr_pids[pcr] = 1;
873
874 /* PCRの重複チェック(複数ServiceID(ProgramID)) */
875 for( i=0; i < sp->pcr_nb; i++ ) {
876 if ( sp->pcr[i].pid == pcr ) {
877 /* 発見 */
878 for ( j=0; j < sp->pcr[i].sid_nb; j++ ) {
879 /* 同一SIDが既に登録されているか確認 */
880 if ( sp->pcr[i].sid[j] == sid ) {
881 pcr_found = 1;
882 break;
883 }
884 }
885 if ( pcr_found ) {
886 /* 同一SIDが既に登録されている */
887 #ifdef PmtDebug
888 printf(" same sid found pcr[%d] sid[%d]\n", pcr, sid);
889 #endif
890 break;
891 }
892 /* 重複PCR発見 */
893 #ifdef PmtDebug
894 printf(" same pcr found pcr[%d] sid[%d] sid_nb[%d], i[%d]\n", pcr, sid, sp->pcr[i].sid_nb, i);
895 #endif
896 sp->pcr[i].sid[sp->pcr[i].sid_nb] = sid;
897 sp->pcr[i].sid_nb += 1;
898 pcr_found = 1;
899 break;
900 }
901 }
902
903 if ( ! pcr_found ) {
904 /* PCR管理領域更新 */
905 #ifdef PmtDebug
906 printf(" new pcr found pcr[%d] sid[%d], pcr_nb[%d]\n", pcr, sid, sp->pcr_nb);
907 #endif
908 sp->pcr[sp->pcr_nb].pid = pcr;
909 sp->pcr[sp->pcr_nb].sid[0] = sid;
910 sp->pcr[sp->pcr_nb].sid_nb = 1;
911 sp->pcr_nb += 1;
912 }
913 #ifdef PmtDebug
914 printf(" PCR PacketID[%d][0x%04x]\n", pcr, pcr);
915 #endif
814 916
815 // N = ((buf[11] & 0x0F) << 4) + buf[12] + 16 + 1; 917 // N = ((buf[11] & 0x0F) << 4) + buf[12] + 16 + 1;
816 N = ((buf[11] & 0x0F) << 8) + buf[12] + 12 + 1; 918 N = ((buf[11] & 0x0F) << 8) + buf[12] + 12 + 1;
817 // printf("NAll[%d] N[%d]\n", Nall, N); 919 // printf("NAll[%d] N[%d]\n", Nall, N);
920
921 // ECM
922 //int p = 17;
923 int p = 13;
924 while(p < N) {
925 if ( p > size -4) {
926 break;
927 }
928 uint32_t cat_pid;
929 uint32_t tag;
930 uint32_t len;
931
932 tag = buf[p];
933 len = buf[p+1];
934 p += 2;
935
936 if(tag == 0x09 && len >= 4 && p+len <= N) {
937 // ca_pid = ((buf[p+2] << 8) | buf[p+3]) & 0x1fff;
938 cat_pid = (AV_RB16(buf+p+2)) & 0x1fff;
939 sp->pids[cat_pid] = 1;
940 sp->cat_pids[cat_pid] = 1;
941 sp->pid_sid_table[cat_pid] = sid; /* CATも複数ServiceIDで重複がある */
942 #ifdef PmtDebug
943 printf(" CAT PacketID[%d][0x%04x]\n", cat_pid, cat_pid);
944 #endif
945 }
946 p += len;
947 }
818 948
819 /* 949 /*
820 * ISO/IEC 13818-1:2000(E) Table 2-29 - Stream type assignments 950 * ISO/IEC 13818-1:2000(E) Table 2-29 - Stream type assignments
821 * Value Desctiption 951 * Value Desctiption
822 * 0x00 ITU-T | ISO/IEC Reserved 952 * 0x00 ITU-T | ISO/IEC Reserved
844 * 0x80-0xFF User Private 974 * 0x80-0xFF User Private
845 * 975 *
846 */ 976 */
847 977
848 // ES PID 978 // ES PID
849 while (N < Nall + 8 - 4) 979 while (N < Nall + 8 - 4) {
850 {
851 av_flag = 0; 980 av_flag = 0;
852 if ( N > size ) {
853 break;
854 }
855 // ストリーム種別が 0x0D(type D)は出力対象外 981 // ストリーム種別が 0x0D(type D)は出力対象外
856 if (0x0D != buf[N]) 982 if (0x0D != buf[N]) {
857 {
858 epid = GetPid(&buf[N + 1]); 983 epid = GetPid(&buf[N + 1]);
859 sp->pids[epid] = 1; 984 sp->pids[epid] = 1;
985 sp->pid_sid_table[epid] = sid;
860 if ( buf[N] == 0x02 ) { /* 13818-2 Video */ 986 if ( buf[N] == 0x02 ) { /* 13818-2 Video */
861 sp->program[sid].video[sp->program[sid].video_nb] = epid; 987 sp->program[sid].video[sp->program[sid].video_nb] = epid;
862 sp->program[sid].video_nb += 1; 988 sp->program[sid].video_nb += 1;
863 av_flag = 1; 989 av_flag = TSS_STREAM_TYPE_VIDEO;
990 #ifdef PmtDebug
991 printf(" VIDEO PacketID[%d][0x%04x] StreamType[0x%02x]\n", epid, epid, buf[N]);
992 #endif
864 } else if ( (buf[N] == 0x04) || (buf[N] == 0x0f) ) { 993 } else if ( (buf[N] == 0x04) || (buf[N] == 0x0f) ) {
865 /* 13818-3 Audio or 13818-7 Audio with ADTS transport syntax */ 994 /* 13818-3 Audio or 13818-7 Audio with ADTS transport syntax */
866 sp->program[sid].audio[sp->program[sid].audio_nb] = epid; 995 sp->program[sid].audio[sp->program[sid].audio_nb] = epid;
867 sp->program[sid].audio_nb += 1; 996 sp->program[sid].audio_nb += 1;
868 av_flag = 2; 997 av_flag = TSS_STREAM_TYPE_AUDIO;
998 #ifdef PmtDebug
999 printf(" AUDIO PacketID[%d][0x%04x] StreamType[0x%02x]\n", epid, epid, buf[N]);
1000 #endif
869 } else { 1001 } else {
1002 #ifdef PmtDebug
1003 printf(" OTHER PacketID[%d][0x%04x] StreamType[0x%02x]\n", epid, epid, buf[N]);
1004 #endif
870 ; /* A/V どちらでもないものはとりあえずスルー */ 1005 ; /* A/V どちらでもないものはとりあえずスルー */
871 } 1006 }
872 if ( av_flag ) { 1007 if ( av_flag && sp->esout ) {
873 /* ESバッファはNULLか? */ 1008 /* ESバッファはNULLか? */
874 if ( sp->esbuf[epid] == NULL ) { 1009 if ( sp->esbuf[epid] == NULL ) {
875 sp->esbuf[epid] = malloc(sizeof(splitesbuf_t)); 1010 sp->esbuf[epid] = malloc(sizeof(splitesbuf_t));
876 if ( sp->esbuf[epid] == NULL ) { 1011 if ( sp->esbuf[epid] == NULL ) {
877 fprintf(stderr, "malloc error\n"); 1012 fprintf(stderr, "malloc error\n");
878 return TSS_NULL; 1013 return TSS_NULL;
879 } 1014 }
880 sp->esbuf[epid]->size = 0; 1015 sp->esbuf[epid]->size = 0;
881 sp->esbuf[epid]->Program = &(sp->program[sid]); 1016 sp->esbuf[epid]->Program = &(sp->program[sid]);
882 // creat_filename(sp->filename, sp->esbuf[epid]->filename, sid, epid, av_flag, &(sp->esbuf[epid])); 1017 sp->esbuf[epid]->fd = -1;
883 creat_filename(sp, sid, epid, av_flag); 1018 if ( creat_es_file(sp, sid, epid, av_flag) ) {
1019 return TSS_ERROR;
1020 }
884 } 1021 }
885 /* PESバッファはNULLか? */ 1022 /* PESバッファはNULLか? */
886 if ( sp->pesbuf[epid] == NULL ) { 1023 if ( sp->pesbuf[epid] == NULL ) {
887 sp->pesbuf[epid] = malloc(sizeof(splitpesbuf_t)); 1024 sp->pesbuf[epid] = malloc(sizeof(splitpesbuf_t));
888 if ( sp->pesbuf[epid] == NULL ) { 1025 if ( sp->pesbuf[epid] == NULL ) {
895 } 1032 }
896 } 1033 }
897 // N += 4 + (((buf[N + 3]) & 0x0F) << 4) + buf[N + 4] + 1; 1034 // N += 4 + (((buf[N + 3]) & 0x0F) << 4) + buf[N + 4] + 1;
898 N += 4 + (((buf[N + 3]) & 0x0F) << 8) + buf[N + 4] + 1; 1035 N += 4 + (((buf[N + 3]) & 0x0F) << 8) + buf[N + 4] + 1;
899 } 1036 }
1037 #ifdef PmtDebug
1038 printf("AnalyzePmt finish.\n");
1039 #endif
900 return TSS_SUCCESS; 1040 return TSS_SUCCESS;
901 } 1041 }
902 1042
903 /** 1043 /**
904 * CRC 計算 1044 * CRC 計算
992 } 1132 }
993 1133
994 /* pesbufにデータを追加 (ret. 0:success / -1:error) */ 1134 /* pesbufにデータを追加 (ret. 0:success / -1:error) */
995 static int pesbuf_add(splitpesbuf_t *pesbuf, const uint8_t *data, int len){ 1135 static int pesbuf_add(splitpesbuf_t *pesbuf, const uint8_t *data, int len){
996 if(pesbuf->size + len > sizeof pesbuf->buffer){ 1136 if(pesbuf->size + len > sizeof pesbuf->buffer){
997 //assert(0);
998 return -1; 1137 return -1;
999 } 1138 }
1000 memcpy(pesbuf->buffer +pesbuf->size, data, len); 1139 memcpy(pesbuf->buffer +pesbuf->size, data, len);
1001 pesbuf->size += len; 1140 pesbuf->size += len;
1002 return 0; 1141 return 0;
1031 } 1170 }
1032 1171
1033 /** 1172 /**
1034 * TSの解析とDemuxを行う 1173 * TSの解析とDemuxを行う
1035 */ 1174 */
1036 static int DemuxTs(const uint8_t *packet, splitter *sp, const int pid, int *random_access) 1175 static int DemuxTs(const uint8_t *packet, splitter *sp, const int pid)
1037 { 1176 {
1038 /* 1177 /*
1039 * PES先頭までの長さは 1178 * PES先頭までの長さは
1040 * 4byte : continity counter 1179 * 4byte : continity counter
1041 * 27,28bit が adaptation fileld制御 1180 * 27,28bit が adaptation fileld制御
1047 int payload_offset; /* ペイロードオフセット(=パケット先頭からのバイト数) */ 1186 int payload_offset; /* ペイロードオフセット(=パケット先頭からのバイト数) */
1048 int payload_length; /* ペイロード長 */ 1187 int payload_length; /* ペイロード長 */
1049 int pes_started; 1188 int pes_started;
1050 int adaptation_field_control; 1189 int adaptation_field_control;
1051 int payload_unit_start_indicator; 1190 int payload_unit_start_indicator;
1052 int random_access_indicator = 0; 1191 // int random_access_indicator = 0;
1053 int sid = sp->pid_sid_table[pid]; 1192 int sid = sp->pid_sid_table[pid]; /* SIDをPIDから引いているが、PCRとCATは重複しているので注意*/
1054 1193
1055 payload_offset = LENGTH_TS_HEADER; 1194 payload_offset = LENGTH_TS_HEADER;
1056 1195
1057 if ( sp->pesbuf[pid] == NULL ) { 1196 if ( sp->pesbuf[pid] == NULL ) {
1058 pes_started = 0; /* malloc走る前(セクション解析だったら呼んで良い) */ 1197 pes_started = 0; /* malloc走る前(セクション解析だったら呼んで良い) */
1066 /* ペイロードなしの場合 */ 1205 /* ペイロードなしの場合 */
1067 return 0; /* 別にエラーではない */ 1206 return 0; /* 別にエラーではない */
1068 } else if ( adaptation_field_control == 0x03 ) { 1207 } else if ( adaptation_field_control == 0x03 ) {
1069 /* アダプテーションフィールド+ペイロードの場合 */ 1208 /* アダプテーションフィールド+ペイロードの場合 */
1070 if ( packet[LENGTH_TS_HEADER] != 0 ) { 1209 if ( packet[LENGTH_TS_HEADER] != 0 ) {
1071 random_access_indicator = (packet[5] & 0x40) >> 6; 1210 // random_access_indicator = (packet[5] & 0x40) >> 6;
1072 } 1211 }
1073 /* ペイロード開始位置 = TSヘッダ長 + アダプテーションフィールド長 + 1 */ 1212 /* ペイロード開始位置 = TSヘッダ長 + アダプテーションフィールド長 + 1 */
1074 payload_offset += packet[LENGTH_TS_HEADER] + 1; 1213 payload_offset += packet[LENGTH_TS_HEADER] + 1;
1075 } else { 1214 } else {
1076 /* ペイロードのみ */ 1215 /* ペイロードのみ */
1098 AnalyzePmt(sp, packet +payload_offset, sid, payload_length); 1237 AnalyzePmt(sp, packet +payload_offset, sid, payload_length);
1099 /* payload 何byte処理したか等管理するべき */ 1238 /* payload 何byte処理したか等管理するべき */
1100 } 1239 }
1101 return 0; /* PMT の場合は処理終わり */ 1240 return 0; /* PMT の場合は処理終わり */
1102 } 1241 }
1242 if ( !sp->esout ) {
1243 /* ES出力しない場合はPES蓄積不要 */
1244 return 0;
1245 }
1246 if ( sp->cat_pids[pid] == 1 ) {
1247 return 0; /* CATは蓄積しない */
1248 }
1249 if ( sp->pesbuf[pid] == NULL ) {
1250 /* PES蓄積不要である場合も蓄積しない */
1251 return 0;
1252 }
1103 1253
1104 /* payload_unit_start_indicatorを処理(2) */ 1254 /* payload_unit_start_indicatorを処理(2) */
1105 /* 必要に応じ、蓄積済みPESの処理と、PES蓄積開始を行う */ 1255 /* 必要に応じ、蓄積済みPESの処理と、PES蓄積開始を行う */
1106 if( payload_unit_start_indicator ){ 1256 if( payload_unit_start_indicator ){
1107 /* PES開始 */ 1257 /* PES開始 */
1108 if ( pes_started ) { 1258 if ( pes_started ) {
1109 /* バッファにデータがあればPES終端なので処理してクリア */ 1259 /* バッファにデータがあればPES終端なので処理してクリア */
1110 pes2es(sp->pesbuf[pid], sp->esbuf[pid], pid, random_access_indicator); 1260 // pes2es(sp->pesbuf[pid], sp->esbuf[pid], pid, random_access_indicator);
1261 pes2es(sp->pesbuf[pid], sp->esbuf[pid], pid);
1111 pesbuf_clear(sp->pesbuf[pid]); 1262 pesbuf_clear(sp->pesbuf[pid]);
1112 } 1263 }
1113 else { 1264 else {
1114 pes_started = 1; 1265 pes_started = 1;
1115 } 1266 }
1122 } 1273 }
1123 /* おつかれさまでした */ 1274 /* おつかれさまでした */
1124 return 0; 1275 return 0;
1125 } 1276 }
1126 1277
1278 #if 0
1279 未使用なため削除
1127 /* PMT_PID から Program(Service ID)を確定させる */ 1280 /* PMT_PID から Program(Service ID)を確定させる */
1128 static int search_pmt_program(splitter *sp, int pid) 1281 static int search_pmt_program(splitter *sp, int pid)
1129 { 1282 {
1130 /* この関数は大変遅いのでなるべく使用しない */ 1283 /* この関数は大変遅いのでなるべく使用しない */
1131 int i; 1284 int i;
1134 return i; 1287 return i;
1135 } 1288 }
1136 } 1289 }
1137 return -1; 1290 return -1;
1138 } 1291 }
1292 #endif
1139 1293
1140 /* esbufが空か判定 (ret. 0:not empty / 1: empty) */ 1294 /* esbufが空か判定 (ret. 0:not empty / 1: empty) */
1141 static int esbuf_empty(splitesbuf_t *esbuf){ 1295 static int esbuf_empty(splitesbuf_t *esbuf){
1142 return esbuf->size == 0; 1296 return esbuf->size == 0;
1143 } 1297 }
1144 1298
1145 /* esbufをクリア */ 1299 /* esbufをクリア */
1146 void esbuf_clear(splitesbuf_t *esbuf){ 1300 void esbuf_clear(splitesbuf_t *esbuf, uint64_t pts, uint64_t dts){
1147 esbuf->random_access_indicator = 0;
1148 esbuf->size = 0; 1301 esbuf->size = 0;
1302 esbuf->pts = pts;
1303 esbuf->dts = dts;
1149 } 1304 }
1150 1305
1151 /* esbufにデータを追加 (ret. 0:success / -1:error) */ 1306 /* esbufにデータを追加 (ret. 0:success / -1:error) */
1152 static int esbuf_add(splitesbuf_t *esbuf, const uint8_t *data, int len){ 1307 static int esbuf_add(splitesbuf_t *esbuf, const uint8_t *data, int len){
1153 if(esbuf->size + len > sizeof esbuf->buffer){ 1308 if(esbuf->size + len > sizeof esbuf->buffer){
1159 } 1314 }
1160 1315
1161 /* 1316 /*
1162 * PESを解析してESを出力する 1317 * PESを解析してESを出力する
1163 */ 1318 */
1164 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid, int random_access_indicator) 1319 //static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid, int random_access_indicator)
1320 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid)
1165 { 1321 {
1166 int len_pesh = 0; 1322 int len_pesh = 0;
1167 int code = 0; 1323 int code = 0;
1168 int flags = 0; 1324 int flags = 0;
1169 int len_pes = 0; 1325 int len_pes = 0;
1182 int audio_lipsync_offset = 0; 1338 int audio_lipsync_offset = 0;
1183 int i = 0; 1339 int i = 0;
1184 int64_t audio_pts = 0; 1340 int64_t audio_pts = 0;
1185 int adts_freq = 0; 1341 int adts_freq = 0;
1186 int64_t adts_frame_time = 0; 1342 int64_t adts_frame_time = 0;
1187 int audio_accumulation = 0; 1343 int gop_start = -1;
1344
1188 /* ありがとう */ 1345 /* ありがとう */
1189 /* ありがとうとコメントを書くと、 1346 /* ありがとうとコメントを書くと、
1190 * 動作がよくなる 1347 * 動作がよくなる
1191 * バグが減る 1348 * バグが減る
1192 * バイナリサイズが小さくなる 1349 * バイナリサイズが小さくなる
1395 1552
1396 p += pes_extension_flags2; 1553 p += pes_extension_flags2;
1397 len_pesh_supposed += pes_extension_flags2; 1554 len_pesh_supposed += pes_extension_flags2;
1398 } 1555 }
1399 } 1556 }
1557 if ( pid != 6417 && pid != 6418 ) {
1558 // printf("es start? pid[%d]\n", pid);
1559 }
1560 /* ES蓄積管理処理 */
1400 payload_length = pesbuf->size -payload_offset; 1561 payload_length = pesbuf->size -payload_offset;
1401 if ( data_alignment_indicator ) { 1562 // if ( data_alignment_indicator ) { /* data_alignment_indicator 区切りでESを出力する */
1402 if ( es_started ) { /* ES にデータが蓄積されている */ 1563 if ( es_started ) { /* ES にデータが蓄積されている */
1403 if ( is_video_stream(pid, esbuf) && !(esbuf->started) ) { /* VIDEO である場合 */ 1564 /*
1404 /* random_access ビットが立っている場合は、GOP先頭である */ 1565 * ビデオをファイル出力し始める条件(1. 2. を満たすこと)
1405 if ( random_access_indicator ) { /* TS の random_access ビットが立ったものがきているか? */ 1566 * 1. ESにGOP先頭を含む
1406 /* 該当ストリームを蓄積開始する */ 1567 * 2. PTSがCUEの時刻を過ぎていること( CUE <= PTS )
1568 */
1569 if ( (is_video_stream(pid, esbuf) == 0) && !(esbuf->started) ) {
1570 /* VIDEO0 を同期の基準とする */
1571 gop_start = search_gop_start_code(esbuf);
1572 if ( (gop_start != -1) && /* ESバッファにGOP_START_CODEが存在するか? */
1573 (esbuf->Program->cue <= esbuf->pts*300) ) { /* CUEを過ぎている? */
1574 /* 該当ストリームをファイル出力開始する */
1407 esbuf->started = 1; 1575 esbuf->started = 1;
1408 esbuf->Program->video_start = 1; 1576 esbuf->Program->video_start = 1;
1409 esbuf->Program->video_pts = esbuf->pts; 1577 esbuf->Program->video_pts = esbuf->pts;
1410 printf("video stream. pid[%d] v_pts[%llu].\n", pid, esbuf->pts); 1578 printf("video stream. pid[%d] v_pts[%llu].\n", pid, esbuf->pts);
1411 } else { 1579 } else {
1412 /* TS の random_access ビットが立ったものがきていない */ 1580 /* GOP先頭を含まないものはクリア */
1413 /* 蓄積開始しない */ 1581 esbuf_clear(esbuf, pesbuf->pts, pesbuf->dts);
1414 esbuf_clear(esbuf); 1582 }
1415 esbuf->pts = pesbuf->pts; 1583 } else if ( (is_video_stream(pid, esbuf) != -1) && !(esbuf->started) ) {
1416 esbuf->dts = pesbuf->dts; 1584 /* VIDEO0 以外のものはVIDEO0 が開始するまでクリア */
1585 if ( !(esbuf->Program->video_start) ) {
1586 /*
1587 * VIDEO0 が始まってない場合、
1588 * VIDEON は常にクリア
1589 */
1590 esbuf_clear(esbuf, pesbuf->pts, pesbuf->dts);
1591 } else {
1592 /*
1593 * VIDEO0 が始まっている場合、
1594 * VIDEON の録画を開始
1595 */
1596 esbuf->started = 1;
1417 } 1597 }
1418 } 1598 }
1419 /* AAC の実験コードここから */
1420 /* 1599 /*
1421 * オーディオを出力し始める条件(1. 2. を満たすこと) 1600 * オーディオをファイル出力し始める条件(1. 2. を満たすこと)
1422 * 1. 動画の蓄積は開始されている 1601 * 1. 動画の蓄積は開始されている
1423 * 2. 動画のGOPの1番目のIピクチャのPTSとオーディオのPTSを比較して以下のどちらかを満たすこと 1602 * 2. 動画のGOPの1番目のIピクチャのPTSとオーディオのPTSを比較して以下のどちらかを満たすこと
1424 * 2.1. 差分が11msec以内 1603 * 2.1. 差分が11msec以内(1000*90k/AACのサンプリング周波数)
1604 * 1000 : ADTSデータの1フレームのサンプル数
1605 * 90k : PTSの周波数
1425 * 2.2. 過ぎている(過ぎている場合はオーディオESの蓄積の継続と次のGOP狙いにする?) 1606 * 2.2. 過ぎている(過ぎている場合はオーディオESの蓄積の継続と次のGOP狙いにする?)
1426 * #GOP先頭にこだわり過ぎると録画を逃すという線もあるので、適当に手を打つのも手 1607 * #動画よりオーディオ側の方が先にESバッファの蓄積を始めるハズなので気にすること無いかなぁ…
1427 */ 1608 */
1428 else if ( (is_audio_stream(pid, esbuf) != -1 ) && !(esbuf->started) ) { 1609 else if ( (is_audio_stream(pid, esbuf) != -1) && !(esbuf->started) ) {
1429 if ( !(esbuf->Program->video_start) ) { 1610 if ( !(esbuf->Program->video_start) ) {
1430 /* 1611 /*
1431 * VIDEO が始まってない場合、 1612 * VIDEO が始まってない場合、
1432 * ESバッファの余裕がある限り蓄積続けちゃえばいいんでない? 1613 * ESバッファの余裕がある限り、オーディオをESバッファに蓄積し続ける
1433 */ 1614 */
1434 audio_accumulation = 1; /* ESバッファにオーディオを追記する */ 1615 if ( esbuf->size + payload_length > sizeof esbuf->buffer ){
1435 if ( esbuf->size > sizeof esbuf->buffer -payload_length ){
1436 /* 溢れそうになったらクリア */ 1616 /* 溢れそうになったらクリア */
1437 esbuf_clear(esbuf); 1617 esbuf_clear(esbuf, pesbuf->pts, pesbuf->dts);
1438 esbuf->pts = pesbuf->pts;
1439 esbuf->dts = pesbuf->dts;
1440 audio_accumulation = 0;
1441 } 1618 }
1442 } 1619 } else if ( esbuf->Program->video_start ) { /* video 蓄積が開始されている?*/
1443 else if ( esbuf->Program->video_start ) { /* video 蓄積が開始されているので音声側の頭を揃える */ 1620 printf("audio stream. pid[%d] a_pts[%llu] v_pts[%llu] size[%d].\n", pid, esbuf->pts, esbuf->Program->video_pts, esbuf->size);
1444 printf("audio stream. pid[%d] a_pts[%llu] v_pts[%llu].\n", pid, esbuf->pts, esbuf->Program->video_pts);
1445 audio_lipsync_offset = 0; 1621 audio_lipsync_offset = 0;
1446 audio_pts = esbuf->pts; 1622 audio_pts = esbuf->pts;
1447 adts_freq = AnalyzeAdifHeader(esbuf); 1623 adts_freq = AnalyzeAdifHeader(esbuf);
1448 adts_frame_time = (int64_t)((float)1000*90000/adts_freq); /* PTSは90KHz */ 1624 adts_frame_time = (int64_t)((float)1000*90000/adts_freq); /* PTSは90KHz */
1625 /* オーディオをフレーム単位で捨ててPTSを進める */
1449 while ( (esbuf->Program->video_pts > audio_pts +adts_frame_time/2) ) { 1626 while ( (esbuf->Program->video_pts > audio_pts +adts_frame_time/2) ) {
1450 /* オーディオデータを捨てると audio_pts は1フレーム分大きくなる */ 1627 /* オーディオデータを捨てると audio_pts は1フレーム分大きくなる */
1451 i = esbuf_adts_start_code_prefix(esbuf, audio_lipsync_offset); /* 次のAACのデータを取得 */ 1628 i = next_adts_start_code(esbuf, audio_lipsync_offset); /* 次のAACのデータを取得 */
1452 if ( i != -1 ) { /* AACデータの終端か? */ 1629 if ( i != -1 ) { /* AACデータの終端か? */
1453 audio_lipsync_offset += i; 1630 audio_lipsync_offset += i;
1454 } else { 1631 } else {
1632 /* バッファ終端まで進めたが、オーディオPTSの方が古い場合ESバッファはクリアする */
1633 esbuf_clear(esbuf, pesbuf->pts, pesbuf->dts);
1455 break; 1634 break;
1456 } 1635 }
1457 printf("audio stream drop. pid[%d] pts[%llu].\n", pid, audio_pts); 1636 printf("audio stream drop. pid[%d] pts[%llu].\n", pid, audio_pts);
1458 audio_pts += adts_frame_time; /* AACの1フレーム分、時間を進める */ 1637 audio_pts += adts_frame_time; /* AACの1フレーム分、時間を進める */
1459 } 1638 }
1461 printf("lipsync start. v_pts[%llu] a_pts[%llu].\n", esbuf->Program->video_pts, audio_pts); 1640 printf("lipsync start. v_pts[%llu] a_pts[%llu].\n", esbuf->Program->video_pts, audio_pts);
1462 memmove(esbuf->buffer +audio_lipsync_offset, 1641 memmove(esbuf->buffer +audio_lipsync_offset,
1463 esbuf->buffer, 1642 esbuf->buffer,
1464 esbuf->size -audio_lipsync_offset); 1643 esbuf->size -audio_lipsync_offset);
1465 esbuf->size -= audio_lipsync_offset; 1644 esbuf->size -= audio_lipsync_offset;
1466 esbuf->started = 1; 1645 esbuf->started = 1; /* オーディオのファイル出力を有効化 */
1467 } 1646 }
1468 } 1647 } else {
1469 else {
1470 ; /* 該当するものは無いはず */ 1648 ; /* 該当するものは無いはず */
1471 } 1649 }
1650 } else {
1651 /* 得に処理なし */
1652 ;
1472 } 1653 }
1473 /* AAC の実験コードここまで */
1474 /* バッファをファイルに出力してクリア */ 1654 /* バッファをファイルに出力してクリア */
1475 if ( esbuf->started ) { 1655 if ( esbuf->started ) { /* 該当ストリームはファイル出力の有効化をされている? */
1476 esbuf_write(esbuf); 1656 esbuf_write(esbuf);
1477 esbuf_clear(esbuf); 1657 esbuf_clear(esbuf, pesbuf->pts, pesbuf->dts);
1478 esbuf->pts = pesbuf->pts;
1479 esbuf->dts = pesbuf->dts;
1480 } 1658 }
1481 } else { 1659 } else {
1482 /* ES蓄積を新たに開始 */ 1660 /* ES蓄積を新たに開始 */
1483 es_started = 1; 1661 es_started = 1;
1484 } 1662 esbuf->pts = pesbuf->pts;
1485 } 1663 esbuf->dts = pesbuf->dts;
1664 }
1665 //}
1486 1666
1487 /* ES蓄積処理 */ 1667 /* ES蓄積処理 */
1488 if ( es_started ) { 1668 if ( es_started ) {
1489 if ( ! audio_accumulation ) { /* オーディオのESバッファへの蓄積をしていない */
1490 esbuf->pts = pesbuf->pts;
1491 esbuf->dts = pesbuf->dts;
1492 }
1493 /* ES蓄積開始済み(これからES蓄積開始を含む)なら、payloadをESとして追加 */ 1669 /* ES蓄積開始済み(これからES蓄積開始を含む)なら、payloadをESとして追加 */
1494 esbuf_add(esbuf, pesbuf->buffer +payload_offset, payload_length); 1670 esbuf_add(esbuf, pesbuf->buffer +payload_offset, payload_length);
1495 } 1671 }
1496 /* お疲れさまでした */ 1672 /* お疲れさまでした */
1497 return 0; 1673 return 0;
1498 } 1674 }
1499 1675
1500 /* PIDはesbufのAUDIO STREAMの一つであるか? */ 1676 /* Program の N 番目の AUDIO STREAM であるかを返却する */
1501 static int is_audio_stream(const int pid, splitesbuf_t *esbuf) 1677 static int is_audio_stream(const int pid, splitesbuf_t *esbuf)
1502 { 1678 {
1503 int i = 0; 1679 int i = 0;
1504 int found = 0;
1505 program_t* program = esbuf->Program; 1680 program_t* program = esbuf->Program;
1506 while (i < program->audio_nb) 1681 while (i < program->audio_nb)
1507 { 1682 {
1508 if (program->audio[i] == pid) { 1683 if (program->audio[i] == pid) {
1509 found = 1; 1684 return i;
1510 break;
1511 } 1685 }
1512 i++; 1686 i++;
1513 } 1687 }
1514 return found; 1688 return -1;
1515 } 1689 }
1516 1690
1517 /* PIDはesbufのVIDEO STREAMの一つであるか? */ 1691 /* Program の N 番目の VIDEO STREAM であるかを返却する */
1518 static int is_video_stream(const int pid, splitesbuf_t *esbuf) 1692 static int is_video_stream(const int pid, splitesbuf_t *esbuf)
1519 { 1693 {
1520 int i = 0; 1694 int i = 0;
1521 int found = 0;
1522 program_t* program = esbuf->Program; 1695 program_t* program = esbuf->Program;
1523 while (i < program->video_nb) 1696 while (i < program->video_nb)
1524 { 1697 {
1525 if (program->video[i] == pid) { 1698 if (program->video[i] == pid) {
1526 found = 1; 1699 return i;
1527 break;
1528 } 1700 }
1529 i++; 1701 i++;
1530 } 1702 }
1531 return found; 1703 return -1;
1532 } 1704 }
1533 1705
1534 /* 1706 /*
1535 * ESをファイル出力する 1707 * ESをファイル出力する
1708 * エラーハンドリングしてないね…
1536 */ 1709 */
1537 //int esbuf_write(splitesbuf_t *esbuf, int pid) 1710 static int esbuf_write(splitesbuf_t *esbuf)
1538 int esbuf_write(splitesbuf_t *esbuf)
1539 { 1711 {
1540 int remain = esbuf->size; 1712 int remain = esbuf->size;
1541 //#define ES_FILE "/tmp/es.%d"
1542 // char filename[1024];
1543 // filename[0] = '\0';
1544 // umask(0133);
1545 // snprintf(filename, sizeof(filename), ES_FILE, pid);
1546 // fd = open(filename, O_CREAT|O_APPEND|O_RDWR, 00644);
1547 while(remain > 0) 1713 while(remain > 0)
1548 { 1714 {
1549 remain -= write(esbuf->fd, esbuf->buffer+(esbuf->size-remain), remain); 1715 remain -= write(esbuf->fd, esbuf->buffer+(esbuf->size-remain), remain);
1550 } 1716 }
1551 // close(fd);
1552 return 0; 1717 return 0;
1553 } 1718 }
1554 1719
1720 #if 0
1721 未使用なため駆除
1555 /* 1722 /*
1556 * packet dump 1723 * packet dump
1557 */ 1724 */
1558 void dump_packet( const uint8_t *packet ) 1725 void dump_packet( const uint8_t *packet )
1559 { 1726 {
1579 } 1746 }
1580 i++; 1747 i++;
1581 } 1748 }
1582 putchar('\n'); 1749 putchar('\n');
1583 } 1750 }
1751 #endif
1584 1752
1585 /* 1753 /*
1586 * TOT の JST_time を解析する 1754 * TOT の JST_time を解析する
1587 */ 1755 */
1588 static int parse_tot( const unsigned char* packet, time_t *t ) 1756 static int parse_tot( const unsigned char* packet, time_t *t )
1644 static int get_pmt_version(const uint8_t *p) 1812 static int get_pmt_version(const uint8_t *p)
1645 { 1813 {
1646 return ((p[6] >> 1) & 0x1f); 1814 return ((p[6] >> 1) & 0x1f);
1647 } 1815 }
1648 1816
1649
1650 #if 0 1817 #if 0
1651 void forward_stc(timespec *stc, timespec offset) 1818 未使用なため駆除
1652 {
1653 struct timespec local_timespec;
1654
1655 clock_gettime(CLOCK_REALTIME, &local_timespec);
1656
1657 stc->tv_sec = local_timespec.tv_sec + offset.tv_sec;
1658 stc->tv_nsec = local_timespec.tv_nsec + offset.tv_nsec;
1659 if ( stc->tv_nsec >= 1 * 1000 * 1000 * 1000 ) {
1660 stc->tv_nsec -= 1 * 1000 * 1000 * 1000;
1661 stc->tv_sec += 1;
1662 } else if ( stc->tv_nsec < 0 ) {
1663 stc->tv_nsec = 1 * 1000 * 1000 * 1000 + stc->tv_nsec;
1664 stc->tv_sec -= 1;
1665 }
1666 }
1667 #endif
1668 void search_mpeg_system_header(const uint8_t *packet) 1819 void search_mpeg_system_header(const uint8_t *packet)
1669 { 1820 {
1670 int i; 1821 int i;
1671 uint8_t *p = (uint8_t*)packet; 1822 uint8_t *p = (uint8_t*)packet;
1672 i = 0; 1823 i = 0;
1674 if( p[i] == 0x00 && p[i+1] == 0x00 && p[i+2] == 0x01 && p[i+3] == 0xb8 ){ 1825 if( p[i] == 0x00 && p[i+1] == 0x00 && p[i+2] == 0x01 && p[i+3] == 0xb8 ){
1675 dump_packet(packet ); 1826 dump_packet(packet );
1676 } 1827 }
1677 } 1828 }
1678 } 1829 }
1830 #endif
1679 1831
1680 /* 1832 /*
1681 * この関数では、現在の仕様では、先頭位置の「次の」ADTS start codeまでの長さを返却する 1833 * この関数では、現在の仕様では、先頭位置の「次の」ADTS start codeまでの長さを返却する
1682 * ret == 0 : 仕様上あり得ない 1834 * ret == 0 : 仕様上あり得ない(esbuf先頭はヘッダ先頭であるため)
1683 * ret > 0 : 見つかった場合 1835 * ret > 0 : 見つかった場合
1684 * ret == -1 : 見つからなかった場合 1836 * ret == -1 : 見つからなかった場合
1685 */ 1837 */
1686 static int esbuf_adts_start_code_prefix(splitesbuf_t *esbuf, int offset) 1838 static int next_adts_start_code(splitesbuf_t *esbuf, int offset)
1687 { 1839 {
1688 /* 1840 /*
1689 * start code prefix のうち、先頭12bit は 1 固定であるが、13bit 目は id に該当 1841 * start code prefix のうち、先頭12bit は 1 固定
1690 * MPEG4なオーディオが来た場合に対応出来ないので、13bit 目は見ないように改造するべき
1691 */ 1842 */
1692 uint8_t adts_start_code_prefix[2] = {0xFF, 0xF8}; /* とりあえず決め打ち */ 1843 uint16_t adts_start_code = 0xfff0;
1693 int i = offset +1; 1844 int i = offset +1;
1845 uint16_t startcode = 0;
1694 1846
1695 /* 小さすぎる */ 1847 /* 小さすぎる */
1696 if(esbuf->size -offset < sizeof adts_start_code_prefix){ 1848 if(esbuf->size -offset < sizeof(adts_start_code)){
1697 return -1; 1849 return -1;
1698 } 1850 }
1699 for(; i < esbuf->size - sizeof adts_start_code_prefix; i++) { 1851 for(; i < esbuf->size - sizeof(adts_start_code); i++) {
1700 if(!memcmp(esbuf->buffer + i ,adts_start_code_prefix, sizeof adts_start_code_prefix)){ 1852 startcode = AV_RB16(esbuf->buffer+i);
1853 if( startcode == adts_start_code ) { /* 該当位置から12bit連続1が立っているか? */
1701 #if 0 1854 #if 0
1702 printf("adts start code found.i[%d]. 0[%02x] 1[%02x] 2[%02x] 3[%02x] 4[%02x] 5[%02x] 6[%02x]\n", 1855 printf("adts start code found.i[%d]. 0[%02x] 1[%02x] 2[%02x] 3[%02x] 4[%02x] 5[%02x] 6[%02x]\n",
1703 i, *(esbuf->buffer+i+0), *(esbuf->buffer+i+1), *(esbuf->buffer+i+2), *(esbuf->buffer+i+3), *(esbuf->buffer+i+4), *(esbuf->buffer+i+5), *(esbuf->buffer+i+6) ); 1856 i, *(esbuf->buffer+i+0), *(esbuf->buffer+i+1), *(esbuf->buffer+i+2), *(esbuf->buffer+i+3), *(esbuf->buffer+i+4), *(esbuf->buffer+i+5), *(esbuf->buffer+i+6) );
1704 #endif 1857 #endif
1705 return (i-offset); 1858 return (i-offset);
1709 } 1862 }
1710 1863
1711 /* ADIF HEADER解析 */ 1864 /* ADIF HEADER解析 */
1712 static int AnalyzeAdifHeader(splitesbuf_t *esbuf) 1865 static int AnalyzeAdifHeader(splitesbuf_t *esbuf)
1713 { 1866 {
1714 int id = 0; /* 0:MPEG-4 1:MPEG-2 */ 1867 int id = 0; /* 0:MPEG-4 1:MPEG-2 */
1715 int layer = 0; /* 常に 0x00 */ 1868 int layer = 0; /* 常に 0x00 */
1716 int protection_absent = 0; /*保護属性 0:保護なし 1:保護あり */ 1869 int protection_absent = 0; /* 保護属性 0:保護なし 1:保護あり */
1717 int profile = 0; /* 00:MAIN 01:LC 10:SSR 11:(reserved) */ 1870 int profile = 0; /* 00:MAIN 01:LC 10:SSR 11:(reserved) */
1718 int sampling_frequency_index = 0; /* サンプリング周波数テーブル値 */ 1871 int sampling_frequency_index = 0; /* サンプリング周波数テーブル値 */
1719 int private_bit = 0; /* private bit */ 1872 int private_bit = 0; /* private bit */
1720 int channel_configuration = 0; /* チャンネル数 */ 1873 int channel_configuration = 0; /* チャンネル数 */
1721 int original_copy = 0; 1874 int original_copy = 0;
1722 int home = 0; /* homeってなに? */ 1875 int home = 0; /* homeってなに? */
1723 int copyright_identification_bit = 0; /* 著作権証明ビット */ 1876 int copyright_identification_bit = 0; /* 著作権証明ビット */
1724 int copyright_identification_start = 0; /* 著作権証明開始ビット */ 1877 int copyright_identification_start = 0; /* 著作権証明開始ビット */
1725 int aac_frame_length = 0; /* AACフレーム長 */ 1878 int aac_frame_length = 0; /* AACフレーム長 */
1726 int adts_buffer_fullness = 0; /* ADTSバッファ残量 */ 1879 int adts_buffer_fullness = 0; /* ADTSバッファ残量 */
1727 int no_raw_data_blocks_in_frame = 0; /* データブロックまでの残量 */ 1880 int no_raw_data_blocks_in_frame = 0; /* データブロックまでの残量 */
1728 /* 1881 /*
1729 * サンプリング周波数テーブル(ヘッダのINDEXが添字) 1882 * サンプリング周波数テーブル(ヘッダのsampling_frequency_indexが添字)
1730 * 単位:Hz 1883 * 単位:Hz
1731 */ 1884 */
1732 int sampling_frequency_table[16] = 1885 int sampling_frequency_table[16] =
1733 { 1886 {
1734 96000, 1887 96000,
1845 static int get_adts_no_raw_data_blocks_in_frame(uint8_t *p) 1998 static int get_adts_no_raw_data_blocks_in_frame(uint8_t *p)
1846 { 1999 {
1847 return (*p & 0x03); 2000 return (*p & 0x03);
1848 } 2001 }
1849 2002
2003 #define GOP_START_CODE (0x000001b8)
1850 /* GOP START CODE を検索する */ 2004 /* GOP START CODE を検索する */
1851 static int search_gop_start_code(splitesbuf_t *esbuf) 2005 static int search_gop_start_code(splitesbuf_t *esbuf)
1852 { 2006 {
1853 uint8_t gop_start_code[4] = {0x00, 0x00, 0x01, 0xb8}; 2007 uint32_t gop_start_code = GOP_START_CODE;
1854 int i; 2008 int i;
1855 2009
1856 /* 小さすぎる */ 2010 /* 小さすぎる */
1857 if ( esbuf->size < sizeof gop_start_code ){ 2011 if ( esbuf->size < sizeof gop_start_code ){
1858 return -1; 2012 return -1;
1859 } 2013 }
1860 for(i = 0; i < esbuf->size - sizeof gop_start_code; i++) { 2014 for(i = 0; i < esbuf->size - sizeof gop_start_code; i++) {
1861 if(!memcmp(esbuf->buffer +i ,gop_start_code, sizeof gop_start_code)){ 2015 if ( (AV_RB32(esbuf->buffer +i)) == gop_start_code ) {
1862 return i; 2016 return i;
1863 } 2017 }
1864 } 2018 }
1865 return -1; 2019 return -1;
1866 } 2020 }
1867 2021
1868 /* ES 出力するファイル名を決定する */ 2022 /* ES 出力するファイルを作成する */
1869 //static int creat_filename(char *base, char *filename, int sid, int pid, int av_flag ,splitesbuf_t *esbuf) 2023 static int creat_es_file(splitter *sp, int sid, int pid, int av_flag)
1870 static int creat_filename(splitter *sp, int sid, int pid, int av_flag)
1871 { 2024 {
1872 /* 2025 /*
1873 * 出力ESファイルの命名規則は以下とする 2026 * 出力ESファイルの命名規則は以下とする
1874 * 2027 *
1875 * ファイル名のベースは出力TSファイル名 2028 * ファイル名のベースは --es オプションの引数
1876 * 出力先パスも出力TSファイル名から取得 2029 * 以下の形式で命名して、ファイルオープンまで実施する。
1877 * ファイル名のうち、「.ts」を削除して、sidとepidをつけて、「.es」とする 2030 * ファイル名prefix_SID_AVのプログラム内番号.m2v
1878 * .m2v とか .m2a とかそういう名前って好きではないのだけど...ISOに既定ないし 2031 * ファイル名prefix_SID_AVのプログラム内番号.aac
1879 * オーディオなのか、ビデオなのかって情報はあるけど 2032 *
2033 * !!注意!!
2034 * MPEG-2/MPEG-4 AAC 以外のオーディオが来た場合の処理が未実装
1880 */ 2035 */
1881 2036
1882 char filename[PATH_MAX]; 2037 char filename[PATH_MAX];
1883 int size = 0; 2038 int size = 0;
1884 char *suffix = NULL; 2039 char *suffix = NULL;
1885 int av_nb = 0; 2040 int av_nb = 0;
1886 char suffix_a[] = "aac"; 2041 char suffix_a[] = "aac";
1887 char suffix_v[] = "m2v"; 2042 char suffix_v[] = "m2v";
1888 filename[0] = '\0'; 2043 filename[0] = '\0';
1889 2044
1890 if ( av_flag == 1 ) { 2045 /* ちょっとこの辺のコードイケてないので後から直すかも */
2046 if ( av_flag == TSS_STREAM_TYPE_VIDEO ) {
1891 suffix = suffix_v; 2047 suffix = suffix_v;
1892 av_nb = sp->program[sid].video_nb -1; 2048 av_nb = sp->program[sid].video_nb -1;
1893 } else if ( av_flag == 2 ){ 2049 } else if ( av_flag == TSS_STREAM_TYPE_AUDIO ){
1894 suffix = suffix_a; 2050 suffix = suffix_a;
1895 av_nb = sp->program[sid].audio_nb -1; 2051 av_nb = sp->program[sid].audio_nb -1;
1896 } else { 2052 } else {
1897 /* ここはありえない */ 2053 /* ここはありえない */
1898 return -1; 2054 return -1;
1899 } 2055 }
1900 size = strlen(sp->filename); 2056 size = strlen(sp->filename);
1901 2057
1902 if ( size +16 < sizeof(filename) ) { 2058 if ( size +16 < sizeof(filename) ) {
1903 snprintf(filename, sizeof(filename), "%s_%04d_%02d.%s", sp->filename, sid, av_nb, suffix); 2059 snprintf(filename, sizeof(filename), "%s_%05d_%02d.%s", sp->filename, sid, av_nb, suffix);
1904 filename[PATH_MAX-1] = '\0'; 2060 filename[PATH_MAX-1] = '\0';
1905 } else { 2061 } else {
1906 /* ファイル名つけられなくて困るでござるの巻 */ 2062 /* ファイル名つけられなくて困るでござるの巻 */
1907 return -1; 2063 return -1;
1908 } 2064 }
1909 umask(0133); 2065 umask(0133);
1910 if ( !(sp->esbuf[pid]->fd = open(filename, O_CREAT|O_APPEND|O_RDWR, 00644)) ) { 2066 if ( !(sp->esbuf[pid]->fd = open(filename, O_CREAT|O_APPEND|O_RDWR, 00644)) ) {
1911 fprintf("cannot open es out file. file[%s].\n", filename); 2067 fprintf(stderr, "cannot open es out file. file[%s].\n", filename);
1912 return -1; 2068 return -1;
1913 } 2069 }
1914 return 0; 2070 return 0;
1915 } 2071 }
2072
2073 static time_t cue2time(char *yyyymmddhhmiss)
2074 {
2075 struct tm cue_tm;
2076 time_t cue_time;
2077 char *p;
2078 int i, j;
2079 char str_yyyy[5];
2080 char str_mm[3];
2081 char str_dd[3];
2082 char str_hh[3];
2083 char str_mi[3];
2084 char str_ss[3];
2085 str_yyyy[0] = '\0';
2086 str_mm[0] = '\0';
2087 str_dd[0] = '\0';
2088 str_hh[0] = '\0';
2089 str_mi[0] = '\0';
2090 str_ss[0] = '\0';
2091
2092 p = yyyymmddhhmiss;
2093 i = strlen(p);
2094 j = strspn(p, LIST_DECIMAL);
2095 if ( i != j && i != 14 ) {
2096 /* 数字以外混ぜるな */
2097 return -1;
2098 }
2099 strncpy(str_yyyy, yyyymmddhhmiss, 4);
2100 strncpy(str_mm, yyyymmddhhmiss+4, 2);
2101 strncpy(str_dd, yyyymmddhhmiss+6, 2);
2102 strncpy(str_hh, yyyymmddhhmiss+8, 2);
2103 strncpy(str_mi, yyyymmddhhmiss+10, 2);
2104 strncpy(str_ss, yyyymmddhhmiss+12, 2);
2105 str_yyyy[4] = '\0';
2106 str_mm[2] = '\0';
2107 str_dd[2] = '\0';
2108 str_hh[2] = '\0';
2109 str_mi[2] = '\0';
2110 str_ss[2] = '\0';
2111
2112 cue_tm.tm_sec = atoi(str_ss);
2113 cue_tm.tm_min = atoi(str_mi);
2114 cue_tm.tm_hour = atoi(str_hh);
2115 cue_tm.tm_mday = atoi(str_dd);
2116 cue_tm.tm_mon = atoi(str_mm)-1;
2117 cue_tm.tm_year = atoi(str_yyyy)-1900;
2118 cue_tm.tm_isdst = -1;
2119 cue_time = mktime(&cue_tm);
2120 return cue_time;
2121 }
2122
2123 /* PCR の PID を検索する */
2124 static int search_pcr_pid(splitter *sp, int pid)
2125 {
2126 int i;
2127 for ( i=0; i < MAX_SERVICES; i++ ) {
2128 if ( sp->pcr[i].pid == pid ) {
2129 return i;
2130 }
2131 }
2132 return -1;
2133 }