comparison src/tssplitter_lite.c @ 124:9c7bc6c0327e

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