comparison recpt1/tssplitter_lite.c @ 120:8e438d2a1529

add tiny lipsync code.
author Naoya OYAMA <naoya.oyama@gmail.com>
date Sun, 25 Apr 2010 18:26:32 +0900
parents 4e7aaa72e158
children e915d31c5bd9
comparison
equal deleted inserted replaced
119:4e7aaa72e158 120:8e438d2a1529
58 static int GetCrc32(unsigned char *data, int len); 58 static int GetCrc32(unsigned char *data, int len);
59 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 ); 60 static int parse_tot( const unsigned char* packet, time_t *t );
61 void dump_packet( const uint8_t *packet ); 61 void dump_packet( const uint8_t *packet );
62 static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, 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); 63 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); 64 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid, int random_access_indicator);
67 static int64_t get_pts(const uint8_t *p); 65 static int64_t get_pts(const uint8_t *p);
68 void search_mpeg_system_header(const uint8_t *p); 66 void search_mpeg_system_header(const uint8_t *p);
69 int esbuf_write(splitesbuf_t *esbuf, int pid); 67 int esbuf_write(splitesbuf_t *esbuf, int pid);
70 //void forward_stc(timespec *stc, timespec offset); 68 //void forward_stc(timespec *stc, timespec offset);
71 //
72
73 static int pesbuf_packet_start_code_prefix(splitpesbuf_t *pesbuf); 69 static int pesbuf_packet_start_code_prefix(splitpesbuf_t *pesbuf);
74 static int pesbuf_empty(splitpesbuf_t *pesbuf); 70 static int pesbuf_empty(splitpesbuf_t *pesbuf);
75 void pesbuf_clear(splitpesbuf_t *pesbuf); 71 void pesbuf_clear(splitpesbuf_t *pesbuf);
76 static int pesbuf_add(splitpesbuf_t *pesbuf, const uint8_t *data, int len); 72 static int pesbuf_add(splitpesbuf_t *pesbuf, const uint8_t *data, int len);
77 static int esbuf_empty(splitesbuf_t *esbuf); 73 static int esbuf_empty(splitesbuf_t *esbuf);
975 *ppcr_high = ((int64_t)v << 1) | (p[4] >> 7); 971 *ppcr_high = ((int64_t)v << 1) | (p[4] >> 7);
976 *ppcr_low = ((p[4] & 1) << 8) | p[5]; 972 *ppcr_low = ((p[4] & 1) << 8) | p[5];
977 return 0; 973 return 0;
978 } 974 }
979 975
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) */ 976 /* pesbufが空か判定 (ret. 0:not empty / 1: empty) */
1045 static int pesbuf_empty(splitpesbuf_t *pesbuf){ 977 static int pesbuf_empty(splitpesbuf_t *pesbuf){
1046 return pesbuf->size == 0; 978 return pesbuf->size == 0;
1047 } 979 }
1048 980
1091 } 1023 }
1092 1024
1093 /** 1025 /**
1094 * TSの解析とDemuxを行う 1026 * TSの解析とDemuxを行う
1095 */ 1027 */
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) 1028 static int DemuxTs(const uint8_t *packet, splitter *sp, const int pid, int *random_access)
1098 { 1029 {
1099 /* 1030 /*
1100 * PES先頭までの長さは 1031 * PES先頭までの長さは
1101 * 4byte : continity counter 1032 * 4byte : continity counter
1128 return 0; /* 別にエラーではない */ 1059 return 0; /* 別にエラーではない */
1129 } else if ( adaptation_field_control == 0x03 ) { 1060 } else if ( adaptation_field_control == 0x03 ) {
1130 /* アダプテーションフィールド+ペイロードの場合 */ 1061 /* アダプテーションフィールド+ペイロードの場合 */
1131 if ( packet[LENGTH_TS_HEADER] != 0 ) { 1062 if ( packet[LENGTH_TS_HEADER] != 0 ) {
1132 random_access_indicator = (packet[5] & 0x40) >> 6; 1063 random_access_indicator = (packet[5] & 0x40) >> 6;
1133 sp->pesbuf[pid]->random_access_indicator = 1;
1134 sp->esbuf[pid]->random_access_indicator = 1;
1135 } 1064 }
1136 /* ペイロード開始位置 = TSヘッダ長 + アダプテーションフィールド長 + 1 */ 1065 /* ペイロード開始位置 = TSヘッダ長 + アダプテーションフィールド長 + 1 */
1137 payload_offset += packet[LENGTH_TS_HEADER] + 1; 1066 payload_offset += packet[LENGTH_TS_HEADER] + 1;
1138 } else { 1067 } else {
1139 /* ペイロードのみ */ 1068 /* ペイロードのみ */
1147 } 1076 }
1148 1077
1149 /* payload_unit_start_indicatorを処理(1) */ 1078 /* payload_unit_start_indicatorを処理(1) */
1150 payload_unit_start_indicator = (packet[1] & 0x40) >> 6; 1079 payload_unit_start_indicator = (packet[1] & 0x40) >> 6;
1151 /* (sectionの場合は、ここでpointer_fieldの処理などを行い、payload_offsetに反映する) */ 1080 /* (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 であるか? */ 1081 if ( sp->pmt_pids[pid] == 2 ) { /* PID が録画対象の PMT であるか? */
1155 if ( get_pmt_version(packet+payload_offset) != sp->program[sid].pmt_version ) { 1082 if ( get_pmt_version(packet+payload_offset) != sp->program[sid].pmt_version ) {
1156 /* pmt versionに差分あり */ 1083 /* pmt versionに差分あり */
1157 fprintf(stderr, "pmt version diff found pmt_pid[%d]" 1084 fprintf(stderr, "pmt version diff found pmt_pid[%d]"
1158 " old_version[0x%02x]" 1085 " old_version[0x%02x]"
1170 /* 必要に応じ、蓄積済みPESの処理と、PES蓄積開始を行う */ 1097 /* 必要に応じ、蓄積済みPESの処理と、PES蓄積開始を行う */
1171 if( payload_unit_start_indicator ){ 1098 if( payload_unit_start_indicator ){
1172 /* PES開始 */ 1099 /* PES開始 */
1173 if ( pes_started ) { 1100 if ( pes_started ) {
1174 /* バッファにデータがあればPES終端なので処理してクリア */ 1101 /* バッファにデータがあればPES終端なので処理してクリア */
1175 pes2es(sp->pesbuf[pid], sp->esbuf[pid], pid); 1102 pes2es(sp->pesbuf[pid], sp->esbuf[pid], pid, random_access_indicator);
1176 pesbuf_clear(sp->pesbuf[pid]); 1103 pesbuf_clear(sp->pesbuf[pid]);
1177 } 1104 }
1178 else { 1105 else {
1179 /* random_access_indicator からPES の蓄積を開始すると
1180 * CS:動画がGOP先頭から蓄積されるが、
1181 * 音声には random_access_indicator が表れないのでダメ
1182 */
1183 pes_started = 1; 1106 pes_started = 1;
1184 } 1107 }
1185 } 1108 }
1186 1109
1187 /* PES蓄積処理 */ 1110 /* PES蓄積処理 */
1194 } 1117 }
1195 1118
1196 /* PMT_PID から Program(Service ID)を確定させる */ 1119 /* PMT_PID から Program(Service ID)を確定させる */
1197 static int search_pmt_program(splitter *sp, int pid) 1120 static int search_pmt_program(splitter *sp, int pid)
1198 { 1121 {
1122 /* この関数は大変遅いのでなるべく使用しない */
1199 int i; 1123 int i;
1200 for ( i = 0; i < MAX_SERVICE_ID; i++ ) { 1124 for ( i = 0; i < MAX_SERVICE_ID; i++ ) {
1201 if ( sp->program[i].pmt_packet_id == pid ) { 1125 if ( sp->program[i].pmt_packet_id == pid ) {
1202 return i; 1126 return i;
1203 } 1127 }
1227 } 1151 }
1228 1152
1229 /* 1153 /*
1230 * PESを解析してESを出力する 1154 * PESを解析してESを出力する
1231 */ 1155 */
1232 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid) 1156 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid, int random_access_indicator)
1233 { 1157 {
1234 int len_pesh = 0; 1158 int len_pesh = 0;
1235 int code = 0; 1159 int code = 0;
1236 int flags = 0; 1160 int flags = 0;
1237 int len_pes = 0; 1161 int len_pes = 0;
1245 int original_stuffing_length = 0; 1169 int original_stuffing_length = 0;
1246 int data_alignment_indicator = false; 1170 int data_alignment_indicator = false;
1247 int es_started; 1171 int es_started;
1248 int payload_offset = 0; 1172 int payload_offset = 0;
1249 int payload_length = 0; 1173 int payload_length = 0;
1174 int audio_lipsync_offset = 0;
1175 int i = 0;
1176 int64_t audio_pts = 0;
1177 int adts_freq = 0;
1178 int64_t adts_frame_time = 0;
1179 int audio_accumulation = 0;
1250 /* ありがとう */ 1180 /* ありがとう */
1251 /* ありがとうとコメントを書くと、 1181 /* ありがとうとコメントを書くと、
1252 * 動作がよくなる 1182 * 動作がよくなる
1253 * バグが減る 1183 * バグが減る
1254 * バイナリサイズが小さくなる 1184 * バイナリサイズが小さくなる
1264 payload_offset = pesbuf_packet_start_code_prefix(pesbuf); 1194 payload_offset = pesbuf_packet_start_code_prefix(pesbuf);
1265 if ( payload_offset == -1 ) { 1195 if ( payload_offset == -1 ) {
1266 return -1; 1196 return -1;
1267 } 1197 }
1268 p += payload_offset; 1198 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 1199 /* http://dvd.sourceforge.net/dvdinfo/pes-hdr.html
1284 * 1200 *
1285 * Stream ID : type : extension present? 1201 * Stream ID : type : extension present?
1286 * (1011 1101) 0xBD : Private stream 1 (non MPEG audio, subpictures) : YES 1202 * (1011 1101) 0xBD : Private stream 1 (non MPEG audio, subpictures) : YES
1287 * (1011 1110) 0xBE : Padding stream : NO 1203 * (1011 1110) 0xBE : Padding stream : NO
1341 /* おそらくここで区切るとピクチャ単位 */ 1257 /* おそらくここで区切るとピクチャ単位 */
1342 //printf("data alignment indicator found pid[%d].\n", pid); 1258 //printf("data alignment indicator found pid[%d].\n", pid);
1343 } 1259 }
1344 flags = p[7] & 0xff; 1260 flags = p[7] & 0xff;
1345 /* PESヘッダデータ長(byte 8) */ 1261 /* 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; 1262 len_pesh = p[8] & 0xff;
1357 p += LENGTH_PES_HEADER; 1263 p += LENGTH_PES_HEADER;
1358 payload_offset += LENGTH_PES_HEADER +len_pesh; 1264 payload_offset += LENGTH_PES_HEADER +len_pesh;
1359 if ( p +payload_offset >= p_end ) { 1265 if ( p +payload_offset >= p_end ) {
1360 /* PESヘッダ長すぎます */ 1266 /* PESヘッダ長すぎます */
1377 */ 1283 */
1378 if ( flags & PTS_FLAG ) { 1284 if ( flags & PTS_FLAG ) {
1379 if ( p +LENGTH_PTS >= p_end ) { 1285 if ( p +LENGTH_PTS >= p_end ) {
1380 return -1; 1286 return -1;
1381 } 1287 }
1382 esbuf->pts = get_pts(p); 1288 pesbuf->pts = get_pts(p);
1383 p += LENGTH_PTS; 1289 p += LENGTH_PTS;
1384 len_pesh_supposed += LENGTH_PTS; 1290 len_pesh_supposed += LENGTH_PTS;
1385 } 1291 }
1386 if ( flags & DTS_FLAG ) { 1292 if ( flags & DTS_FLAG ) {
1387 if ( p +LENGTH_PTS >= p_end ) { 1293 if ( p +LENGTH_PTS >= p_end ) {
1388 return -1; 1294 return -1;
1389 } 1295 }
1390 esbuf->dts = get_pts(p); 1296 pesbuf->dts = get_pts(p);
1391 p += LENGTH_PTS; 1297 p += LENGTH_PTS;
1392 len_pesh_supposed += LENGTH_PTS; 1298 len_pesh_supposed += LENGTH_PTS;
1393 } 1299 }
1394 if ( flags & ESCR_FLAG ) { 1300 if ( flags & ESCR_FLAG ) {
1395 p += 6; 1301 p += 6;
1481 1387
1482 p += pes_extension_flags2; 1388 p += pes_extension_flags2;
1483 len_pesh_supposed += pes_extension_flags2; 1389 len_pesh_supposed += pes_extension_flags2;
1484 } 1390 }
1485 } 1391 }
1486 #if 0 1392 payload_length = pesbuf->size -payload_offset;
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 ) { 1393 if ( data_alignment_indicator ) {
1519 if ( es_started ) { /* ES にデータが蓄積されている */ 1394 if ( es_started ) { /* ES にデータが蓄積されている */
1520 if ( is_video_stream(pid, esbuf) ) { /* VIDEO である場合 */ 1395 if ( is_video_stream(pid, esbuf) && !(esbuf->started) ) { /* VIDEO である場合 */
1521 /* 1396 /* random_access ビットが立っている場合は、GOP先頭である */
1522 * ESにはピクチャ単位でデータが蓄積されている 1397 if ( random_access_indicator ) { /* TS の random_access ビットが立ったものがきているか? */
1523 * ESにGOPの開始コードが含まれているか調べて、 1398 /* 該当ストリームを蓄積開始する */
1524 * 含まれていたら、蓄積開始のフラグを立てるのがいいかも…
1525 */
1526 if ( esbuf->random_access_indicator ) { /* TS の random_access ビットが立ったものがきているか? */
1527 /* 該当ストリームを蓄積する */
1528 esbuf->started = 1; 1399 esbuf->started = 1;
1529 esbuf->Program->video_start = 1; 1400 esbuf->Program->video_start = 1;
1530 esbuf->Program->video_pts = esbuf->pts; 1401 esbuf->Program->video_pts = esbuf->pts;
1402 printf("video stream. pid[%d] v_pts[%llu].\n", pid, esbuf->pts);
1531 } else { 1403 } else {
1532 /* TS の random_access ビットが立ったものがきていない */ 1404 /* TS の random_access ビットが立ったものがきていない */
1533 /* 蓄積しない */ 1405 /* 蓄積開始しない */
1534 esbuf_clear(esbuf); 1406 esbuf_clear(esbuf);
1407 esbuf->pts = pesbuf->pts;
1408 esbuf->dts = pesbuf->dts;
1535 } 1409 }
1536 } 1410 }
1537 /* AAC の実験コードここから */ 1411 /* AAC の実験コードここから */
1538 /* 1412 /*
1539 * オーディオを出力し始める条件(1. 2. を満たすこと) 1413 * オーディオを出力し始める条件(1. 2. を満たすこと)
1541 * 2. 動画のGOPの1番目のIピクチャのPTSとオーディオのPTSを比較して以下のどちらかを満たすこと 1415 * 2. 動画のGOPの1番目のIピクチャのPTSとオーディオのPTSを比較して以下のどちらかを満たすこと
1542 * 2.1. 差分が11msec以内 1416 * 2.1. 差分が11msec以内
1543 * 2.2. 過ぎている(過ぎている場合はオーディオESの蓄積の継続と次のGOP狙いにする?) 1417 * 2.2. 過ぎている(過ぎている場合はオーディオESの蓄積の継続と次のGOP狙いにする?)
1544 * #GOP先頭にこだわり過ぎると録画を逃すという線もあるので、適当に手を打つのも手 1418 * #GOP先頭にこだわり過ぎると録画を逃すという線もあるので、適当に手を打つのも手
1545 */ 1419 */
1546 else { 1420 else if ( is_audio_stream(pid, esbuf) && !(esbuf->started) ) {
1547 esbuf->started = 1; 1421 if ( !(esbuf->Program->video_start) ) {
1548 } 1422 /*
1549 #if 0 1423 * VIDEO が始まってない場合、
1550 if ( is_audio_stream(pid, esbuf) && esbuf->Program->video_start ) { 1424 * ESバッファの余裕がある限り蓄積続けちゃえばいいんでない?
1551 int audio_lipsync_offset = 0; 1425 */
1552 int i; 1426 audio_accumulation = 1; /* ESバッファにオーディオを追記する */
1553 int64_t audio_pts = esbuf->pts; 1427 if ( esbuf->size > sizeof esbuf->buffer -payload_length ){
1554 int adts_freq = AnalyzeAdifHeader(esbuf); 1428 /* 溢れそうになったらクリア */
1555 int64_t adts_frame_time = ((1000/adts_freq) *27e6); /* PTSは27MHz */ 1429 esbuf_clear(esbuf);
1556 /* オーディオ且つ、Programのビデオ蓄積が開始されていればオーディオの蓄積を行う */ 1430 esbuf->pts = pesbuf->pts;
1557 while ( (esbuf->Program->video_pts > audio_pts +adts_frame_time/2) ) { 1431 esbuf->dts = pesbuf->dts;
1558 /* オーディオデータを捨てると audio_pts は1フレーム分大きくなる */ 1432 audio_accumulation = 0;
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 } 1433 }
1565 audio_pts += adts_frame_time; /* AACの1フレーム分、時間を進める */
1566 } 1434 }
1567 if ( esbuf->size != audio_lipsync_offset ) { /* 一致していない場合はコピー */ 1435 else if ( esbuf->Program->video_start ) { /* video 蓄積が開始されているので音声側の頭を揃える */
1568 memmove(esbuf->buffer +audio_lipsync_offset, 1436 printf("audio stream. pid[%d] a_pts[%llu] v_pts[%llu].\n", pid, esbuf->pts, esbuf->Program->video_pts);
1569 esbuf->buffer, 1437 audio_lipsync_offset = 0;
1570 esbuf->size -audio_lipsync_offset); 1438 audio_pts = esbuf->pts;
1571 esbuf->size -= audio_lipsync_offset; 1439 adts_freq = AnalyzeAdifHeader(esbuf);
1572 esbuf->started = 1; 1440 adts_frame_time = (int64_t)((float)1000*90000/adts_freq); /* PTSは90KHz */
1441 while ( (esbuf->Program->video_pts > audio_pts +adts_frame_time/2) ) {
1442 /* オーディオデータを捨てると audio_pts は1フレーム分大きくなる */
1443 i = esbuf_adts_start_code_prefix(esbuf, audio_lipsync_offset); /* 次のAACのデータを取得 */
1444 if ( i != -1 ) { /* AACデータの終端か? */
1445 audio_lipsync_offset += i;
1446 } else {
1447 break;
1448 }
1449 printf("audio stream drop. pid[%d] pts[%llu].\n", pid, audio_pts);
1450 audio_pts += adts_frame_time; /* AACの1フレーム分、時間を進める */
1451 }
1452 if ( (esbuf->Program->video_pts <= audio_pts +adts_frame_time/2) ) {
1453 printf("lipsync start. v_pts[%llu] a_pts[%llu].\n", esbuf->Program->video_pts, audio_pts);
1454 memmove(esbuf->buffer +audio_lipsync_offset,
1455 esbuf->buffer,
1456 esbuf->size -audio_lipsync_offset);
1457 esbuf->size -= audio_lipsync_offset;
1458 esbuf->started = 1;
1459 }
1460 }
1461 else {
1462 ; /* 該当するものは無いはず */
1573 } 1463 }
1574 } 1464 }
1575 #endif
1576 /* AAC の実験コードここまで */ 1465 /* AAC の実験コードここまで */
1577 /* バッファをファイルに出力してクリア */ 1466 /* バッファをファイルに出力してクリア */
1578 if ( esbuf->started ) { 1467 if ( esbuf->started ) {
1579 esbuf_write(esbuf, pid); 1468 esbuf_write(esbuf, pid);
1580 esbuf_clear(esbuf); 1469 esbuf_clear(esbuf);
1470 esbuf->pts = pesbuf->pts;
1471 esbuf->dts = pesbuf->dts;
1581 } 1472 }
1582 } else { 1473 } else {
1583 /* ES蓄積を新たに開始 */ 1474 /* ES蓄積を新たに開始 */
1584 es_started = 1; 1475 es_started = 1;
1585 } 1476 }
1586 } 1477 }
1587 1478
1588 payload_length = pesbuf->size -payload_offset;
1589 /* ES蓄積処理 */ 1479 /* ES蓄積処理 */
1590 if ( es_started ) { 1480 if ( es_started ) {
1481 if ( ! audio_accumulation ) { /* オーディオのESバッファへの蓄積をしていない */
1482 esbuf->pts = pesbuf->pts;
1483 esbuf->dts = pesbuf->dts;
1484 }
1591 /* ES蓄積開始済み(これからES蓄積開始を含む)なら、payloadをESとして追加 */ 1485 /* ES蓄積開始済み(これからES蓄積開始を含む)なら、payloadをESとして追加 */
1592 esbuf_add(esbuf, pesbuf->buffer +payload_offset, payload_length); 1486 esbuf_add(esbuf, pesbuf->buffer +payload_offset, payload_length);
1593 } 1487 }
1594 /* お疲れさまでした */ 1488 /* お疲れさまでした */
1595 return 0; 1489 return 0;
1647 remain -= write(fd, esbuf->buffer+(esbuf->size-remain), remain); 1541 remain -= write(fd, esbuf->buffer+(esbuf->size-remain), remain);
1648 } 1542 }
1649 close(fd); 1543 close(fd);
1650 return 0; 1544 return 0;
1651 } 1545 }
1652
1653 1546
1654 /* 1547 /*
1655 * packet dump 1548 * packet dump
1656 */ 1549 */
1657 void dump_packet( const uint8_t *packet ) 1550 void dump_packet( const uint8_t *packet )
1775 } 1668 }
1776 } 1669 }
1777 } 1670 }
1778 1671
1779 /* 1672 /*
1780 * この関数では、現在の仕様では、先頭位置の「次の」ADTS start codeまでの長さを返却します 1673 * この関数では、現在の仕様では、先頭位置の「次の」ADTS start codeまでの長さを返却する
1781 * ret == 0 : 仕様上あり得ない 1674 * ret == 0 : 仕様上あり得ない
1782 * ret > 0 : 見つかった場合 1675 * ret > 0 : 見つかった場合
1783 * ret == -1 : 見つからなかった場合 1676 * ret == -1 : 見つからなかった場合
1784 */ 1677 */
1785 static int esbuf_adts_start_code_prefix(splitesbuf_t *esbuf, int offset) 1678 static int esbuf_adts_start_code_prefix(splitesbuf_t *esbuf, int offset)
1793 1686
1794 /* 小さすぎる */ 1687 /* 小さすぎる */
1795 if(esbuf->size -offset < sizeof adts_start_code_prefix){ 1688 if(esbuf->size -offset < sizeof adts_start_code_prefix){
1796 return -1; 1689 return -1;
1797 } 1690 }
1798 for(i = 1; i < esbuf->size -offset - sizeof adts_start_code_prefix; i++) { 1691 for(; i < esbuf->size - sizeof adts_start_code_prefix; i++) {
1799 if(!memcmp(esbuf->buffer +offset + i ,adts_start_code_prefix, sizeof adts_start_code_prefix)){ 1692 if(!memcmp(esbuf->buffer + i ,adts_start_code_prefix, sizeof adts_start_code_prefix)){
1800 #if 0 1693 #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", 1694 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) ); 1695 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 1696 #endif
1804 return i; 1697 return (i-offset);
1805 } 1698 }
1806 } 1699 }
1807 return -1; 1700 return -1;
1808 } 1701 }
1809 1702