# HG changeset patch # User Naoya OYAMA # Date 1272474162 -32400 # Node ID e915d31c5bd967a75b6c0a86486b92869f4eaa8d # Parent 8e438d2a1529d3cdfab7d1f432f008f0fcbe3b0b add --es option diff -r 8e438d2a1529 -r e915d31c5bd9 recpt1/recpt1.c --- 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; } diff -r 8e438d2a1529 -r e915d31c5bd9 recpt1/tssplitter_lite.c --- 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; +} diff -r 8e438d2a1529 -r e915d31c5bd9 recpt1/tssplitter_lite.h --- 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 #include +#include #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);