comparison recpt1/tssplitter_lite.c @ 100:aeba1988234f

support macros to specify sid: - macros: hd, sd1, sd2, sd3, 1seg and all are supported. - if sid has been specified but no suitable sid found, fall back to "all". technical summary: - use splitter structure as the argument where it is applicable. - add tab configuration to some source files.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Sat, 13 Feb 2010 19:43:25 +0900
parents 3a3f15b063e1
children 3f7288b0672c
comparison
equal deleted inserted replaced
99:3a3f15b063e1 100:aeba1988234f
1 /* -*- tab-width: 4; indent-tabs-mode: t -*- */
1 /* tssplitter_lite.c -- split TS stream. 2 /* tssplitter_lite.c -- split TS stream.
2 3
3 Copyright 2009 querulous 4 Copyright 2009 querulous
4 Copyright 2010 Naoya OYAMA <naoya.oyama@gmail.com> 5 Copyright 2010 Naoya OYAMA <naoya.oyama@gmail.com>
5 6
26 #include "decoder.h" 27 #include "decoder.h"
27 #include "recpt1.h" 28 #include "recpt1.h"
28 #include "tssplitter_lite.h" 29 #include "tssplitter_lite.h"
29 30
30 /* prototypes */ 31 /* prototypes */
31 static char** AnalyzeSid(char* sid); 32 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf);
32 static int ReadTs( unsigned char** pat, unsigned char* pids, char** sid_list, unsigned char* pmt_pids, ARIB_STD_B25_BUFFER *sbuf, int* pmt_remain, int* pmt_counter); 33 static int AnalyzePat(splitter *sp, unsigned char *buf);
33 static int AnalyzePat(unsigned char* buf, unsigned char** pat, unsigned char* pids, char** sid_list, unsigned char* pmt_pids, int* pmt_remain); 34 static int RecreatePat(splitter *sp, unsigned char *buf, int *pos);
34 static int RecreatePat(unsigned char* buf, unsigned char** pat, unsigned char* pids, int *pos); 35 static char** AnalyzeSid(char *sid);
35 static int AnalyzePmt(unsigned char* buf, unsigned char* pids); 36 static int AnalyzePmt(splitter *sp, unsigned char *buf);
36 static int GetCrc32(unsigned char* data, int len); 37 static int GetCrc32(unsigned char *data, int len);
37 static int GetPid(unsigned char* data); 38 static int GetPid(unsigned char *data);
38 39
39 /** 40 /**
40 * サービスID解析 41 * サービスID解析
41 */ 42 */
42 static char** AnalyzeSid( 43 static char** AnalyzeSid(
154 { 155 {
155 free(sp); 156 free(sp);
156 return NULL; 157 return NULL;
157 } 158 }
158 sp->pat_count = 0xFF; 159 sp->pat_count = 0xFF;
159 sp->pmt_remain = -1; 160 sp->pmt_retain = -1;
160 sp->pmt_counter = 0; 161 sp->pmt_counter = 0;
161 162
162 return sp; 163 return sp;
163 } 164 }
164 165
170 ARIB_STD_B25_BUFFER *sbuf // [in] 入力TS 171 ARIB_STD_B25_BUFFER *sbuf // [in] 入力TS
171 ) 172 )
172 { 173 {
173 int result; 174 int result;
174 // TS解析 175 // TS解析
175 result = ReadTs(&(sp->pat), sp->pids, sp->sid_list, sp->pmt_pids, sbuf, &(sp->pmt_remain), &(sp->pmt_counter)); 176 result = ReadTs(sp, sbuf);
176 177
177 return result; 178 return result;
178 } 179 }
179 180
180 /** 181 /**
181 * 終了処理 182 * 終了処理
182 */ 183 */
183 void split_shutdown( 184 void split_shutdown(splitter* sp)
184 splitter* sp
185 )
186 { 185 {
187 if ( sp != NULL ) { 186 if ( sp != NULL ) {
188 if ( sp->pat != NULL ) 187 if ( sp->pat != NULL )
189 { 188 {
190 free(sp->pat); 189 free(sp->pat);
203 /** 202 /**
204 * TS 解析処理 203 * TS 解析処理
205 * 204 *
206 * 対象のチャンネル番号のみの PAT の再構築と出力対象 PID の抽出を行う 205 * 対象のチャンネル番号のみの PAT の再構築と出力対象 PID の抽出を行う
207 */ 206 */
208 static int ReadTs( 207 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf)
209 unsigned char** pat, // [out] PAT 情報(再構築後) 208 {
209 #if 0
210 unsigned char **pat, // [out] PAT 情報(再構築後)
210 unsigned char* pids, // [out] 出力対象 PID 情報 211 unsigned char* pids, // [out] 出力対象 PID 情報
211 char** sid_list, // [in] 出力対象サービス ID のリスト 212 char** sid_list, // [in] 出力対象サービス ID のリスト
212 unsigned char* pmt_pids, // [in] 出力対象PIDのPMT PID 213 unsigned char* pmt_pids, // [in] 出力対象PIDのPMT PID
213 ARIB_STD_B25_BUFFER *sbuf, // [in] pt1_drvの入力TS 214 , // [in] pt1_drvの入力TS
214 int* pmt_remain, // [in] PMTの落とすべき数 215 int* pmt_retain, // [in] PMTの落とすべき数
215 int* pmt_counter // [out] PMTの落とした数 216 int* pmt_counter // [out] PMTの落とした数
216 ) 217 #endif
217 { 218
218 int length = sbuf->size; 219 int length = sbuf->size;
219 int pid; 220 int pid;
220 int result = TSS_ERROR; 221 int result = TSS_ERROR;
221 int index; 222 int index;
222 223
223 index = 0; 224 index = 0;
224 while (((length - index - LENGTH_PACKET)) > 0) 225 while(length - index - LENGTH_PACKET > 0) {
225 { 226 pid = GetPid(sbuf->data + index + 1);
226 pid = GetPid(((unsigned char*)sbuf->data)+index+1);
227 // PAT 227 // PAT
228 if (0x0000 == pid) 228 if(0x0000 == pid) {
229 { 229 result = AnalyzePat(sp, sbuf->data + index);
230 result = AnalyzePat(((unsigned char*)sbuf->data)+index, pat, pids, sid_list, pmt_pids, pmt_remain); 230 if(TSS_SUCCESS != result) {
231 if (TSS_SUCCESS != result)
232 {
233 /* 下位の関数内部でmalloc error発生 */ 231 /* 下位の関数内部でmalloc error発生 */
234 return result; 232 return result;
235 } 233 }
236 } 234 }
237 235
238 // PMT 236 // PMT
239 /* 残すpmt_pidである場合には、pmtに書かれている 237 /* 残すpmt_pidである場合には、pmtに書かれている
240 * 残すべきPCR/AUDIO/VIDEO PIDを取得する */ 238 * 残すべきPCR/AUDIO/VIDEO PIDを取得する */
241 if (pmt_pids[pid] == 1) 239 if(sp->pmt_pids[pid] == 1) {
242 {
243 // fprintf(stderr, "\npmt_pid=%d\n", pid);
244 /* この中にはPMT毎に一度しか入らないようにしておく */ 240 /* この中にはPMT毎に一度しか入らないようにしておく */
245 AnalyzePmt(((unsigned char*)sbuf->data)+index, pids); 241 AnalyzePmt(sp, sbuf->data + index);
246 pmt_pids[pid]++; 242 sp->pmt_pids[pid]++;
247 *pmt_counter += 1; 243 sp->pmt_counter += 1;
248 } 244 }
249 /* 録画する全てのPMTについて、中にあるPCR/AUDIO/VIDEOのPIDを 245 /* 録画する全てのPMTについて、中にあるPCR/AUDIO/VIDEOのPIDを
250 * 得る */ 246 * 得る */
251 /* pmt_counter と pmt_remain が一致する場合に条件は満たされる */ 247 /* pmt_counter と pmt_retain が一致する場合に条件は満たされる */
252 if ((*pmt_counter == *pmt_remain)) { 248 if(sp->pmt_counter == sp->pmt_retain) {
253 result = TSS_SUCCESS; 249 result = TSS_SUCCESS;
254 break; 250 break;
255 } 251 }
256 else { 252 else {
257 result = TSS_ERROR; 253 result = TSS_ERROR;
285 sptr = sbuf->data; 281 sptr = sbuf->data;
286 dptr = dbuf->buffer; 282 dptr = dbuf->buffer;
287 283
288 while(sbuf->size > s_offset) { 284 while(sbuf->size > s_offset) {
289 pid = GetPid(sptr + s_offset + 1); 285 pid = GetPid(sptr + s_offset + 1);
290 switch(pid) { 286 switch(pid) {
291 287
292 // PAT 288 // PAT
293 case 0x0000: 289 case 0x0000:
294 // 巡回カウンタカウントアップ 290 // 巡回カウンタカウントアップ
295 if(0xFF == splitter->pat_count) { 291 if(0xFF == splitter->pat_count) {
323 /** 319 /**
324 * PAT 解析処理 320 * PAT 解析処理
325 * 321 *
326 * PAT を解析し、出力対象チャンネルが含まれているかチェックを行い、PAT を再構築する 322 * PAT を解析し、出力対象チャンネルが含まれているかチェックを行い、PAT を再構築する
327 */ 323 */
328 static int AnalyzePat( 324 static int AnalyzePat(splitter *sp, unsigned char *buf)
325 #if 0
329 unsigned char* buf, // [in] 読み込んだバッファ 326 unsigned char* buf, // [in] 読み込んだバッファ
330 unsigned char** pat, // [out] PAT 情報(再構築後) 327 unsigned char** pat, // [out] PAT 情報(再構築後)
331 unsigned char* pids, // [out] 出力対象 PID 情報 328 unsigned char* pids, // [out] 出力対象 PID 情報
332 char** sid_list, // [in] 出力対象サービス ID のリスト 329 char** sid_list, // [in] 出力対象サービス ID のリスト
333 unsigned char* pmt_pids, // [out] サービス ID に対応する PMT の PID 330 unsigned char* pmt_pids, // [out] サービス ID に対応する PMT の PID
334 int* pmt_remain 331 int* pmt_retain // [out] 残すPMTの数
335 ) // [out] 落とすPMTの数 332 )
333 #endif
336 { 334 {
337 int pos[MAX_PID]; 335 int pos[MAX_PID];
338 int service_id; 336 int service_id;
339 int i, j=0, k; 337 int i, j, k;
340 int size = 0; 338 int size = 0;
341 int pid; 339 int pid;
342 int result = TSS_SUCCESS; 340 int result = TSS_SUCCESS;
343 char **p; 341 char **p;
344 int sid_found; 342 int sid_found = FALSE;
345 int avail_sids[MAX_SERVICES]; 343 int avail_sids[MAX_SERVICES];
346 344
347 if(*pat == NULL) { 345 unsigned char *pat = sp->pat;
346 unsigned char *pids = sp->pids;
347 char **sid_list = sp->sid_list;
348 unsigned char *pmt_pids = sp->pmt_pids;
349
350 char chosen_sid[512];
351 chosen_sid[0] = '\0';
352
353 if(pat == NULL) {
348 /* 初期化 */ 354 /* 初期化 */
349 *pmt_remain = 0; 355 sp->pmt_retain = 0;
350 memset(pos, 0, sizeof(pos)); 356 memset(pos, 0, sizeof(pos));
351 size = buf[7]; 357 size = buf[7];
358
359 /* prescan SID/PMT */
360 for(i = 17, j = 0; i < (size + 8) - 4; i = i + 4, j++) {
361 avail_sids[j] = (buf[i] << 8) + buf[i+1];
362 sp->avail_pmts[j] = GetPid(&buf[i+2]);
363 }
364 sp->num_pmts = j;
352 365
353 // 対象チャンネル判定 366 // 対象チャンネル判定
354 /* size + 8 = パケット全長 */ 367 /* size + 8 = パケット全長 */
355 /* 最終 4 バイトはCRCなので飛ばす */ 368 /* 最終 4 バイトはCRCなので飛ばす */
356 for(i = 17; i < (size + 8) - 4; i = i + 4) { 369 for(i = 17; i < (size + 8) - 4; i = i + 4) {
357 370
358 sid_found = 0; 371 service_id = (buf[i] << 8) + buf[i+1];
359 service_id = (buf[i] << 8) + buf[i + 1];
360 avail_sids[j] = service_id;
361 p = sid_list; 372 p = sid_list;
362 373
363 while(*p) { 374 while(*p) {
364 if(service_id == atoi(*p)) { 375 if(service_id == atoi(*p)) {
365 /* 録画対象 = 落とす対象とはしないものなので、基本的に何もしない */
366 /* 録画対象の pmt_pids は 1 とする */ 376 /* 録画対象の pmt_pids は 1 とする */
367 /* 録画対象の pmt の pids は 1 とする */ 377 /* 録画対象の pmt の pids は 1 とする */
368 pid = GetPid(&buf[i + 2]); 378 pid = GetPid(&buf[i + 2]);
369 *(pmt_pids+pid) = 1; 379 *(pmt_pids+pid) = 1;
370 *(pids+pid) = 1; 380 *(pids+pid) = 1;
371 pos[pid] = i; 381 pos[pid] = i;
372 sid_found = 1; 382 sid_found = TRUE;
373 *pmt_remain += 1; 383 sp->pmt_retain += 1;
374 // fprintf(stderr, "sid=%d pid=%d\n", service_id, pid); 384 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id);
375 break; 385 p++;
386 continue;
376 } 387 }
377 else if(strstr(*p, "all")) { 388 else if(!strcasecmp(*p, "hd") || !strcasecmp(*p, "sd1")) {
389 /* hd/sd1 指定時には1番目のサービスを保存する */
390 if(service_id == avail_sids[0]) {
391 pid = GetPid(&buf[i + 2]);
392 *(pmt_pids+pid) = 1;
393 *(pids+pid) = 1;
394 pos[pid] = i;
395 sid_found = TRUE;
396 sp->pmt_retain += 1;
397 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id);
398 }
399 p++;
400 continue;
401 }
402 else if(!strcasecmp(*p, "sd2")) {
403 /* sd2 指定時には2番目のサービスを保存する */
404 if(service_id == avail_sids[1]) {
405 pid = GetPid(&buf[i + 2]);
406 *(pmt_pids+pid) = 1;
407 *(pids+pid) = 1;
408 pos[pid] = i;
409 sid_found = TRUE;
410 sp->pmt_retain += 1;
411 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id);
412 }
413 p++;
414 continue;
415 }
416 else if(!strcasecmp(*p, "sd3")) {
417 /* sd3 指定時には3番目のサービスを保存する */
418 if(service_id == avail_sids[2]) {
419 pid = GetPid(&buf[i + 2]);
420 *(pmt_pids+pid) = 1;
421 *(pids+pid) = 1;
422 pos[pid] = i;
423 sid_found = TRUE;
424 sp->pmt_retain += 1;
425 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id);
426 }
427 p++;
428 continue;
429 }
430 else if(!strcasecmp(*p, "1seg")) {
431 /* 1seg 指定時には PMTPID=0x1FC8 のサービスを保存する */
432 pid = GetPid(&buf[i + 2]);
433 if(pid == 0x1FC8) {
434 *(pmt_pids+pid) = 1;
435 *(pids+pid) = 1;
436 pos[pid] = i;
437 sid_found = TRUE;
438 sp->pmt_retain += 1;
439 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id);
440 }
441 p++;
442 continue;
443 }
444 else if(!strcasecmp(*p, "all")) {
378 /* all指定時には全保存する */ 445 /* all指定時には全保存する */
379 pid = GetPid(&buf[i + 2]); 446 pid = GetPid(&buf[i + 2]);
380 *(pmt_pids+pid) = 1; 447 *(pmt_pids+pid) = 1;
381 *(pids+pid) = 1; 448 *(pids+pid) = 1;
382 pos[pid] = i; 449 pos[pid] = i;
383 sid_found = 1; 450 sid_found = TRUE;
384 *pmt_remain += 1; 451 sp->pmt_retain += 1;
385 // fprintf(stderr, "sid=%d pid=%d\n", service_id, pid); 452 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id);
386 break; 453 break;
387 } 454 }
388 455
389 p++; 456 p++;
390 } /* while */ 457 } /* while */
391 458 }
392 j++; 459
460 /* if sid has been specified but no sid found, fall back to all */
461 if(*sid_list && !sid_found) {
462 for(i = 17; i < (size + 8) - 4; i = i + 4) {
463 service_id = (buf[i] << 8) + buf[i+1];
464 pid = GetPid(&buf[i + 2]);
465 *(pmt_pids+pid) = 1;
466 *(pids+pid) = 1;
467 pos[pid] = i;
468 sid_found = TRUE;
469 sp->pmt_retain += 1;
470 sprintf(chosen_sid, "%s %d", *chosen_sid ? chosen_sid : "", service_id);
471 }
393 } 472 }
394 473
395 /* print SIDs */ 474 /* print SIDs */
396 fprintf(stderr, "Available sid = "); 475 fprintf(stderr, "Available sid = ");
397 for(k=0; k<j; k++) 476 for(k=0; k < sp->num_pmts; k++)
398 fprintf(stderr, "%d ", avail_sids[k]); 477 fprintf(stderr, "%d ", avail_sids[k]);
399 fprintf(stderr, "\n"); 478 fprintf(stderr, "\n");
400 479 fprintf(stderr, "Chosen sid =%s\n", chosen_sid);
401 fprintf(stderr, "Chosen sid = "); 480
402 p = sid_list; 481 #if 0
403 while(*p != NULL) { 482 /* print PMTs */
404 fprintf(stderr, "%s ", *p); 483 fprintf(stderr, "Available PMT = ");
405 p++; 484 for(k=0; k < sp->num_pmts; k++)
406 } 485 fprintf(stderr, "%d ", sp->avail_pmts[k]);
407 fprintf(stderr, "\n"); 486 fprintf(stderr, "\n");
487 #endif
408 488
409 // PAT 再構築 489 // PAT 再構築
410 result = RecreatePat(buf, pat, pids, pos); 490 result = RecreatePat(sp, buf, pos);
411 #if 0 491 #if 0
412 int tc; 492 int tc;
413 for(tc=0; tc<188; tc++) 493 for(tc=0; tc<188; tc++)
414 fprintf(stderr, "%02x ", *(*pat+tc)); 494 fprintf(stderr, "%02x ", *(pat+tc));
415 #endif 495 #endif
416 } 496 }
417 497
418 return(result); 498 return(result);
419 } 499 }
421 /** 501 /**
422 * PAT 再構築処理 502 * PAT 再構築処理
423 * 503 *
424 * PMT から出力対象チャンネル以外のチャンネル情報を削除し、PAT を再構築する 504 * PMT から出力対象チャンネル以外のチャンネル情報を削除し、PAT を再構築する
425 */ 505 */
426 static int RecreatePat( 506 static int RecreatePat(splitter *sp, unsigned char *buf, int *pos)
507 #if 0
427 unsigned char* buf, // [in] 読み込んだバッファ 508 unsigned char* buf, // [in] 読み込んだバッファ
428 unsigned char** pat, // [out] PAT 情報(再構築後) 509 unsigned char** pat, // [out] PAT 情報(再構築後)
429 unsigned char* pids, // [out] 出力対象 PID 情報 510 unsigned char* pids, // [out] 出力対象 PID 情報
430 int *pos) // [in] 取得対象 PMT のバッファ中の位置 511 int *pos) // [in] 取得対象 PMT のバッファ中の位置
512 #endif
431 { 513 {
432 unsigned char y[LENGTH_CRC_DATA]; 514 unsigned char y[LENGTH_CRC_DATA];
433 int crc; 515 int crc;
434 int i; 516 int i;
435 int j; 517 int j;
462 y[2] = pid_num * 4 + 0x0d; 544 y[2] = pid_num * 4 + 0x0d;
463 // CRC 計算 545 // CRC 計算
464 crc = GetCrc32(y, LENGTH_PAT_HEADER + pid_num*4); 546 crc = GetCrc32(y, LENGTH_PAT_HEADER + pid_num*4);
465 547
466 // PAT 再構成 548 // PAT 再構成
467 *pat = (unsigned char*)malloc(LENGTH_PACKET); 549 sp->pat = (unsigned char*)malloc(LENGTH_PACKET);
468 if ( *pat == NULL ) 550 if(sp->pat == NULL)
469 { 551 {
470 fprintf(stderr, "RecreatePat() malloc error.\n"); 552 fprintf(stderr, "RecreatePat() malloc error.\n");
471 return(TSS_NULL); 553 return(TSS_NULL);
472 } 554 }
473 memset(*pat, 0xFF, LENGTH_PACKET); 555 memset(sp->pat, 0xFF, LENGTH_PACKET);
474 for (i = 0; i < 5; i++) 556 for (i = 0; i < 5; i++)
475 { 557 {
476 (*pat)[i] = buf[i]; 558 (sp->pat)[i] = buf[i];
477 } 559 }
478 for (i = 0; i < LENGTH_PAT_HEADER + pid_num*4; i++) 560 for (i = 0; i < LENGTH_PAT_HEADER + pid_num*4; i++)
479 { 561 {
480 (*pat)[i + 5] = y[i]; 562 (sp->pat)[i + 5] = y[i];
481 } 563 }
482 (*pat)[5 + LENGTH_PAT_HEADER + pid_num*4] = (crc >> 24) & 0xFF; 564 (sp->pat)[5 + LENGTH_PAT_HEADER + pid_num*4] = (crc >> 24) & 0xFF;
483 (*pat)[6 + LENGTH_PAT_HEADER + pid_num*4] = (crc >> 16) & 0xFF; 565 (sp->pat)[6 + LENGTH_PAT_HEADER + pid_num*4] = (crc >> 16) & 0xFF;
484 (*pat)[7 + LENGTH_PAT_HEADER + pid_num*4] = (crc >> 8) & 0xFF; 566 (sp->pat)[7 + LENGTH_PAT_HEADER + pid_num*4] = (crc >> 8) & 0xFF;
485 (*pat)[8 + LENGTH_PAT_HEADER + pid_num*4] = (crc ) & 0xFF; 567 (sp->pat)[8 + LENGTH_PAT_HEADER + pid_num*4] = (crc ) & 0xFF;
568
486 return(TSS_SUCCESS); 569 return(TSS_SUCCESS);
487 } 570 }
488 571
489 /** 572 /**
490 * PMT 解析処理 573 * PMT 解析処理
491 * 574 *
492 * PMT を解析し、保存対象の PID を特定する 575 * PMT を解析し、保存対象の PID を特定する
493 */ 576 */
494 static int AnalyzePmt( 577 static int AnalyzePmt(splitter *sp, unsigned char *buf)
578 #if 0
495 unsigned char* buf, // [in] 読み込んだバッファ 579 unsigned char* buf, // [in] 読み込んだバッファ
496 unsigned char* pids) // [out] 出力対象 PID 情報 580 unsigned char* pids) // [out] 出力対象 PID 情報
581 #endif
497 { 582 {
498 unsigned char Nall; 583 unsigned char Nall;
499 unsigned char N; 584 unsigned char N;
500 int pcr; 585 int pcr;
501 int epid; 586 int epid;
502 587
503 Nall = ((buf[6] & 0x0F) << 4) + buf[7]; 588 Nall = ((buf[6] & 0x0F) << 4) + buf[7];
504 589
505 // PCR 590 // PCR
506 pcr = GetPid(&buf[13]); 591 pcr = GetPid(&buf[13]);
507 pids[pcr] = 1; 592 sp->pids[pcr] = 1;
508 // fprintf(stderr, "pcr_pid:%5d", pcr);
509 593
510 N = ((buf[15] & 0x0F) << 4) + buf[16] + 16 + 1; 594 N = ((buf[15] & 0x0F) << 4) + buf[16] + 16 + 1;
511 595
512 // ES PID 596 // ES PID
513 while (N < Nall + 8 - 4) 597 while (N < Nall + 8 - 4)
515 // ストリーム種別が 0x0D(type D)は出力対象外 599 // ストリーム種別が 0x0D(type D)は出力対象外
516 if (0x0D != buf[N]) 600 if (0x0D != buf[N])
517 { 601 {
518 epid = GetPid(&buf[N + 1]); 602 epid = GetPid(&buf[N + 1]);
519 603
520 pids[epid] = 1; 604 sp->pids[epid] = 1;
521 // fprintf(stderr, "%10d", epid);
522 } 605 }
523 N += 4 + (((buf[N + 3]) & 0x0F) << 4) + buf[N + 4] + 1; 606 N += 4 + (((buf[N + 3]) & 0x0F) << 4) + buf[N + 4] + 1;
524 } 607 }
525 608
526 return TSS_SUCCESS; 609 return TSS_SUCCESS;