diff recpt1/tssplitter_lite.c @ 121:e915d31c5bd9

add --es option
author Naoya OYAMA <naoya.oyama@gmail.com>
date Thu, 29 Apr 2010 02:02:42 +0900
parents 8e438d2a1529
children 4009737ea899
line wrap: on
line diff
--- a/recpt1/tssplitter_lite.c	Sun Apr 25 18:26:32 2010 +0900
+++ b/recpt1/tssplitter_lite.c	Thu Apr 29 02:02:42 2010 +0900
@@ -47,7 +47,7 @@
 #ifndef AV_RB16
 #define AV_RB16(x)  ((((const uint8_t*)(x))[0] << 8) | ((const uint8_t*)(x))[1])
 #endif
-
+#define MAX_SERVICE_ID ( 0xffff )
 
 /* prototypes */
 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf);
@@ -64,7 +64,7 @@
 static int pes2es(splitpesbuf_t *pesbuf, splitesbuf_t *esbuf, const int pid, int random_access_indicator);
 static int64_t get_pts(const uint8_t *p);
 void search_mpeg_system_header(const uint8_t *p);
-int esbuf_write(splitesbuf_t *esbuf, int pid);
+int esbuf_write(splitesbuf_t *esbuf);
 //void forward_stc(timespec *stc, timespec offset);
 static int pesbuf_packet_start_code_prefix(splitpesbuf_t *pesbuf);
 static int pesbuf_empty(splitpesbuf_t *pesbuf);
@@ -94,6 +94,8 @@
 static int get_adts_no_raw_data_blocks_in_frame(uint8_t *p);
 static int search_pmt_program(splitter *sp, int pid);
 static int search_gop_start_code(splitesbuf_t *esbuf);
+//static int creat_filename(char *base, char *filename, int sid, int epid, int av_flag ,splitesbuf_t *esbuf);
+static int creat_filename(splitter *sp, int sid, int pid, int av_flag);
 
 /**
  * サービスID解析
@@ -193,7 +195,8 @@
  * 初期化処理
  */
 splitter* split_startup(
-	char *sid		// [in]		サービスID(引数で指定した文字列)
+	char *sid,		// [in]		サービスID(引数で指定した文字列)
+	char *filename	// [in]		出力ESファイル名(引数で指定したファイル名)
 )
 {
 	splitter* sp;
@@ -204,7 +207,6 @@
 		fprintf(stderr, "split_startup malloc error.\n");
 		return NULL;
 	}
-#define MAX_SERVICE_ID ( 0xffff )
 	sp->program = malloc( sizeof(program_t) * MAX_SERVICE_ID );
 	if ( sp->program == NULL )
 	{
@@ -240,7 +242,11 @@
 		sp->program[i].pmt_version = -1;
 	}
 	memset(sp->pid_sid_table, 0, sizeof(int)*MAX_PID);
-
+//	sp->filename = filename;
+	if ( filename != NULL ) {
+		sp->esout = 1;
+		sp->filename = filename;
+	}
 	return sp;
 }
 
@@ -859,7 +865,7 @@
 				/* 13818-3 Audio or 13818-7 Audio with ADTS transport syntax */
 				sp->program[sid].audio[sp->program[sid].audio_nb] = epid;
 				sp->program[sid].audio_nb += 1;
-				av_flag = 1;
+				av_flag = 2;
 			} else {
 				; /* A/V どちらでもないものはとりあえずスルー */
 			}
@@ -873,6 +879,8 @@
 					}
 					sp->esbuf[epid]->size = 0;
 					sp->esbuf[epid]->Program = &(sp->program[sid]);
+//					creat_filename(sp->filename, sp->esbuf[epid]->filename, sid, epid, av_flag, &(sp->esbuf[epid]));
+					creat_filename(sp, sid, epid, av_flag);
 				}
 				/* PESバッファはNULLか? */
 				if ( sp->pesbuf[epid] == NULL ) {
@@ -1417,7 +1425,7 @@
 			 *    2.2. 過ぎている(過ぎている場合はオーディオESの蓄積の継続と次のGOP狙いにする?)
 			 *    #GOP先頭にこだわり過ぎると録画を逃すという線もあるので、適当に手を打つのも手
 			 */
-			else if ( is_audio_stream(pid, esbuf) && !(esbuf->started) ) {
+			else if ( (is_audio_stream(pid, esbuf) != -1 ) && !(esbuf->started) ) {
 				if ( !(esbuf->Program->video_start) ) {
 					/*
 					 * VIDEO が始まってない場合、
@@ -1465,7 +1473,7 @@
 			/* AAC の実験コードここまで */
 			/* バッファをファイルに出力してクリア */
 			if ( esbuf->started ) {
-				esbuf_write(esbuf, pid);
+				esbuf_write(esbuf);
 				esbuf_clear(esbuf);
 				esbuf->pts = pesbuf->pts;
 				esbuf->dts = pesbuf->dts;
@@ -1526,21 +1534,21 @@
 /*
  * ESをファイル出力する
  */
-int esbuf_write(splitesbuf_t *esbuf, int pid)
+//int esbuf_write(splitesbuf_t *esbuf, int pid)
+int esbuf_write(splitesbuf_t *esbuf)
 {
-	int fd;
 	int remain = esbuf->size;
-#define ES_FILE "/tmp/es.%d"
-	char filename[1024];
-	filename[0] = '\0';
-	umask(0133);
-	snprintf(filename, sizeof(filename), ES_FILE, pid);
-	fd = open(filename, O_CREAT|O_APPEND|O_RDWR, 00644);
+//#define ES_FILE "/tmp/es.%d"
+//	char filename[1024];
+//	filename[0] = '\0';
+//	umask(0133);
+//	snprintf(filename, sizeof(filename), ES_FILE, pid);
+//	fd = open(filename, O_CREAT|O_APPEND|O_RDWR, 00644);
 	while(remain > 0)
 	{
-		remain -= write(fd, esbuf->buffer+(esbuf->size-remain), remain);
+		remain -= write(esbuf->fd, esbuf->buffer+(esbuf->size-remain), remain);
 	}
-	close(fd);
+//	close(fd);
 	return 0;
 }
 
@@ -1856,3 +1864,52 @@
 	}
 	return -1;
 }
+
+/* ES 出力するファイル名を決定する */
+//static int creat_filename(char *base, char *filename, int sid, int pid, int av_flag ,splitesbuf_t *esbuf)
+static int creat_filename(splitter *sp, int sid, int pid, int av_flag)
+{
+	/*
+	 * 出力ESファイルの命名規則は以下とする
+	 *
+	 * ファイル名のベースは出力TSファイル名
+	 * 出力先パスも出力TSファイル名から取得
+	 * ファイル名のうち、「.ts」を削除して、sidとepidをつけて、「.es」とする
+	 * .m2v とか .m2a とかそういう名前って好きではないのだけど...ISOに既定ないし
+	 * オーディオなのか、ビデオなのかって情報はあるけど
+	 */
+
+	char filename[PATH_MAX];
+	int size = 0;
+	char *suffix = NULL;
+	int av_nb = 0;
+	char suffix_a[] = "aac";
+	char suffix_v[] = "m2v";
+	filename[0] = '\0';
+
+	if ( av_flag == 1 ) {
+		suffix = suffix_v;
+		av_nb = sp->program[sid].video_nb -1;
+	} else if ( av_flag == 2 ){
+		suffix = suffix_a;
+		av_nb = sp->program[sid].audio_nb -1;
+	} else {
+		/* ここはありえない */
+		return -1;
+	}
+	size = strlen(sp->filename);
+
+	if ( size +16 < sizeof(filename) ) {
+		snprintf(filename, sizeof(filename), "%s_%04d_%02d.%s", sp->filename, sid, av_nb, suffix);
+		filename[PATH_MAX-1] = '\0';
+	} else {
+		/* ファイル名つけられなくて困るでござるの巻 */
+		return -1;
+	}
+	umask(0133);
+	if ( !(sp->esbuf[pid]->fd = open(filename, O_CREAT|O_APPEND|O_RDWR, 00644)) ) {
+		fprintf("cannot open es out file. file[%s].\n", filename);
+		return -1;
+	}
+	return 0;
+}