changeset 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
files recpt1/recpt1.c recpt1/tssplitter_lite.c recpt1/tssplitter_lite.h
diffstat 3 files changed, 99 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/recpt1/recpt1.c	Sun Apr 25 18:26:32 2010 +0900
+++ b/recpt1/recpt1.c	Thu Apr 29 02:02:42 2010 +0900
@@ -336,8 +336,8 @@
         if(use_b25) {
             code = b25_decode(dec, &sbuf, &dbuf);
             if(code < 0) {
-                fprintf(stderr, "b25_decode failed (code=%d). fall back to encrypted recording.\n", code);
-                use_b25 = FALSE;
+                fprintf(stderr, "b25_decode failed. fall back to encrypted recording.\n");
+                use_b25 = FALSE; /* local flag */
             }
             else
                 buf = dbuf;
@@ -361,12 +361,6 @@
                         /* $BJ,N%BP>](BPID$B$,40A4$KCj=P$G$-$k$^$G=PNO$7$J$$(B
                          * 1$BICDxEYM>M5$r8+$k$H$$$$$+$b(B
                          */
-                        time_t cur_time;
-                        time(&cur_time);
-                        if(cur_time - data->start_time > 4) {
-                            use_splitter = FALSE;
-                            goto fin;
-                        }
                         break;
                     }
                 }
@@ -486,9 +480,9 @@
 show_usage(char *cmd)
 {
 #ifdef HAVE_LIBARIB25
-    fprintf(stderr, "Usage: \n%s [--b25 [--round N] [--strip] [--EMM]] [--udp [--addr hostname --port portnumber]] [--device devicefile] [--lnb voltage] [--sid SID1,SID2] channel rectime destfile\n", cmd);
+    fprintf(stderr, "Usage: \n%s [--b25 [--round N] [--strip] [--EMM]] [--udp [--addr hostname --port portnumber]] [--device devicefile] [--lnb voltage] [--sid SID1,SID2] channel [--es filename_suffix] rectime destfile\n", cmd);
 #else
-    fprintf(stderr, "Usage: \n%s [--strip] [--EMM]] [--udp [--addr hostname --port portnumber]] [--device devicefile] [--lnb voltage] [--sid SID1,SID2] channel rectime destfile\n", cmd);
+    fprintf(stderr, "Usage: \n%s [--strip] [--EMM]] [--udp [--addr hostname --port portnumber]] [--device devicefile] [--lnb voltage] [--sid SID1,SID2] [--es filename_suffix] channel rectime destfile\n", cmd);
 #endif
     fprintf(stderr, "\n");
     fprintf(stderr, "Remarks:\n");
@@ -512,6 +506,7 @@
     fprintf(stderr, "--device devicefile: Specify devicefile to use\n");
     fprintf(stderr, "--lnb voltage:       Specify LNB voltage (0, 11, 15)\n");
     fprintf(stderr, "--sid SID1,SID2,...: Specify SID number in CSV format (101,102,...)\n");
+    fprintf(stderr, "  --es filename:     Specify ES out filename prefix\n");
     fprintf(stderr, "--help:              Show this help\n");
     fprintf(stderr, "--version:           Show version\n");
     fprintf(stderr, "--list:              Show channel list\n");
@@ -898,6 +893,9 @@
         { "version",   0, NULL, 'v'},
         { "list",      0, NULL, 'l'},
         { "sid",       1, NULL, 'i'},
+        { "SID",       1, NULL, 'i'},
+        { "es",       1, NULL, 'e'},
+        { "ES",       1, NULL, 'e'},
         {0, 0, NULL, 0} /* terminate */
     };
 
@@ -913,6 +911,7 @@
     int val;
     char *voltage[] = {"0V", "11V", "15V"};
     char *sid_list = NULL;
+    char *es_name_prefix = NULL;
 
     while((result = getopt_long(argc, argv, "br:smn:ua:p:d:hvli:",
                                 long_options, &option_index)) != -1) {
@@ -990,6 +989,9 @@
             use_splitter = TRUE;
             sid_list = optarg;
             break;
+        case 'e':
+            es_name_prefix = optarg;
+            break;
         }
     }
 
@@ -1047,13 +1049,15 @@
         if(!dec) {
             fprintf(stderr, "Cannot start b25 decoder\n");
             fprintf(stderr, "Fall back to encrypted recording\n");
-            use_b25 = FALSE;
+            use_b25 = 0;
         }
     }
     /* initialize splitter */
-    if(use_splitter) {
-        splitter = split_startup(sid_list);
-        if(splitter->sid_list == NULL) {
+    if(use_splitter)
+    {
+        splitter = split_startup(sid_list, es_name_prefix);
+        if ( splitter->sid_list == NULL )
+        {
             fprintf(stderr, "Cannot start TS splitter\n");
             return 1;
         }
--- 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;
+}
--- a/recpt1/tssplitter_lite.h	Sun Apr 25 18:26:32 2010 +0900
+++ b/recpt1/tssplitter_lite.h	Thu Apr 29 02:02:42 2010 +0900
@@ -23,6 +23,7 @@
 #define __STDC_FORMAT_MACROS
 #include <inttypes.h>
 #include <unistd.h>
+#include <limits.h>
 
 #define LENGTH_PACKET		(188)
 #define MAX_PID				(8192)
@@ -36,6 +37,7 @@
 #define TSS_NULL			(-2)
 #define LENGTH_PAT_HEADER	(12)
 #define C_CHAR_COMMA		','
+#define C_CHAR_DOT			'.'
 #define LENGTH_TS_HEADER (4)
 #define LENGTH_PES_HEADER (9)
 #define LENGTH_PTS (5)
@@ -158,6 +160,7 @@
 	int64_t dts;
 	int started; /* 該当ESが蓄積開始しているか */
 	int random_access_indicator; /* TS の random_access_indicator */
+	int fd; /* 該当ESのfd */
     int size;
     u_char buffer[3*1024*1024];
 } splitesbuf_t;
@@ -184,6 +187,8 @@
 	splitesbuf_t *esbuf[MAX_PID];
 	program_t *program;
 	int pid_sid_table[MAX_PID]; /* pid to sid の変換を行うためのテーブル */
+	char *filename; /* ファイル名を上位からもらってくるためのポインタ */
+	int esout; /* ES出力する? */
 } splitter;
 
 /* b25 decoder would hoard up large chank */
@@ -193,7 +198,7 @@
     u_char buffer[1024*1024];
 } splitbuf_t;
 
-splitter* split_startup(char *sid);
+splitter* split_startup(char *sid, char *filename);
 int split_select(splitter *sp, ARIB_STD_B25_BUFFER *sbuf);
 void split_shutdown(splitter *sp);
 int split_ts(splitter *splitter, ARIB_STD_B25_BUFFER *sbuf, splitbuf_t *dbuf);