Mercurial > pt1.oyama
comparison recpt1/tssplitter_lite.c @ 119:4e7aaa72e158
ES out early release version.
author | Naoya OYAMA <naoya.oyama@gmail.com> |
---|---|
date | Mon, 19 Apr 2010 00:30:09 +0900 |
parents | ac39bb18136e |
children | 8e438d2a1529 |
comparison
equal
deleted
inserted
replaced
118:caecbba2a76f | 119:4e7aaa72e158 |
---|---|
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> | |
28 #include "decoder.h" | 30 #include "decoder.h" |
29 #include "recpt1.h" | 31 #include "recpt1.h" |
30 #include "tssplitter_lite.h" | 32 #include "tssplitter_lite.h" |
33 | |
34 #ifndef AV_RB32 | |
35 #define AV_RB32(x) ((((const uint8_t*)(x))[0] << 24) | \ | |
36 (((const uint8_t*)(x))[1] << 16) | \ | |
37 (((const uint8_t*)(x))[2] << 8) | \ | |
38 ((const uint8_t*)(x))[3]) | |
39 #endif | |
40 | |
41 #ifndef AV_RB24 | |
42 #define AV_RB24(x) ((((const uint8_t*)(x))[0] << 16) | \ | |
43 (((const uint8_t*)(x))[1] << 8) | \ | |
44 ((const uint8_t*)(x))[2]) | |
45 #endif | |
46 | |
47 #ifndef AV_RB16 | |
48 #define AV_RB16(x) ((((const uint8_t*)(x))[0] << 8) | ((const uint8_t*)(x))[1]) | |
49 #endif | |
50 | |
31 | 51 |
32 /* prototypes */ | 52 /* prototypes */ |
33 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf); | 53 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf); |
34 static int AnalyzePat(splitter *sp, unsigned char *buf); | 54 static int AnalyzePat(splitter *sp, unsigned char *buf); |
35 static int RecreatePat(splitter *sp, unsigned char *buf, int *pos); | 55 static int RecreatePat(splitter *sp, unsigned char *buf, int *pos); |
36 static char** AnalyzeSid(char *sid); | 56 static char** AnalyzeSid(char *sid); |
37 static int AnalyzePmt(splitter *sp, unsigned char *buf); | 57 static int AnalyzePmt(splitter *sp, const uint8_t *buf, int sid, const int size); |
38 static int GetCrc32(unsigned char *data, int len); | 58 static int GetCrc32(unsigned char *data, int len); |
39 static int GetPid(unsigned char *data); | 59 static int GetPid(unsigned char *data); |
60 static int parse_tot( const unsigned char* packet, time_t *t ); | |
61 void dump_packet( const uint8_t *packet ); | |
62 static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, const uint8_t *packet); | |
63 //static int parse_pts(int64_t *ppts, int64_t *pdts, const uint8_t *packet, int *len_pes, splitesbuf_t *esbuf, const int pid); | |
64 //static int ts2pes(int64_t *ppts, int64_t *pdts, const uint8_t *packet, splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid); | |
65 static int DemuxTs(const uint8_t *packet, splitter *sp, const int pid, int *random_access); | |
66 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid); | |
67 static int64_t get_pts(const uint8_t *p); | |
68 void search_mpeg_system_header(const uint8_t *p); | |
69 int esbuf_write(splitesbuf_t *esbuf, int pid); | |
70 //void forward_stc(timespec *stc, timespec offset); | |
71 // | |
72 | |
73 static int pesbuf_packet_start_code_prefix(splitpesbuf_t *pesbuf); | |
74 static int pesbuf_empty(splitpesbuf_t *pesbuf); | |
75 void pesbuf_clear(splitpesbuf_t *pesbuf); | |
76 static int pesbuf_add(splitpesbuf_t *pesbuf, const uint8_t *data, int len); | |
77 static int esbuf_empty(splitesbuf_t *esbuf); | |
78 void esbuf_clear(splitesbuf_t *esbuf); | |
79 static int esbuf_add(splitesbuf_t *esbuf, const uint8_t *data, int len); | |
80 static int get_pmt_version(const uint8_t *p); | |
81 static int esbuf_adts_start_code_prefix(splitesbuf_t *esbuf, int offset); | |
82 static int is_video_stream(const int pid, splitesbuf_t *esbuf); | |
83 static int is_audio_stream(const int pid, splitesbuf_t *esbuf); | |
84 static int AnalyzeAdifHeader(splitesbuf_t *esbuf); | |
85 static int get_adif_id(uint8_t *p); | |
86 static int get_adif_layer(uint8_t *p); | |
87 static int get_adif_protection_absent(uint8_t *p); | |
88 static int get_adif_profile(uint8_t *p); | |
89 static int get_adif_sampling_frequency_index(uint8_t *p); | |
90 static int get_adif_private_bit(uint8_t *p); | |
91 static int get_adif_channel_configuration(uint8_t *p); | |
92 static int get_adif_original_copy(uint8_t *p); | |
93 static int get_adif_home(uint8_t *p); | |
94 static int get_adif_copyright_idication_bit(uint8_t *p); | |
95 static int get_adif_copyright_idication_start(uint8_t *p); | |
96 static int get_adif_aac_frame_length(uint8_t *p); | |
97 static int get_adts_buffer_fullness(uint8_t *p); | |
98 static int get_adts_no_raw_data_blocks_in_frame(uint8_t *p); | |
99 static int search_pmt_program(splitter *sp, int pid); | |
100 static int search_gop_start_code(splitesbuf_t *esbuf); | |
40 | 101 |
41 /** | 102 /** |
42 * サービスID解析 | 103 * サービスID解析 |
43 */ | 104 */ |
44 static char** AnalyzeSid( | 105 static char** AnalyzeSid( |
138 splitter* split_startup( | 199 splitter* split_startup( |
139 char *sid // [in] サービスID(引数で指定した文字列) | 200 char *sid // [in] サービスID(引数で指定した文字列) |
140 ) | 201 ) |
141 { | 202 { |
142 splitter* sp; | 203 splitter* sp; |
204 int i; | |
143 sp = malloc(sizeof(splitter)); | 205 sp = malloc(sizeof(splitter)); |
144 if ( sp == NULL ) | 206 if ( sp == NULL ) |
207 { | |
208 fprintf(stderr, "split_startup malloc error.\n"); | |
209 return NULL; | |
210 } | |
211 #define MAX_SERVICE_ID ( 0xffff ) | |
212 sp->program = malloc( sizeof(program_t) * MAX_SERVICE_ID ); | |
213 if ( sp->program == NULL ) | |
145 { | 214 { |
146 fprintf(stderr, "split_startup malloc error.\n"); | 215 fprintf(stderr, "split_startup malloc error.\n"); |
147 return NULL; | 216 return NULL; |
148 } | 217 } |
149 memset(sp->pids, 0, sizeof(sp->pids)); | 218 memset(sp->pids, 0, sizeof(sp->pids)); |
158 return NULL; | 227 return NULL; |
159 } | 228 } |
160 sp->pat_count = 0xFF; | 229 sp->pat_count = 0xFF; |
161 sp->pmt_retain = -1; | 230 sp->pmt_retain = -1; |
162 sp->pmt_counter = 0; | 231 sp->pmt_counter = 0; |
232 // sp->STC_timespec.tv_sec = 0; | |
233 // sp->STC_timespec.tv_nsec = 0; | |
234 // sp->tot_offset.tv_sec = 0; | |
235 // sp->tot_offset.tv_nsec = 0; | |
236 sp->cue_time = -1; | |
237 sp->stc = 0; | |
238 sp->status = 1; | |
239 memset(sp->esbuf, 0, sizeof(splitesbuf_t *)*MAX_PID); | |
240 memset(sp->pesbuf, 0, sizeof(splitpesbuf_t *)*MAX_PID); | |
241 memset(sp->program, 0, sizeof(program_t *)*MAX_SERVICE_ID); | |
242 for ( i=0; i < MAX_PID; i++ ) { | |
243 /* pmt_version は (N%32) の値を取るので、0 で初期化してはならない */ | |
244 sp->program[i].pmt_version = -1; | |
245 } | |
246 memset(sp->pid_sid_table, 0, sizeof(int)*MAX_PID); | |
163 | 247 |
164 return sp; | 248 return sp; |
165 } | 249 } |
166 | 250 |
167 /** | 251 /** |
211 unsigned char **pat, // [out] PAT 情報(再構築後) | 295 unsigned char **pat, // [out] PAT 情報(再構築後) |
212 unsigned char* pids, // [out] 出力対象 PID 情報 | 296 unsigned char* pids, // [out] 出力対象 PID 情報 |
213 char** sid_list, // [in] 出力対象サービス ID のリスト | 297 char** sid_list, // [in] 出力対象サービス ID のリスト |
214 unsigned char* pmt_pids, // [in] 出力対象PIDのPMT PID | 298 unsigned char* pmt_pids, // [in] 出力対象PIDのPMT PID |
215 , // [in] pt1_drvの入力TS | 299 , // [in] pt1_drvの入力TS |
216 int* pmt_retain, // [in] 残すべきPMTの数 | 300 int* pmt_retain, // [in] PMTの落とすべき数 |
217 int* pmt_counter // [out] 残したPMTの数 | 301 int* pmt_counter // [out] PMTの落とした数 |
218 #endif | 302 #endif |
219 | 303 |
220 int length = sbuf->size; | 304 int length = sbuf->size; |
221 int pid; | 305 int pid; |
222 int result = TSS_ERROR; | 306 int result = TSS_ERROR; |
224 | 308 |
225 index = 0; | 309 index = 0; |
226 while(length - index - LENGTH_PACKET > 0) { | 310 while(length - index - LENGTH_PACKET > 0) { |
227 pid = GetPid(sbuf->data + index + 1); | 311 pid = GetPid(sbuf->data + index + 1); |
228 // PAT | 312 // PAT |
229 if(0x0000 == pid) { | 313 if(PAT == pid) { |
314 dump_packet(sbuf->data + index); | |
230 result = AnalyzePat(sp, sbuf->data + index); | 315 result = AnalyzePat(sp, sbuf->data + index); |
231 if(TSS_SUCCESS != result) { | 316 if(TSS_SUCCESS != result) { |
232 /* 下位の関数内部でmalloc error発生 */ | 317 /* 下位の関数内部でmalloc error発生 */ |
233 return result; | 318 return result; |
234 } | 319 } |
236 | 321 |
237 // PMT | 322 // PMT |
238 /* 残すpmt_pidである場合には、pmtに書かれている | 323 /* 残すpmt_pidである場合には、pmtに書かれている |
239 * 残すべきPCR/AUDIO/VIDEO PIDを取得する */ | 324 * 残すべきPCR/AUDIO/VIDEO PIDを取得する */ |
240 if(sp->pmt_pids[pid] == 1) { | 325 if(sp->pmt_pids[pid] == 1) { |
326 /* | |
327 * program(番組)とServiceID をベースに管理することにしているので、 | |
328 * pmt_pidsとかもう必要ないかも… | |
329 */ | |
241 /* この中にはPMT毎に一度しか入らないようにしておく */ | 330 /* この中にはPMT毎に一度しか入らないようにしておく */ |
242 AnalyzePmt(sp, sbuf->data + index); | 331 int random_access; |
332 //AnalyzePmt(sp, sbuf->data + index, pid); | |
333 //AnalyzePmt(sp, sbuf->data + index +4, pid, LENGTH_PACKET-4); | |
243 sp->pmt_pids[pid]++; | 334 sp->pmt_pids[pid]++; |
244 sp->pmt_counter += 1; | 335 sp->pmt_counter += 1; |
336 DemuxTs(sbuf->data +index, sp, pid, &random_access); /* AnalyzePmt より DemuxTs の方がアダプテーションフィールドの処理が良いので変更 */ | |
245 } | 337 } |
246 /* 録画する全てのPMTについて、中にあるPCR/AUDIO/VIDEOのPIDを | 338 /* 録画する全てのPMTについて、中にあるPCR/AUDIO/VIDEOのPIDを |
247 * 得る */ | 339 * 得る */ |
248 /* pmt_counter と pmt_retain が一致する場合に条件は満たされる */ | 340 /* pmt_counter と pmt_retain が一致する場合に条件は満たされる */ |
249 if(sp->pmt_counter == sp->pmt_retain) { | 341 if(sp->pmt_counter == sp->pmt_retain) { |
270 { | 362 { |
271 int pid; | 363 int pid; |
272 unsigned char *sptr, *dptr; | 364 unsigned char *sptr, *dptr; |
273 int s_offset = 0; | 365 int s_offset = 0; |
274 int d_offset = 0; | 366 int d_offset = 0; |
367 int64_t pcr; | |
368 int64_t pcr_h; | |
369 int pcr_l; | |
370 struct timespec tot_timespec; | |
371 struct timespec local_timespec; | |
372 int len_pes; | |
373 int random_access; | |
374 int sid; | |
275 | 375 |
276 /* 初期化 */ | 376 /* 初期化 */ |
277 dbuf->size = 0; | 377 dbuf->size = 0; |
278 if (sbuf->size < 0) { | 378 if (sbuf->size < 0) { |
279 return TSS_ERROR; | 379 return TSS_ERROR; |
280 } | 380 } |
281 | 381 |
282 sptr = sbuf->data; | 382 sptr = sbuf->data; |
283 dptr = dbuf->buffer; | 383 dptr = dbuf->buffer; |
384 #if 0 | |
385 /* TOT受信済みであるなら、STC を成長させる */ | |
386 if ( sp->tot_offset.tv_nsec != 0 && sp->tot_offset.tv_sec != 0) { | |
387 forward_stc(&(sp->STC_timespec), sp->tot_offset); | |
388 } | |
389 #endif | |
284 | 390 |
285 while(sbuf->size > s_offset) { | 391 while(sbuf->size > s_offset) { |
286 pid = GetPid(sptr + s_offset + 1); | 392 pid = GetPid(sptr + s_offset + 1); |
393 sid = splitter->pid_sid_table[pid]; | |
287 switch(pid) { | 394 switch(pid) { |
288 | 395 |
289 // PAT | 396 // PAT |
290 case 0x0000: | 397 case PAT: |
291 // 巡回カウンタカウントアップ | 398 // 巡回カウンタカウントアップ |
292 if(0xFF == splitter->pat_count) { | 399 if(0xFF == splitter->pat_count) { |
293 splitter->pat_count = splitter->pat[3]; | 400 splitter->pat_count = splitter->pat[3]; |
294 } | 401 } |
295 else { | 402 else { |
296 splitter->pat_count += 1; | 403 splitter->pat_count = (splitter->pat_count + 1) % 16; |
297 if(0 == splitter->pat_count % 0x10) { | |
298 splitter->pat_count -= 0x10; | |
299 } | |
300 } | 404 } |
301 splitter->pat[3] = splitter->pat_count; | 405 splitter->pat[3] = splitter->pat_count; |
302 | 406 |
303 memcpy(dptr + d_offset, splitter->pat, LENGTH_PACKET); | 407 memcpy(dptr + d_offset, splitter->pat, LENGTH_PACKET); |
304 d_offset += LENGTH_PACKET; | 408 d_offset += LENGTH_PACKET; |
305 dbuf->size += LENGTH_PACKET; | 409 dbuf->size += LENGTH_PACKET; |
306 break; | 410 break; |
411 case TOT: | |
412 /* TOT に TDTの情報全てが含まれており、実放送では TOT しか送信されない */ | |
413 /* TOT は 500msec の誤差が保証されている | |
414 * 閏秒の場合は最大1.5秒の誤差となる | |
415 */ | |
416 #if 0 | |
417 if ( sp->tot_offset.tv_nsec != 0 && sp->tot_offset.tv_sec != 0 ) { | |
418 parse_tot(sptr + s_offset, &(tot_timespec.tv_sec)); | |
419 clock_gettime(CLOCK_REALTIME, &local_timespec); | |
420 | |
421 /* TOT をSystem Time Clock(STC)に入れる */ | |
422 sp->STC_timespec.tv_sec = tot_timespec.tv_sec; | |
423 sp->STC_timespec.tv_nsec = tot_timespec.tv_nsec; | |
424 | |
425 /* TOT と localtime の差分を sp->tot_offset に入れる */ | |
426 sp->tot_offset.tv_sec = tot_timespec.tv_sec - local_timespec.tv_sec; | |
427 sp->tot_offset.tv_nsec = tot_timespec.tv_nsec - local_timespec.tv_nsec; | |
428 } | |
429 #endif | |
430 /* STC が既にあるならTOT受信時に頭出し時刻を決定する */ | |
431 /* 59秒9990 あたりを頭出し時刻に設定でよいかな */ | |
432 if ( splitter->stc != 0 && splitter->cue_time == -1) { | |
433 /* TOT から cue_time を計算する */ | |
434 /* えいや。で、59秒9990固定決め打ち */ | |
435 parse_tot(sptr + s_offset, &(tot_timespec.tv_sec)); | |
436 //cue_second = ((tot_timespec.tv_sec % 60) - 59); | |
437 splitter->cue_time = splitter->stc + (((59 - (tot_timespec.tv_sec % 60))*(27*1000*1000)) + floor((27*1000*1000)*0.999)); | |
438 //printf("stc[%lld]. cue_time[%lld].\n", splitter->stc, splitter->cue_time); | |
439 | |
440 } else { | |
441 /* TOT受診時にSTCが存在しないならTOTは捨てる */ | |
442 } | |
443 break; | |
307 default: | 444 default: |
445 /* 時間管理に関しての実装方針 */ | |
446 /* | |
447 * 時間関係を扱っている変数のまとめ | |
448 * PCR : 42Bit @27MHz(プログラム毎に独立) | |
449 * PTS : 42Bit @90KHz(SYSTEM ID(ES)毎に独立) | |
450 * DTS : 42Bit @90KHz(SYSTEM ID(ES)毎に独立) | |
451 * TOT : MJD + 2進化10進数(ストリームに一つだけ) | |
452 * STC : 64Bit @27MHz(システムローカル時刻(ソースはTOT)) | |
453 * | |
454 * STC と TOT の関連だけ計算出来るようにしておいて、 | |
455 * 出力するようにする/しないの判定は全体的に、 | |
456 * STCからTOTを使って出した時刻情報とする。かなぁ。 | |
457 * PCR/PTS/DTSはオーバーフローしたときには34Bit目が立っていると見なすこと | |
458 */ | |
459 // if ( 1 == splitter->pmt_pids[pid] ) { | |
460 if ( 2 == splitter->pmt_pids[pid] ) { | |
461 /* PMT の追跡 */ | |
462 int random_access; | |
463 DemuxTs((sptr+s_offset), splitter, pid, &random_access); | |
464 } | |
308 /* pids[pid] が 1 は残すパケットなので書き込む */ | 465 /* pids[pid] が 1 は残すパケットなので書き込む */ |
309 if(1 == splitter->pids[pid]) { | 466 if ( 1 == splitter->pids[pid] ) { |
310 memcpy(dptr + d_offset, sptr + s_offset, LENGTH_PACKET); | 467 len_pes = 0; |
311 d_offset += LENGTH_PACKET; | 468 random_access = 0; |
312 dbuf->size += LENGTH_PACKET; | 469 /* PCR 解析テスト */ |
470 if (parse_pcr(&pcr_h, &pcr_l, (sptr+s_offset)) == 0){ | |
471 pcr = pcr_h * 300 + pcr_l; | |
472 /* PCR の種にするものは、Program の PCR として指定されたPacketIDのものとすること */ | |
473 /* STC は PCR を種にする */ | |
474 splitter->stc = pcr; | |
475 // printf("PID[%d] pcr_h=[%llx] pcr_l=[%d] PCR[%f]\n",pid, pcr_h, pcr_l, ((double)pcr/(90000*300))); | |
476 } | |
477 /* TS処理 */ | |
478 if (DemuxTs((sptr+s_offset), splitter, pid, &random_access) == 0 ) { | |
479 #if 0 | |
480 /* とりあえずやっつけ */ | |
481 /* パケットの画面表示時刻(pts) >= 録画開始時刻(cue_time) となった場合に録画開始 */ | |
482 // if ( ((pts*300) >= splitter->cue_time) && (splitter->cue_time != -1)) { | |
483 if ( ((splitter->esbuf[pid].pts) >= splitter->program[sid].cue_time) && (splitter->program[sid].cue_time != -1)) { | |
484 splitter->cue_time = 0; | |
485 splitter->status = 0; | |
486 clock_gettime(CLOCK_REALTIME, &local_timespec); | |
487 printf("start recording. time_sec[%d] nsec[%d].\n", local_timespec.tv_sec%60, local_timespec.tv_nsec); | |
488 } | |
489 #endif | |
490 } | |
491 //search_mpeg_system_header(sptr+s_offset); | |
492 /* | |
493 * STCが cue_time を経過したら録画開始 | |
494 */ | |
495 if ( splitter->cue_time != -1 && splitter->cue_time <= splitter->stc ) { | |
496 memcpy(dptr + d_offset, sptr + s_offset, LENGTH_PACKET); | |
497 d_offset += LENGTH_PACKET; | |
498 dbuf->size += LENGTH_PACKET; | |
499 if ( splitter->status ) { | |
500 struct timespec local_timespec; | |
501 clock_gettime(CLOCK_REALTIME, &local_timespec); | |
502 printf("start recording. time_sec[%d] nsec[%d].\n", local_timespec.tv_sec%60, local_timespec.tv_nsec); | |
503 splitter->status = 0; | |
504 } | |
505 } | |
313 } | 506 } |
314 break; | 507 break; |
315 } /* switch */ | 508 } /* switch */ |
316 | 509 |
317 s_offset += LENGTH_PACKET; | 510 s_offset += LENGTH_PACKET; |
383 *(pmt_pids+pid) = 1; | 576 *(pmt_pids+pid) = 1; |
384 *(pids+pid) = 1; | 577 *(pids+pid) = 1; |
385 pos[pid] = i; | 578 pos[pid] = i; |
386 sid_found = TRUE; | 579 sid_found = TRUE; |
387 sp->pmt_retain += 1; | 580 sp->pmt_retain += 1; |
581 sp->program[service_id].pmt_packet_id = pid; | |
582 sp->pid_sid_table[pid] = service_id; | |
388 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 583 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
389 p++; | 584 p++; |
390 continue; | 585 continue; |
391 } | 586 } |
392 else if(!strcasecmp(*p, "hd") || !strcasecmp(*p, "sd1")) { | 587 else if(!strcasecmp(*p, "hd") || !strcasecmp(*p, "sd1")) { |
396 *(pmt_pids+pid) = 1; | 591 *(pmt_pids+pid) = 1; |
397 *(pids+pid) = 1; | 592 *(pids+pid) = 1; |
398 pos[pid] = i; | 593 pos[pid] = i; |
399 sid_found = TRUE; | 594 sid_found = TRUE; |
400 sp->pmt_retain += 1; | 595 sp->pmt_retain += 1; |
596 sp->program[service_id].pmt_packet_id = pid; | |
597 sp->pid_sid_table[pid] = service_id; | |
401 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 598 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
402 } | 599 } |
403 p++; | 600 p++; |
404 continue; | 601 continue; |
405 } | 602 } |
410 *(pmt_pids+pid) = 1; | 607 *(pmt_pids+pid) = 1; |
411 *(pids+pid) = 1; | 608 *(pids+pid) = 1; |
412 pos[pid] = i; | 609 pos[pid] = i; |
413 sid_found = TRUE; | 610 sid_found = TRUE; |
414 sp->pmt_retain += 1; | 611 sp->pmt_retain += 1; |
612 sp->program[service_id].pmt_packet_id = pid; | |
613 sp->pid_sid_table[pid] = service_id; | |
415 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 614 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
416 } | 615 } |
417 p++; | 616 p++; |
418 continue; | 617 continue; |
419 } | 618 } |
424 *(pmt_pids+pid) = 1; | 623 *(pmt_pids+pid) = 1; |
425 *(pids+pid) = 1; | 624 *(pids+pid) = 1; |
426 pos[pid] = i; | 625 pos[pid] = i; |
427 sid_found = TRUE; | 626 sid_found = TRUE; |
428 sp->pmt_retain += 1; | 627 sp->pmt_retain += 1; |
628 sp->program[service_id].pmt_packet_id = pid; | |
629 sp->pid_sid_table[pid] = service_id; | |
429 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 630 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
430 } | 631 } |
431 p++; | 632 p++; |
432 continue; | 633 continue; |
433 } | 634 } |
438 *(pmt_pids+pid) = 1; | 639 *(pmt_pids+pid) = 1; |
439 *(pids+pid) = 1; | 640 *(pids+pid) = 1; |
440 pos[pid] = i; | 641 pos[pid] = i; |
441 sid_found = TRUE; | 642 sid_found = TRUE; |
442 sp->pmt_retain += 1; | 643 sp->pmt_retain += 1; |
644 sp->program[service_id].pmt_packet_id = pid; | |
645 sp->pid_sid_table[pid] = service_id; | |
443 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 646 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
444 } | 647 } |
445 p++; | 648 p++; |
446 continue; | 649 continue; |
447 } | 650 } |
451 *(pmt_pids+pid) = 1; | 654 *(pmt_pids+pid) = 1; |
452 *(pids+pid) = 1; | 655 *(pids+pid) = 1; |
453 pos[pid] = i; | 656 pos[pid] = i; |
454 sid_found = TRUE; | 657 sid_found = TRUE; |
455 sp->pmt_retain += 1; | 658 sp->pmt_retain += 1; |
659 sp->program[service_id].pmt_packet_id = pid; | |
660 sp->pid_sid_table[pid] = service_id; | |
456 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 661 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
457 break; | 662 break; |
458 } | 663 } |
459 | 664 |
460 p++; | 665 p++; |
469 *(pmt_pids+pid) = 1; | 674 *(pmt_pids+pid) = 1; |
470 *(pids+pid) = 1; | 675 *(pids+pid) = 1; |
471 pos[pid] = i; | 676 pos[pid] = i; |
472 sid_found = TRUE; | 677 sid_found = TRUE; |
473 sp->pmt_retain += 1; | 678 sp->pmt_retain += 1; |
679 sp->program[service_id].pmt_packet_id = pid; | |
680 sp->pid_sid_table[pid] = service_id; | |
474 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); | 681 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id); |
475 } | 682 } |
476 } | 683 } |
477 | 684 |
478 /* print SIDs */ | 685 /* print SIDs */ |
575 | 782 |
576 /** | 783 /** |
577 * PMT 解析処理 | 784 * PMT 解析処理 |
578 * | 785 * |
579 * PMT を解析し、保存対象の PID を特定する | 786 * PMT を解析し、保存対象の PID を特定する |
787 * TSヘッダとアダプテーションフィールドの処理は DemuxTs に一任するので、 | |
788 * この内部では、セクションデータの先頭ポインタをもらってくる | |
580 */ | 789 */ |
581 static int AnalyzePmt(splitter *sp, unsigned char *buf) | 790 static int AnalyzePmt(splitter *sp, const uint8_t *buf, int sid, const int size) |
582 #if 0 | 791 #if 0 |
583 unsigned char* buf, // [in] 読み込んだバッファ | 792 unsigned char* buf, // [in] セクション先頭 |
584 unsigned char* pids) // [out] 出力対象 PID 情報 | 793 unsigned char* pids) // [out] 出力対象 PID 情報 |
585 #endif | 794 #endif |
586 { | 795 { |
587 unsigned char Nall; | 796 unsigned char Nall; |
588 unsigned char N; | 797 unsigned char N; |
589 int pcr; | 798 int pcr; |
590 int epid; | 799 int epid; |
591 | 800 int av_flag = 0; |
592 Nall = ((buf[6] & 0x0F) << 4) + buf[7]; | 801 |
593 if(Nall > LENGTH_PACKET) | 802 // Nall = ((buf[2] & 0x0F) << 4) + buf[3]; |
594 Nall = LENGTH_PACKET - 8; /* xxx workaround --yaz */ | 803 Nall = ((buf[2] & 0x0F) << 8) + buf[3]; |
804 | |
805 /* get version */ | |
806 sp->program[sid].pmt_version = get_pmt_version(buf); | |
595 | 807 |
596 // PCR | 808 // PCR |
597 pcr = GetPid(&buf[13]); | 809 pcr = GetPid(&buf[9]); |
598 sp->pids[pcr] = 1; | 810 sp->pids[pcr] = 1; |
599 | 811 sp->program[sid].pcr_packet_id = pcr; |
600 N = ((buf[15] & 0x0F) << 4) + buf[16] + 16 + 1; | 812 |
601 | 813 // N = ((buf[11] & 0x0F) << 4) + buf[12] + 16 + 1; |
602 // ECM | 814 N = ((buf[11] & 0x0F) << 8) + buf[12] + 12 + 1; |
603 int p = 17; | 815 // printf("NAll[%d] N[%d]\n", Nall, N); |
604 while(p < N) { | 816 |
605 uint32_t ca_pid; | 817 /* |
606 uint32_t tag; | 818 * ISO/IEC 13818-1:2000(E) Table 2-29 - Stream type assignments |
607 uint32_t len; | 819 * Value Desctiption |
608 | 820 * 0x00 ITU-T | ISO/IEC Reserved |
609 tag = buf[p]; | 821 * 0x01 ISO/IEC 11172 Video |
610 len = buf[p+1]; | 822 * 0x02 ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream |
611 p += 2; | 823 * 0x03 ISO/IEC 11172 Audio |
612 | 824 * 0x04 ISO/IEC 13818-3 Audio |
613 if(tag == 0x09 && len >= 4 && p+len <= N) { | 825 * 0x05 ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private_sections |
614 ca_pid = ((buf[p+2] << 8) | buf[p+3]) & 0x1fff; | 826 * 0x06 ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing private data |
615 sp->pids[ca_pid] = 1; | 827 * 0x07 ISO/IEC 13522 MHEG |
616 } | 828 * 0x08 ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Annex A DSM-CC |
617 p += len; | 829 * 0x09 ITU-T Rec. H.222.1 |
618 } | 830 * 0x0A ISO/IEC 13818-6 type A |
831 * 0x0B ISO/IEC 13818-6 type B | |
832 * 0x0C ISO/IEC 13818-6 type C | |
833 * 0x0D ISO/IEC 13818-6 type D | |
834 * 0x0E ITU-T Rec. H.222.0 | ISO/IEC 13818-1 auxiliary | |
835 * 0x0F ISO/IEC 13818-7 Audio with ADTS transport syntax | |
836 * 0x10 ISO/IEC 14496-2 Visual | |
837 * 0x11 ISO/IEC 14496-3 Audio with the LATM transport syntax as defined in ISO/IEC 14496-3 / AMD 1 | |
838 * 0x12 ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in PES packets | |
839 * 0x13 ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in ISO/IEC14496_sections. | |
840 * 0x14 ISO/IEC 13818-6 Synchronized Download Protocol | |
841 * 0x15-0x7F ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Reserved | |
842 * 0x80-0xFF User Private | |
843 * | |
844 */ | |
619 | 845 |
620 // ES PID | 846 // ES PID |
621 while (N < Nall + 8 - 4) | 847 while (N < Nall + 8 - 4) |
622 { | 848 { |
849 av_flag = 0; | |
850 if ( N > size ) { | |
851 break; | |
852 } | |
623 // ストリーム種別が 0x0D(type D)は出力対象外 | 853 // ストリーム種別が 0x0D(type D)は出力対象外 |
624 if (0x0D != buf[N]) | 854 if (0x0D != buf[N]) |
625 { | 855 { |
626 epid = GetPid(&buf[N + 1]); | 856 epid = GetPid(&buf[N + 1]); |
627 | |
628 sp->pids[epid] = 1; | 857 sp->pids[epid] = 1; |
629 } | 858 if ( buf[N] == 0x02 ) { /* 13818-2 Video */ |
630 N += 4 + (((buf[N + 3]) & 0x0F) << 4) + buf[N + 4] + 1; | 859 sp->program[sid].video[sp->program[sid].video_nb] = epid; |
631 } | 860 sp->program[sid].video_nb += 1; |
632 | 861 av_flag = 1; |
862 } else if ( (buf[N] == 0x04) || (buf[N] == 0x0f) ) { | |
863 /* 13818-3 Audio or 13818-7 Audio with ADTS transport syntax */ | |
864 sp->program[sid].audio[sp->program[sid].audio_nb] = epid; | |
865 sp->program[sid].audio_nb += 1; | |
866 av_flag = 1; | |
867 } else { | |
868 ; /* A/V どちらでもないものはとりあえずスルー */ | |
869 } | |
870 if ( av_flag ) { | |
871 /* ESバッファはNULLか? */ | |
872 if ( sp->esbuf[epid] == NULL ) { | |
873 sp->esbuf[epid] = malloc(sizeof(splitesbuf_t)); | |
874 if ( sp->esbuf[epid] == NULL ) { | |
875 fprintf(stderr, "malloc error\n"); | |
876 return TSS_NULL; | |
877 } | |
878 sp->esbuf[epid]->size = 0; | |
879 sp->esbuf[epid]->Program = &(sp->program[sid]); | |
880 } | |
881 /* PESバッファはNULLか? */ | |
882 if ( sp->pesbuf[epid] == NULL ) { | |
883 sp->pesbuf[epid] = malloc(sizeof(splitpesbuf_t)); | |
884 if ( sp->pesbuf[epid] == NULL ) { | |
885 fprintf(stderr, "malloc error\n"); | |
886 return TSS_NULL; | |
887 } | |
888 sp->pesbuf[epid]->size = 0; | |
889 sp->pesbuf[epid]->Program = &(sp->program[sid]); | |
890 } | |
891 } | |
892 } | |
893 // N += 4 + (((buf[N + 3]) & 0x0F) << 4) + buf[N + 4] + 1; | |
894 N += 4 + (((buf[N + 3]) & 0x0F) << 8) + buf[N + 4] + 1; | |
895 } | |
633 return TSS_SUCCESS; | 896 return TSS_SUCCESS; |
634 } | 897 } |
635 | 898 |
636 /** | 899 /** |
637 * CRC 計算 | 900 * CRC 計算 |
682 static int GetPid( | 945 static int GetPid( |
683 unsigned char* data) // [in] 取得対象データのポインタ | 946 unsigned char* data) // [in] 取得対象データのポインタ |
684 { | 947 { |
685 return ((data[0] & 0x1F) << 8) + data[1]; | 948 return ((data[0] & 0x1F) << 8) + data[1]; |
686 } | 949 } |
950 | |
951 /* return the 90kHz PCR and the extension for the 27MHz PCR. return | |
952 (-1) if not available */ | |
953 static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, | |
954 const uint8_t *packet) | |
955 { | |
956 int afc, len, flags; | |
957 const uint8_t *p; | |
958 unsigned int v; | |
959 | |
960 afc = (packet[3] >> 4) & 3; | |
961 if (afc <= 1) | |
962 return -1; | |
963 p = packet + 4; | |
964 len = p[0]; | |
965 p++; | |
966 if (len == 0) | |
967 return -1; | |
968 flags = *p++; | |
969 len--; | |
970 if (!(flags & 0x10)) | |
971 return -1; | |
972 if (len < 6) | |
973 return -1; | |
974 v = AV_RB32(p); | |
975 *ppcr_high = ((int64_t)v << 1) | (p[4] >> 7); | |
976 *ppcr_low = ((p[4] & 1) << 8) | p[5]; | |
977 return 0; | |
978 } | |
979 | |
980 #if 0 | |
981 /** | |
982 * TSを解析してPESを出力する | |
983 */ | |
984 static int ts2pes(int64_t *ppts, int64_t *pdts, const uint8_t *packet, splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid) | |
985 { | |
986 /* 全体的に length がpacket長越えた時の処理を追記すること */ | |
987 /* | |
988 * PES先頭までの長さは | |
989 * 4byte : continity counter | |
990 * 27,28bit が adaptation fileld制御 | |
991 * (01:ペイロードのみ, 10:adaptation fileldのみ、11:adaptation fileld+payload、00:reserved) | |
992 * ペイロード長 = 188 - TS header(4byte) -adaptation field長 -1 | |
993 */ | |
994 int len_afh = 0; | |
995 *ppts = -1; | |
996 *pdts = -1; | |
997 int flags = 0; | |
998 const uint8_t *p; | |
999 p = (uint8_t*)packet; | |
1000 | |
1001 flags = (p[3] & 0x30) >> 4; | |
1002 if ( flags == 0x02 || flags == 0x00) { | |
1003 /* ペイロードなし */ | |
1004 return -1; | |
1005 } else if ( flags == 0x03 ) { | |
1006 /* アダプテーションフィールド+ペイロード */ | |
1007 /* アダプテーションフィールド長 */ | |
1008 len_afh = *(p+LENGTH_TS_HEADER) & 0xff; | |
1009 if ( len_afh > LENGTH_PACKET -LENGTH_TS_HEADER ) { | |
1010 return -1; | |
1011 } | |
1012 if (!(p[1] & 0x40)) { | |
1013 /* payload start unit indicator 発見 */ | |
1014 if ( pesbuf->size != 0 ) { | |
1015 pes2es(ppts, pdts, pesbuf, esbuf, pid); | |
1016 pesbuf->size = 0; | |
1017 } | |
1018 memcpy(pesbuf->buffer + pesbuf->size, | |
1019 packet +LENGTH_TS_HEADER +len_afh +1, | |
1020 LENGTH_PACKET -LENGTH_TS_HEADER -len_afh -1); | |
1021 pesbuf->size += LENGTH_PACKET -LENGTH_TS_HEADER -len_afh -1; | |
1022 } | |
1023 /* PES先頭パケットではないのでバッファに書き込み */ | |
1024 if ( pesbuf->size != 0 ) { | |
1025 memcpy(pesbuf->buffer + pesbuf->size, | |
1026 packet +LENGTH_TS_HEADER +len_afh +1, | |
1027 LENGTH_PACKET -LENGTH_TS_HEADER -len_afh -1); | |
1028 pesbuf->size += LENGTH_PACKET -LENGTH_TS_HEADER -len_afh -1; | |
1029 } | |
1030 } else { | |
1031 /* ペイロードのみ */ | |
1032 /* TSヘッダを取り除いてPESバッファ書き込み */ | |
1033 if ( pesbuf->size != 0 ) { | |
1034 memcpy(pesbuf->buffer +pesbuf->size, | |
1035 packet +LENGTH_TS_HEADER, | |
1036 LENGTH_PACKET -LENGTH_TS_HEADER); | |
1037 pesbuf->size += LENGTH_PACKET -LENGTH_TS_HEADER; | |
1038 } | |
1039 } | |
1040 return 0; | |
1041 } | |
1042 #endif | |
1043 | |
1044 /* pesbufが空か判定 (ret. 0:not empty / 1: empty) */ | |
1045 static int pesbuf_empty(splitpesbuf_t *pesbuf){ | |
1046 return pesbuf->size == 0; | |
1047 } | |
1048 | |
1049 /* pesbufをクリア */ | |
1050 void pesbuf_clear(splitpesbuf_t *pesbuf){ | |
1051 pesbuf->size = 0; | |
1052 } | |
1053 | |
1054 /* pesbufにデータを追加 (ret. 0:success / -1:error) */ | |
1055 static int pesbuf_add(splitpesbuf_t *pesbuf, const uint8_t *data, int len){ | |
1056 if(pesbuf->size + len > sizeof pesbuf->buffer){ | |
1057 //assert(0); | |
1058 return -1; | |
1059 } | |
1060 memcpy(pesbuf->buffer +pesbuf->size, data, len); | |
1061 pesbuf->size += len; | |
1062 return 0; | |
1063 } | |
1064 | |
1065 /* pesbufから、PESの先頭(packet_start_code_prefix)を探す */ | |
1066 /* (ret. >=0:offset / -1: error) */ | |
1067 static int pesbuf_packet_start_code_prefix(splitpesbuf_t *pesbuf){ | |
1068 uint8_t packet_start_code_prefix[3] = {0x00, 0x00, 0x01}; | |
1069 int i = 0; | |
1070 | |
1071 /* 小さすぎる */ | |
1072 if(pesbuf->size < sizeof packet_start_code_prefix){ | |
1073 return -1; | |
1074 } | |
1075 /* 先頭で探す */ | |
1076 if(!memcmp(pesbuf->buffer + i, packet_start_code_prefix, sizeof packet_start_code_prefix)){ | |
1077 return 0; | |
1078 } | |
1079 | |
1080 #if 0 | |
1081 /* 先頭以外からも探す場合は、ここのコードを有効化する。 */ | |
1082 /* ただし、MPEG-Videoのstart_codeと同じなので、深追いしない方がいいと思う... */ | |
1083 for(i = 0; i < pesbuf->size - sizeof packet_start_code_prefix; i++){ | |
1084 if(!memcmp(pesbuf->buffer + i, packet_start_code_prefix, sizeof packet_start_code_prefix)){ | |
1085 return i; | |
1086 } | |
1087 } | |
1088 #endif | |
1089 | |
1090 return -1; | |
1091 } | |
1092 | |
1093 /** | |
1094 * TSの解析とDemuxを行う | |
1095 */ | |
1096 //static int ts2pes(int64_t *ppts, int64_t *pdts, const uint8_t *packet, splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid) | |
1097 static int DemuxTs(const uint8_t *packet, splitter *sp, const int pid, int *random_access) | |
1098 { | |
1099 /* | |
1100 * PES先頭までの長さは | |
1101 * 4byte : continity counter | |
1102 * 27,28bit が adaptation fileld制御 | |
1103 * (01:ペイロードのみ, 10:adaptation fileldのみ、11:adaptation fileld+payload、00:reserved) | |
1104 * ペイロード長 = 188 - TS header(4byte) -adaptation field長 -1 | |
1105 */ | |
1106 /* ありがとう */ | |
1107 | |
1108 int payload_offset; /* ペイロードオフセット(=パケット先頭からのバイト数) */ | |
1109 int payload_length; /* ペイロード長 */ | |
1110 int pes_started; | |
1111 int adaptation_field_control; | |
1112 int payload_unit_start_indicator; | |
1113 int random_access_indicator = 0; | |
1114 int sid = sp->pid_sid_table[pid]; | |
1115 | |
1116 payload_offset = LENGTH_TS_HEADER; | |
1117 | |
1118 if ( sp->pesbuf[pid] == NULL ) { | |
1119 pes_started = 0; /* malloc走る前(セクション解析だったら呼んで良い) */ | |
1120 } else { | |
1121 pes_started = !pesbuf_empty(sp->pesbuf[pid]); /* PES蓄積開始済み */ | |
1122 } | |
1123 | |
1124 /* adaptation_field_controlおよびadaptation_fieldを処理する */ | |
1125 adaptation_field_control = (packet[3] & 0x30) >> 4; | |
1126 if ( adaptation_field_control == 0x02 || adaptation_field_control == 0x00) { | |
1127 /* ペイロードなしの場合 */ | |
1128 return 0; /* 別にエラーではない */ | |
1129 } else if ( adaptation_field_control == 0x03 ) { | |
1130 /* アダプテーションフィールド+ペイロードの場合 */ | |
1131 if ( packet[LENGTH_TS_HEADER] != 0 ) { | |
1132 random_access_indicator = (packet[5] & 0x40) >> 6; | |
1133 sp->pesbuf[pid]->random_access_indicator = 1; | |
1134 sp->esbuf[pid]->random_access_indicator = 1; | |
1135 } | |
1136 /* ペイロード開始位置 = TSヘッダ長 + アダプテーションフィールド長 + 1 */ | |
1137 payload_offset += packet[LENGTH_TS_HEADER] + 1; | |
1138 } else { | |
1139 /* ペイロードのみ */ | |
1140 ; /* 特に処理なし */ | |
1141 } | |
1142 | |
1143 /* ペイロード長を出す */ | |
1144 payload_length = LENGTH_PACKET - payload_offset; | |
1145 if( payload_length <= 0 ){ /* payload長が0以下の場合 */ | |
1146 return -1; /* エラーにすべきかは微妙なところ */ | |
1147 } | |
1148 | |
1149 /* payload_unit_start_indicatorを処理(1) */ | |
1150 payload_unit_start_indicator = (packet[1] & 0x40) >> 6; | |
1151 /* (sectionの場合は、ここでpointer_fieldの処理などを行い、payload_offsetに反映する) */ | |
1152 // if ( sp->pmt_pids[pid] == 2 ) { /* PID が録画対象の PMT であるか? */ | |
1153 // int sid = search_pmt_program(sp, pid); /* PID が録画対象の PMT であるか? */ | |
1154 if ( sp->pmt_pids[pid] == 2 ) { /* PID が録画対象の PMT であるか? */ | |
1155 if ( get_pmt_version(packet+payload_offset) != sp->program[sid].pmt_version ) { | |
1156 /* pmt versionに差分あり */ | |
1157 fprintf(stderr, "pmt version diff found pmt_pid[%d]" | |
1158 " old_version[0x%02x]" | |
1159 " new_version[0x%02x].\n", | |
1160 pid, | |
1161 sp->program[sid].pmt_version, | |
1162 get_pmt_version(packet+payload_offset)); | |
1163 AnalyzePmt(sp, packet +payload_offset, sid, payload_length); | |
1164 /* payload 何byte処理したか等管理するべき */ | |
1165 } | |
1166 return 0; /* PMT の場合は処理終わり */ | |
1167 } | |
1168 | |
1169 /* payload_unit_start_indicatorを処理(2) */ | |
1170 /* 必要に応じ、蓄積済みPESの処理と、PES蓄積開始を行う */ | |
1171 if( payload_unit_start_indicator ){ | |
1172 /* PES開始 */ | |
1173 if ( pes_started ) { | |
1174 /* バッファにデータがあればPES終端なので処理してクリア */ | |
1175 pes2es(sp->pesbuf[pid], sp->esbuf[pid], pid); | |
1176 pesbuf_clear(sp->pesbuf[pid]); | |
1177 } | |
1178 else { | |
1179 /* random_access_indicator からPES の蓄積を開始すると | |
1180 * CS:動画がGOP先頭から蓄積されるが、 | |
1181 * 音声には random_access_indicator が表れないのでダメ | |
1182 */ | |
1183 pes_started = 1; | |
1184 } | |
1185 } | |
1186 | |
1187 /* PES蓄積処理 */ | |
1188 if ( pes_started ){ | |
1189 /* PES蓄積開始済み(これからPES蓄積開始を含む)なら、payloadをPESとして追加 */ | |
1190 pesbuf_add(sp->pesbuf[pid], packet + payload_offset, payload_length); | |
1191 } | |
1192 /* おつかれさまでした */ | |
1193 return 0; | |
1194 } | |
1195 | |
1196 /* PMT_PID から Program(Service ID)を確定させる */ | |
1197 static int search_pmt_program(splitter *sp, int pid) | |
1198 { | |
1199 int i; | |
1200 for ( i = 0; i < MAX_SERVICE_ID; i++ ) { | |
1201 if ( sp->program[i].pmt_packet_id == pid ) { | |
1202 return i; | |
1203 } | |
1204 } | |
1205 return -1; | |
1206 } | |
1207 | |
1208 /* esbufが空か判定 (ret. 0:not empty / 1: empty) */ | |
1209 static int esbuf_empty(splitesbuf_t *esbuf){ | |
1210 return esbuf->size == 0; | |
1211 } | |
1212 | |
1213 /* esbufをクリア */ | |
1214 void esbuf_clear(splitesbuf_t *esbuf){ | |
1215 esbuf->random_access_indicator = 0; | |
1216 esbuf->size = 0; | |
1217 } | |
1218 | |
1219 /* esbufにデータを追加 (ret. 0:success / -1:error) */ | |
1220 static int esbuf_add(splitesbuf_t *esbuf, const uint8_t *data, int len){ | |
1221 if(esbuf->size + len > sizeof esbuf->buffer){ | |
1222 return -1; | |
1223 } | |
1224 memcpy(esbuf->buffer +esbuf->size, data, len); | |
1225 esbuf->size += len; | |
1226 return 0; | |
1227 } | |
1228 | |
1229 /* | |
1230 * PESを解析してESを出力する | |
1231 */ | |
1232 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid) | |
1233 { | |
1234 int len_pesh = 0; | |
1235 int code = 0; | |
1236 int flags = 0; | |
1237 int len_pes = 0; | |
1238 int len_pesh_supposed = 0; | |
1239 int pes_extension_flags = 0; | |
1240 int pes_extension_flags2 = 0; | |
1241 int program_packet_sequence_counter_flag = 0; | |
1242 int es_rate = 0; | |
1243 const uint8_t *p = pesbuf->buffer; | |
1244 const uint8_t *p_end = pesbuf->buffer +pesbuf->size; | |
1245 int original_stuffing_length = 0; | |
1246 int data_alignment_indicator = false; | |
1247 int es_started; | |
1248 int payload_offset = 0; | |
1249 int payload_length = 0; | |
1250 /* ありがとう */ | |
1251 /* ありがとうとコメントを書くと、 | |
1252 * 動作がよくなる | |
1253 * バグが減る | |
1254 * バイナリサイズが小さくなる | |
1255 * 画質がよくなる | |
1256 * 音質がよくなる | |
1257 */ | |
1258 if ( esbuf == NULL ) { | |
1259 return -1; /* malloc走る前この関数は呼んじゃダメです */ | |
1260 } else { | |
1261 es_started = !esbuf_empty(esbuf); /* ES蓄積開始済み */ | |
1262 } | |
1263 | |
1264 payload_offset = pesbuf_packet_start_code_prefix(pesbuf); | |
1265 if ( payload_offset == -1 ) { | |
1266 return -1; | |
1267 } | |
1268 p += payload_offset; | |
1269 #if 0 | |
1270 while( p < p_end -LENGTH_PES_HEADER -2) { | |
1271 /* PES PREFIXが出現するまで読み捨てる */ | |
1272 if ( (p[0] == 0x00 && p[1] == 0x00 && p[2] == 0x01) ) { | |
1273 break; | |
1274 } else { | |
1275 offset++; | |
1276 p++; | |
1277 } | |
1278 } | |
1279 if ( p >= p_end -LENGTH_PES_HEADER -2) { | |
1280 return -1; | |
1281 } | |
1282 #endif | |
1283 /* http://dvd.sourceforge.net/dvdinfo/pes-hdr.html | |
1284 * | |
1285 * Stream ID : type : extension present? | |
1286 * (1011 1101) 0xBD : Private stream 1 (non MPEG audio, subpictures) : YES | |
1287 * (1011 1110) 0xBE : Padding stream : NO | |
1288 * (1011 1111) 0xBF : Private stream 2 (navigation data) : NO | |
1289 * (110x xxxx) 0xC0 - 0xDF : MPEG-1 or MPEG-2 audio stream number x xxxx : YES | |
1290 * (1110 xxxx) 0xE0 - 0xEF : MPEG-1 or MPEG-2 video stream number xxxx : YES | |
1291 * note: DVD allows only 8 audio streams/DVD allows only 1 video stream | |
1292 */ | |
1293 /* http://www2.arib.or.jp/johomem/pdf/2009/2009_0088.pdf | |
1294 * | |
1295 * 0xBC : プログラムストリームマップ | |
1296 * 0xBD : プライベートストリーム1 | |
1297 * 0xBE : パディングストリーム | |
1298 * 0xBF : プライベートストリーム2 | |
1299 * 0xC0 - 0xDF : ISO/IEC 13318 3、ISO/IEC 11172 3、ISO/IEC 13318 7 or ISO/IEC 14496 3 audio xxxx | |
1300 * 0xE0 - 0xEF : ITU-T H.262、ISO/IEC 11172 2、ISO/IEC 14496 2 or ITU-T H264映像ストリーム | |
1301 * 0xF0 : ECMストリーム | |
1302 * 0xF1 : EMMストリーム | |
1303 * 0xF2 : ITU-T勧告H.222.0 Annex A 又は ISO/IEC 13318 6 のDSMCCストリーム | |
1304 * 0xF3 : ISO/IEC 13522ストリーム | |
1305 * 0xF4 : ITU-T勧告 H.222.1 type A | |
1306 * 0xF5 : ITU-T勧告 H.222.1 type B | |
1307 * 0xF6 : ITU-T勧告 H.222.1 type C | |
1308 * 0xF7 : ITU-T勧告 H.222.1 type D | |
1309 * 0xF8 : ITU-T勧告 H.222.1 type E | |
1310 * 0xF9 : 補助ストリーム | |
1311 * 0xFA : ISO/IEC 14496 1SLパケット化ストリーム | |
1312 * 0xFB : ISO/IEC 14496 1フレックスマックスストリーム | |
1313 * 0xFC : メタデータストリーム | |
1314 * 0xFD : 拡張ストリームID | |
1315 * 0xFE : 未定義 | |
1316 * 0xFF : プログラムストリームディレクトリ | |
1317 */ | |
1318 /* 上記より、ここでは | |
1319 * MPEG-1 or MPEG-2 audio stream と | |
1320 * MPEG-1 or MPEG-2 video stream と | |
1321 * Private stream 1 と | |
1322 * 0xFD(拡張ストリームID)を抽出する | |
1323 * ?0xBF Private stream 2 落としてるけどよいの? | |
1324 * >多分よくない。ffmpegではここに入る前に PRIVATE_STREAM2 のコードが入っている | |
1325 */ | |
1326 code = (p[3] &0xff) | 0x100; | |
1327 if ( !((code >= 0x1c0 && code <= 0x1df) || | |
1328 (code >= 0x1e0 && code <= 0x1ef) || | |
1329 (code == 0x1bd) || (code == 0x1fd))) { | |
1330 return -1; | |
1331 } | |
1332 /* PES のデータ長 */ | |
1333 /* 動画のストリームである場合には、ES長は不定となるので0が許容される */ | |
1334 len_pes = AV_RB16(p+4); | |
1335 /* PESヘッダ拡張部(byte 6) */ | |
1336 flags = p[6] & 0xff; | |
1337 if ( flags & 0x04 ) { | |
1338 data_alignment_indicator = true; | |
1339 /* data alignment indicator */ | |
1340 /* video start code or audio syncword. */ | |
1341 /* おそらくここで区切るとピクチャ単位 */ | |
1342 //printf("data alignment indicator found pid[%d].\n", pid); | |
1343 } | |
1344 flags = p[7] & 0xff; | |
1345 /* PESヘッダデータ長(byte 8) */ | |
1346 /* | |
1347 * PESヘッダデータ長 = PESヘッダ拡張部の長さ + stuffing byteの長さ | |
1348 */ | |
1349 /* | |
1350 *len_pesh = flags(byte 7)のデータ合計(24) | |
1351 * +PES Extension flagのデータ合計(23) | |
1352 * +PES Extension flag2のデータ合計(127) | |
1353 * +stuffing byte(32) <- これもlen_peshの長さに混ぜていいの? | |
1354 * MAX=206(?) | |
1355 */ | |
1356 len_pesh = p[8] & 0xff; | |
1357 p += LENGTH_PES_HEADER; | |
1358 payload_offset += LENGTH_PES_HEADER +len_pesh; | |
1359 if ( p +payload_offset >= p_end ) { | |
1360 /* PESヘッダ長すぎます */ | |
1361 return -1; | |
1362 } | |
1363 | |
1364 /* flags | |
1365 * +---------------------------------------------------+ | |
1366 * name |byte 7(flags) | | |
1367 * +-----+-----+-----+------+----------+----+----------+ | |
1368 * Bit |76 |5 |4 |3 |2 |1 |0 | | |
1369 * +-----+-----+-----+------+----------+----+----------+ | |
1370 * field|PTS |ESCR |ES |DSM |additional|PES |PES | | |
1371 * name |DTS |FLAG |RATE |Trick |copy info |CRC |Extension | | |
1372 * |flag | |flag |mode |flag |flag|flag | | |
1373 * +-----+-----+-----+------+----------+----+----------+ | |
1374 * Data |5,5 |6 |3 |1 |1 |2 |1 |(24) | |
1375 * byte | | | | | | | | | |
1376 * +-----+-----+-----+------+----------+----+----------+ | |
1377 */ | |
1378 if ( flags & PTS_FLAG ) { | |
1379 if ( p +LENGTH_PTS >= p_end ) { | |
1380 return -1; | |
1381 } | |
1382 esbuf->pts = get_pts(p); | |
1383 p += LENGTH_PTS; | |
1384 len_pesh_supposed += LENGTH_PTS; | |
1385 } | |
1386 if ( flags & DTS_FLAG ) { | |
1387 if ( p +LENGTH_PTS >= p_end ) { | |
1388 return -1; | |
1389 } | |
1390 esbuf->dts = get_pts(p); | |
1391 p += LENGTH_PTS; | |
1392 len_pesh_supposed += LENGTH_PTS; | |
1393 } | |
1394 if ( flags & ESCR_FLAG ) { | |
1395 p += 6; | |
1396 len_pesh_supposed += 6; | |
1397 } | |
1398 if ( flags & ES_RATE_FLAG ) { | |
1399 es_rate = AV_RB24(p); | |
1400 es_rate = (es_rate >>1) & 0x3fffff; | |
1401 es_rate = es_rate * 50; | |
1402 printf("pid[%d] es_rate[%d]Byte/Sec.\n", pid, es_rate); | |
1403 p += 3; | |
1404 len_pesh_supposed += 3; | |
1405 } | |
1406 if ( flags & DSM_TRICK_MODE_FLAG ) { | |
1407 p += 1; | |
1408 len_pesh_supposed += 1; | |
1409 } | |
1410 if ( flags & COPY_INFO_FLAG ) { | |
1411 p += 1; | |
1412 len_pesh_supposed += 1; | |
1413 } | |
1414 if ( flags & CRC_FLAG ) { | |
1415 p += 2; | |
1416 len_pesh_supposed += 2; | |
1417 } | |
1418 if ( flags & EXTENSION_FLAG ) { | |
1419 /* PES Extension flag | |
1420 * +------------------------------------------------------------------+ | |
1421 * name |PES Extension flag | | |
1422 * +-----------+-----------+----------------+------+---+--------------+ | |
1423 * bit |7 |6 |5 |4 |321|0 | | |
1424 * +-----------+-----------+----------------+------+---+--------------+ | |
1425 * field|PES private|pack header|program |P-STD |111|PES extension | | |
1426 * name |data flag |field flag |packet |buffer| |flag2 | | |
1427 * | | |sequence counter|flag | | | | |
1428 * +-----------+-----------+----------------+------+---+--------------+ | |
1429 * Data |16 |1 |2 |2 | |1 |(23) | |
1430 * byte | | | | | | | | |
1431 * +-----------+-----------+----------------+------+---+--------------+ | |
1432 */ | |
1433 if ( p >= p_end ) { | |
1434 return -1; | |
1435 } | |
1436 pes_extension_flags = *p & 0xff; | |
1437 p += 1; | |
1438 len_pesh_supposed += 1; | |
1439 if ( pes_extension_flags & PES_PRIVATE_DATA_FLAG ) { | |
1440 p += 16; | |
1441 len_pesh_supposed += 16; | |
1442 } | |
1443 if ( pes_extension_flags & PACK_HEADER_FIELD_FLAG ) { | |
1444 p += 1; | |
1445 len_pesh_supposed += 1; | |
1446 } | |
1447 if ( pes_extension_flags & PROGRAM_PACKET_SEQUENCE_COUNTER ) { | |
1448 if ( p >= p_end ) { | |
1449 return -1; | |
1450 } | |
1451 program_packet_sequence_counter_flag = *p & 0xff; | |
1452 original_stuffing_length = program_packet_sequence_counter_flag & 0x3f; | |
1453 p += 2; | |
1454 len_pesh_supposed += 2; | |
1455 } | |
1456 if ( pes_extension_flags & PSTD_BUFFER_FLAG ) { | |
1457 p += 2; | |
1458 len_pesh_supposed += 2; | |
1459 } | |
1460 if ( pes_extension_flags & PES_EXTENSION_FLAG2 ) { | |
1461 /* PES Extension flag2 | |
1462 * +------------------------------------------------------------------+ | |
1463 * name |PES Extension flag2 | | |
1464 * +------+-----------------------------------------------------------+ | |
1465 * bit |7 |6543210 | | |
1466 * +------+-----------------------------------------------------------+ | |
1467 * field|marker|PES_extension_field_length | | |
1468 * name |bit | | | |
1469 * |'1' | | | |
1470 * +------+-----------------------------------------------------------+ | |
1471 * Data |- |0 <= N <= 127 |(127) | |
1472 * byte | | | | |
1473 * +------+-----------------------------------------------------------+ | |
1474 */ | |
1475 if ( p >= p_end ) { | |
1476 return -1; | |
1477 } | |
1478 pes_extension_flags2 = *p & 0x7f; | |
1479 p += 1; | |
1480 len_pesh_supposed += 1; | |
1481 | |
1482 p += pes_extension_flags2; | |
1483 len_pesh_supposed += pes_extension_flags2; | |
1484 } | |
1485 } | |
1486 #if 0 | |
1487 /* | |
1488 * 画像であれば、PTS/DTSが立っていた場合に出力して、 | |
1489 * それ以外であれば、PTSが立っていた場合にのみ出力にすると、 | |
1490 * GOP的なまとまりで出力できる? | |
1491 */ | |
1492 /* esbuf->size が 0 であるのはは初期化後、初めてここに到達した場合 */ | |
1493 if ((have_data_alignment_indicator) && (esbuf->size != 0)) { | |
1494 /* ここのタイミングでパックヘッダつけてあげればPSになるはず */ | |
1495 /* ピクチャ先頭パケット */ | |
1496 write_es(esbuf, pid); | |
1497 memcpy(esbuf->buffer, | |
1498 pesbuf->buffer +offset +LENGTH_PES_HEADER +len_pesh, | |
1499 pesbuf->size -offset -LENGTH_PES_HEADER -len_pesh); | |
1500 esbuf->size = pesbuf->size -offset -LENGTH_PES_HEADER -len_pesh; | |
1501 } else if (have_data_alignment_indicator && (esbuf->size == 0)) { | |
1502 /* プロセス起動してから最初のピクチャ先頭データ */ | |
1503 memcpy(esbuf->buffer, | |
1504 pesbuf->buffer +offset +LENGTH_PES_HEADER +len_pesh, | |
1505 pesbuf->size -offset -LENGTH_PES_HEADER -len_pesh); | |
1506 esbuf->size = pesbuf->size -offset -LENGTH_PES_HEADER -len_pesh; | |
1507 } else if(esbuf->size != 0) { | |
1508 /* それ以外のPESデータ */ | |
1509 memcpy(esbuf->buffer + esbuf->size, | |
1510 pesbuf->buffer +offset +LENGTH_PES_HEADER +len_pesh, | |
1511 pesbuf->size -offset -LENGTH_PES_HEADER -len_pesh); | |
1512 esbuf->size += pesbuf->size -offset -LENGTH_PES_HEADER -len_pesh; | |
1513 } else { | |
1514 /* 読み捨て */ | |
1515 /* プロセス起動直後のデータは捨てる(GOP境界をまたいだパケットから書き始めない為) */ } | |
1516 printf("len_pesh_supposed[%d], len_pesh[%d].\n", len_pesh_supposed, len_pesh); | |
1517 #endif | |
1518 if ( data_alignment_indicator ) { | |
1519 if ( es_started ) { /* ES にデータが蓄積されている */ | |
1520 if ( is_video_stream(pid, esbuf) ) { /* VIDEO である場合 */ | |
1521 /* | |
1522 * ESにはピクチャ単位でデータが蓄積されている | |
1523 * ESにGOPの開始コードが含まれているか調べて、 | |
1524 * 含まれていたら、蓄積開始のフラグを立てるのがいいかも… | |
1525 */ | |
1526 if ( esbuf->random_access_indicator ) { /* TS の random_access ビットが立ったものがきているか? */ | |
1527 /* 該当ストリームを蓄積する */ | |
1528 esbuf->started = 1; | |
1529 esbuf->Program->video_start = 1; | |
1530 esbuf->Program->video_pts = esbuf->pts; | |
1531 } else { | |
1532 /* TS の random_access ビットが立ったものがきていない */ | |
1533 /* 蓄積しない */ | |
1534 esbuf_clear(esbuf); | |
1535 } | |
1536 } | |
1537 /* AAC の実験コードここから */ | |
1538 /* | |
1539 * オーディオを出力し始める条件(1. 2. を満たすこと) | |
1540 * 1. 動画の蓄積は開始されている | |
1541 * 2. 動画のGOPの1番目のIピクチャのPTSとオーディオのPTSを比較して以下のどちらかを満たすこと | |
1542 * 2.1. 差分が11msec以内 | |
1543 * 2.2. 過ぎている(過ぎている場合はオーディオESの蓄積の継続と次のGOP狙いにする?) | |
1544 * #GOP先頭にこだわり過ぎると録画を逃すという線もあるので、適当に手を打つのも手 | |
1545 */ | |
1546 else { | |
1547 esbuf->started = 1; | |
1548 } | |
1549 #if 0 | |
1550 if ( is_audio_stream(pid, esbuf) && esbuf->Program->video_start ) { | |
1551 int audio_lipsync_offset = 0; | |
1552 int i; | |
1553 int64_t audio_pts = esbuf->pts; | |
1554 int adts_freq = AnalyzeAdifHeader(esbuf); | |
1555 int64_t adts_frame_time = ((1000/adts_freq) *27e6); /* PTSは27MHz */ | |
1556 /* オーディオ且つ、Programのビデオ蓄積が開始されていればオーディオの蓄積を行う */ | |
1557 while ( (esbuf->Program->video_pts > audio_pts +adts_frame_time/2) ) { | |
1558 /* オーディオデータを捨てると audio_pts は1フレーム分大きくなる */ | |
1559 i = esbuf_adts_start_code_prefix(esbuf, audio_lipsync_offset); /* 次のAACのデータを取得 */ | |
1560 if ( i != -1 ) { /* AACデータの終端か? */ | |
1561 audio_lipsync_offset += i; | |
1562 } else { | |
1563 break; | |
1564 } | |
1565 audio_pts += adts_frame_time; /* AACの1フレーム分、時間を進める */ | |
1566 } | |
1567 if ( esbuf->size != audio_lipsync_offset ) { /* 一致していない場合はコピー */ | |
1568 memmove(esbuf->buffer +audio_lipsync_offset, | |
1569 esbuf->buffer, | |
1570 esbuf->size -audio_lipsync_offset); | |
1571 esbuf->size -= audio_lipsync_offset; | |
1572 esbuf->started = 1; | |
1573 } | |
1574 } | |
1575 #endif | |
1576 /* AAC の実験コードここまで */ | |
1577 /* バッファをファイルに出力してクリア */ | |
1578 if ( esbuf->started ) { | |
1579 esbuf_write(esbuf, pid); | |
1580 esbuf_clear(esbuf); | |
1581 } | |
1582 } else { | |
1583 /* ES蓄積を新たに開始 */ | |
1584 es_started = 1; | |
1585 } | |
1586 } | |
1587 | |
1588 payload_length = pesbuf->size -payload_offset; | |
1589 /* ES蓄積処理 */ | |
1590 if ( es_started ) { | |
1591 /* ES蓄積開始済み(これからES蓄積開始を含む)なら、payloadをESとして追加 */ | |
1592 esbuf_add(esbuf, pesbuf->buffer +payload_offset, payload_length); | |
1593 } | |
1594 /* お疲れさまでした */ | |
1595 return 0; | |
1596 } | |
1597 | |
1598 /* PIDはesbufのAUDIO STREAMの一つであるか? */ | |
1599 static int is_audio_stream(const int pid, splitesbuf_t *esbuf) | |
1600 { | |
1601 int i = 0; | |
1602 int found = 0; | |
1603 program_t* program = esbuf->Program; | |
1604 while (i < program->audio_nb) | |
1605 { | |
1606 if (program->audio[i] == pid) { | |
1607 found = 1; | |
1608 break; | |
1609 } | |
1610 i++; | |
1611 } | |
1612 return found; | |
1613 } | |
1614 | |
1615 /* PIDはesbufのVIDEO STREAMの一つであるか? */ | |
1616 static int is_video_stream(const int pid, splitesbuf_t *esbuf) | |
1617 { | |
1618 int i = 0; | |
1619 int found = 0; | |
1620 program_t* program = esbuf->Program; | |
1621 while (i < program->video_nb) | |
1622 { | |
1623 if (program->video[i] == pid) { | |
1624 found = 1; | |
1625 break; | |
1626 } | |
1627 i++; | |
1628 } | |
1629 return found; | |
1630 } | |
1631 | |
1632 /* | |
1633 * ESをファイル出力する | |
1634 */ | |
1635 int esbuf_write(splitesbuf_t *esbuf, int pid) | |
1636 { | |
1637 int fd; | |
1638 int remain = esbuf->size; | |
1639 #define ES_FILE "/tmp/es.%d" | |
1640 char filename[1024]; | |
1641 filename[0] = '\0'; | |
1642 umask(0133); | |
1643 snprintf(filename, sizeof(filename), ES_FILE, pid); | |
1644 fd = open(filename, O_CREAT|O_APPEND|O_RDWR, 00644); | |
1645 while(remain > 0) | |
1646 { | |
1647 remain -= write(fd, esbuf->buffer+(esbuf->size-remain), remain); | |
1648 } | |
1649 close(fd); | |
1650 return 0; | |
1651 } | |
1652 | |
1653 | |
1654 /* | |
1655 * packet dump | |
1656 */ | |
1657 void dump_packet( const uint8_t *packet ) | |
1658 { | |
1659 int i = 0; | |
1660 uint8_t *p = (uint8_t*)packet; | |
1661 char tmp[17]; | |
1662 | |
1663 printf("HEADER 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F <ASCII>\n"); | |
1664 while(i < LENGTH_PACKET) { | |
1665 if ( (i%16) == 0 ) { | |
1666 printf("0x%04X ", i); | |
1667 } | |
1668 printf("%02x ", *(p+i)); | |
1669 if ( isprint(*(p+i)) ){ | |
1670 tmp[i%16] = *(p+i); | |
1671 } | |
1672 else { | |
1673 tmp[i%16] = '.'; | |
1674 } | |
1675 if ((i%16) == 15) { | |
1676 tmp[sizeof(tmp)-1] = '\0'; | |
1677 printf(" %s\n", tmp); | |
1678 } | |
1679 i++; | |
1680 } | |
1681 putchar('\n'); | |
1682 } | |
1683 | |
1684 /* | |
1685 * TOT の JST_time を解析する | |
1686 */ | |
1687 static int parse_tot( const unsigned char* packet, time_t *t ) | |
1688 { | |
1689 /* 注意事項 | |
1690 * 本当は TOT が有効かどうかをチェックするべきですがしていません | |
1691 * サマータイム関係は無視しています | |
1692 */ | |
1693 struct tm tm; | |
1694 time_t t2; | |
1695 int k; | |
1696 uint8_t *p = (uint8_t*)packet; | |
1697 unsigned int MJD; | |
1698 tm.tm_wday = 0; | |
1699 tm.tm_yday = 0; | |
1700 tm.tm_isdst = 0; | |
1701 | |
1702 p += 8; | |
1703 MJD = (*(p) & 0xff) <<8; | |
1704 p++; | |
1705 MJD |= *(p) & 0xff; | |
1706 printf("MJD[%x].\n", MJD); | |
1707 | |
1708 /* ARIB STD-B10 第2部 付録C の公式より MJD to YYYYMMDD */ | |
1709 tm.tm_year = (int)floor((MJD - 15078.2)/365.25); | |
1710 tm.tm_mon = (int)floor((MJD - 14956.1 - floor(tm.tm_year * 365.25))/30.6001); | |
1711 tm.tm_mday = MJD - 14956 - floor(tm.tm_year * 365.25) - floor(tm.tm_mon * 30.6001); | |
1712 if ( tm.tm_mon == 14 || tm.tm_mon == 15 ) | |
1713 k = 1; | |
1714 else | |
1715 k = 0; | |
1716 tm.tm_year += k; | |
1717 tm.tm_mon = tm.tm_mon -1 - k * 12; | |
1718 tm.tm_mon--; | |
1719 | |
1720 /* HHMISSは2進化10進数 */ | |
1721 p++; | |
1722 tm.tm_hour = ((*p & 0xf0) >>4)*10 + (*p & 0x0f); | |
1723 p++; | |
1724 tm.tm_min = ((*p & 0xf0) >>4)*10 + (*p & 0x0f); | |
1725 p++; | |
1726 tm.tm_sec = ((*p & 0xf0) >>4)*10 + (*p & 0x0f); | |
1727 | |
1728 *t = mktime(&tm); | |
1729 time(&t2); | |
1730 // printf("time[%d] TOT[%d].\n", t2, *t); | |
1731 | |
1732 return TRUE; | |
1733 } | |
1734 | |
1735 static int64_t get_pts(const uint8_t *p) | |
1736 { | |
1737 int64_t pts = (int64_t)((p[0] >> 1) & 0x07) << 30; | |
1738 pts |= (AV_RB16(p + 1) >> 1) << 15; | |
1739 pts |= AV_RB16(p + 3) >> 1; | |
1740 return pts; | |
1741 } | |
1742 | |
1743 static int get_pmt_version(const uint8_t *p) | |
1744 { | |
1745 return ((p[6] >> 1) & 0x1f); | |
1746 } | |
1747 | |
1748 | |
1749 #if 0 | |
1750 void forward_stc(timespec *stc, timespec offset) | |
1751 { | |
1752 struct timespec local_timespec; | |
1753 | |
1754 clock_gettime(CLOCK_REALTIME, &local_timespec); | |
1755 | |
1756 stc->tv_sec = local_timespec.tv_sec + offset.tv_sec; | |
1757 stc->tv_nsec = local_timespec.tv_nsec + offset.tv_nsec; | |
1758 if ( stc->tv_nsec >= 1 * 1000 * 1000 * 1000 ) { | |
1759 stc->tv_nsec -= 1 * 1000 * 1000 * 1000; | |
1760 stc->tv_sec += 1; | |
1761 } else if ( stc->tv_nsec < 0 ) { | |
1762 stc->tv_nsec = 1 * 1000 * 1000 * 1000 + stc->tv_nsec; | |
1763 stc->tv_sec -= 1; | |
1764 } | |
1765 } | |
1766 #endif | |
1767 void search_mpeg_system_header(const uint8_t *packet) | |
1768 { | |
1769 int i; | |
1770 uint8_t *p = (uint8_t*)packet; | |
1771 i = 0; | |
1772 for( i=0; i < LENGTH_PACKET-4; i++) { | |
1773 if( p[i] == 0x00 && p[i+1] == 0x00 && p[i+2] == 0x01 && p[i+3] == 0xb8 ){ | |
1774 dump_packet(packet ); | |
1775 } | |
1776 } | |
1777 } | |
1778 | |
1779 /* | |
1780 * この関数では、現在の仕様では、先頭位置の「次の」ADTS start codeまでの長さを返却します | |
1781 * ret == 0 : 仕様上あり得ない | |
1782 * ret > 0 : 見つかった場合 | |
1783 * ret == -1 : 見つからなかった場合 | |
1784 */ | |
1785 static int esbuf_adts_start_code_prefix(splitesbuf_t *esbuf, int offset) | |
1786 { | |
1787 /* | |
1788 * start code prefix のうち、先頭12bit は 1 固定であるが、13bit 目は id に該当 | |
1789 * MPEG4なオーディオが来た場合に対応出来ないので、13bit 目は見ないように改造するべき | |
1790 */ | |
1791 uint8_t adts_start_code_prefix[2] = {0xFF, 0xF8}; /* とりあえず決め打ち */ | |
1792 int i = offset +1; | |
1793 | |
1794 /* 小さすぎる */ | |
1795 if(esbuf->size -offset < sizeof adts_start_code_prefix){ | |
1796 return -1; | |
1797 } | |
1798 for(i = 1; i < esbuf->size -offset - sizeof adts_start_code_prefix; i++) { | |
1799 if(!memcmp(esbuf->buffer +offset + i ,adts_start_code_prefix, sizeof adts_start_code_prefix)){ | |
1800 #if 0 | |
1801 printf("adts start code found.i[%d]. 0[%02x] 1[%02x] 2[%02x] 3[%02x] 4[%02x] 5[%02x] 6[%02x]\n", | |
1802 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) ); | |
1803 #endif | |
1804 return i; | |
1805 } | |
1806 } | |
1807 return -1; | |
1808 } | |
1809 | |
1810 /* ADIF HEADER解析 */ | |
1811 static int AnalyzeAdifHeader(splitesbuf_t *esbuf) | |
1812 { | |
1813 int id = 0; /* 0:MPEG-4 1:MPEG-2 */ | |
1814 int layer = 0; /* 常に 0x00 */ | |
1815 int protection_absent = 0; /*保護属性 0:保護なし 1:保護あり */ | |
1816 int profile = 0; /* 00:MAIN 01:LC 10:SSR 11:(reserved) */ | |
1817 int sampling_frequency_index = 0; /* サンプリング周波数テーブル値 */ | |
1818 int private_bit = 0; /* private bit */ | |
1819 int channel_configuration = 0; /* チャンネル数 */ | |
1820 int original_copy = 0; | |
1821 int home = 0; /* homeってなに? */ | |
1822 int copyright_identification_bit = 0; /* 著作権証明ビット */ | |
1823 int copyright_identification_start = 0; /* 著作権証明開始ビット */ | |
1824 int aac_frame_length = 0; /* AACフレーム長 */ | |
1825 int adts_buffer_fullness = 0; /* ADTSバッファ残量 */ | |
1826 int no_raw_data_blocks_in_frame = 0; /* データブロックまでの残量 */ | |
1827 /* | |
1828 * サンプリング周波数テーブル(ヘッダのINDEXが添字) | |
1829 * 単位:Hz | |
1830 */ | |
1831 int sampling_frequency_table[16] = | |
1832 { | |
1833 96000, | |
1834 88200, | |
1835 64000, | |
1836 48000, | |
1837 44100, | |
1838 32000, | |
1839 24000, | |
1840 22050, | |
1841 16000, | |
1842 12000, | |
1843 11025, | |
1844 8000, | |
1845 -1, | |
1846 -1, | |
1847 -1, | |
1848 -1 | |
1849 }; | |
1850 | |
1851 uint8_t *p = esbuf->buffer; | |
1852 if ( esbuf->size < 8 ) { | |
1853 return -1; | |
1854 } | |
1855 | |
1856 id = get_adif_id(p+1); | |
1857 layer = get_adif_layer(p+1); | |
1858 protection_absent = get_adif_protection_absent(p+1); | |
1859 profile = get_adif_profile(p+2); | |
1860 sampling_frequency_index = get_adif_sampling_frequency_index(p+2); | |
1861 private_bit = get_adif_private_bit(p+2); | |
1862 channel_configuration = get_adif_channel_configuration(p+3); | |
1863 original_copy = get_adif_original_copy(p+3); | |
1864 home = get_adif_home(p+3); | |
1865 copyright_identification_bit = get_adif_copyright_idication_bit(p+3); | |
1866 copyright_identification_start = get_adif_copyright_idication_start(p+3); | |
1867 aac_frame_length = get_adif_aac_frame_length(p+3); | |
1868 adts_buffer_fullness = get_adts_buffer_fullness(p+5); | |
1869 no_raw_data_blocks_in_frame = get_adts_no_raw_data_blocks_in_frame(p+5); | |
1870 | |
1871 /* | |
1872 * とりあえず return は サンプリング周波数としておく | |
1873 * 本当は取得した情報を構造体にして返却する方がいいのだろうけど、 | |
1874 * 利用する予定もないので取得するだけにしておく | |
1875 */ | |
1876 return sampling_frequency_table[sampling_frequency_index]; | |
1877 } | |
1878 | |
1879 static int get_adif_id(uint8_t *p) | |
1880 { | |
1881 return ((*p & 0x08) >>3); | |
1882 } | |
1883 | |
1884 static int get_adif_layer(uint8_t *p) | |
1885 { | |
1886 return ((*p & 0x06) >>1); | |
1887 } | |
1888 | |
1889 static int get_adif_protection_absent(uint8_t *p) | |
1890 { | |
1891 return (*p & 0x01); | |
1892 } | |
1893 | |
1894 static int get_adif_profile(uint8_t *p) | |
1895 { | |
1896 return ((*p & 0xc0) >>6); | |
1897 } | |
1898 | |
1899 static int get_adif_sampling_frequency_index(uint8_t *p) | |
1900 { | |
1901 return ((*p & 0x3c) >>2); | |
1902 } | |
1903 | |
1904 static int get_adif_private_bit(uint8_t *p) | |
1905 { | |
1906 return ((*p & 0x02) >>1); | |
1907 } | |
1908 | |
1909 static int get_adif_channel_configuration(uint8_t *p) | |
1910 { | |
1911 return ((*p & 0x01) <<2 | (*(p+1) & 0xc0 >>6) ); | |
1912 } | |
1913 | |
1914 static int get_adif_original_copy(uint8_t *p) | |
1915 { | |
1916 return (*p & 0x20 >>5 ); | |
1917 } | |
1918 | |
1919 static int get_adif_home(uint8_t *p) | |
1920 { | |
1921 return (*p & 0x10 >>4 ); | |
1922 } | |
1923 | |
1924 static int get_adif_copyright_idication_bit(uint8_t *p) | |
1925 { | |
1926 return (*p & 0x08 >>3 ); | |
1927 } | |
1928 | |
1929 static int get_adif_copyright_idication_start(uint8_t *p) | |
1930 { | |
1931 return (*p & 0x04 >>2 ); | |
1932 } | |
1933 | |
1934 static int get_adif_aac_frame_length(uint8_t *p) | |
1935 { | |
1936 return ( ((*p & 0x02) <<11) || ((*(p+1) & 0xff) <<3) || ((*(p+2) & 0xe0) >>5) ); | |
1937 } | |
1938 | |
1939 static int get_adts_buffer_fullness(uint8_t *p) | |
1940 { | |
1941 return ( ((*p & 0x1f) <<6) || ((*(p+1) &0xfc) >>2)); | |
1942 } | |
1943 | |
1944 static int get_adts_no_raw_data_blocks_in_frame(uint8_t *p) | |
1945 { | |
1946 return (*p & 0x03); | |
1947 } | |
1948 | |
1949 /* GOP START CODE を検索する */ | |
1950 static int search_gop_start_code(splitesbuf_t *esbuf) | |
1951 { | |
1952 uint8_t gop_start_code[4] = {0x00, 0x00, 0x01, 0xb8}; | |
1953 int i; | |
1954 | |
1955 /* 小さすぎる */ | |
1956 if ( esbuf->size < sizeof gop_start_code ){ | |
1957 return -1; | |
1958 } | |
1959 for(i = 0; i < esbuf->size - sizeof gop_start_code; i++) { | |
1960 if(!memcmp(esbuf->buffer +i ,gop_start_code, sizeof gop_start_code)){ | |
1961 return i; | |
1962 } | |
1963 } | |
1964 return -1; | |
1965 } |