comparison recpt1/recpt1.c @ 2:8ac7c59fefc9

added b25 decode functionality
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 16 Feb 2009 21:40:16 +0900
parents 29f3b2bbbd67
children 6801fe7e04ff
comparison
equal deleted inserted replaced
1:29f3b2bbbd67 2:8ac7c59fefc9
9 #include <unistd.h> 9 #include <unistd.h>
10 10
11 #include <sys/ioctl.h> 11 #include <sys/ioctl.h>
12 #include "pt1_ioctl.h" 12 #include "pt1_ioctl.h"
13 13
14 #include "recpt1.h" 14 #include "recpt1.h"
15 #include "decoder.h"
16
17 /* globals */
18 int wfd; // ファイル書き込み用
19 int f_exit = FALSE ;
20 decoder *dec;
15 21
16 22
17 // 周波数テーブル変換 23 // 周波数テーブル変換
18 ISDB_T_FREQ_CONV_TABLE *searchrecoff(char *channel) 24 ISDB_T_FREQ_CONV_TABLE *
19 { 25 searchrecoff(char *channel)
20 int lp ; 26 {
21 27 int lp ;
22 for(lp = 0 ; lp < 113 ; lp++){ 28
23 // 文字列&長さ一致したら周波数テーブル番号を返却する 29 for(lp = 0 ; lp < 113 ; lp++){
24 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, strlen(channel)) == 0) && 30 // 文字列&長さ一致したら周波数テーブル番号を返却する
25 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){ 31 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel,
26 return &isdb_t_conv_table[lp] ; 32 strlen(channel)) == 0) &&
27 } 33 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){
28 } 34 return &isdb_t_conv_table[lp] ;
29 return NULL ; 35 }
30 } 36 }
31 37 return NULL ;
32 QUEUE_T* create_queue(size_t size) 38 }
33 { 39
34 QUEUE_T* p_queue; 40 QUEUE_T *
35 int memsize = sizeof(QUEUE_T) + (size * sizeof(BUFSZ)); 41 create_queue(size_t size)
36 42 {
37 p_queue = (QUEUE_T*)calloc(memsize, sizeof(char)); 43 QUEUE_T* p_queue;
38 44 int memsize = sizeof(QUEUE_T) + (size * sizeof(BUFSZ));
39 if(p_queue != NULL){ 45
40 p_queue->size = size; 46 p_queue = (QUEUE_T*)calloc(memsize, sizeof(char));
41 p_queue->no_full = size; 47
42 p_queue->no_empty = 0; 48 if(p_queue != NULL){
43 pthread_mutex_init(&p_queue->mutex, NULL); 49 p_queue->size = size;
44 pthread_cond_init(&p_queue->cond_full, NULL); 50 p_queue->no_full = size;
45 pthread_cond_init(&p_queue->cond_empty, NULL); 51 p_queue->no_empty = 0;
46 } 52 pthread_mutex_init(&p_queue->mutex, NULL);
47 53 pthread_cond_init(&p_queue->cond_full, NULL);
48 return p_queue; 54 pthread_cond_init(&p_queue->cond_empty, NULL);
49 } 55 }
50 56
51 void destroy_queue(QUEUE_T *p_queue) 57 return p_queue;
52 { 58 }
53 if(p_queue != NULL){ 59
54 pthread_mutex_destroy(&p_queue->mutex); 60 void
55 pthread_cond_destroy(&p_queue->cond_full); 61 destroy_queue(QUEUE_T *p_queue)
56 pthread_cond_destroy(&p_queue->cond_empty); 62 {
57 free(p_queue); 63 if(p_queue != NULL){
58 } 64 pthread_mutex_destroy(&p_queue->mutex);
65 pthread_cond_destroy(&p_queue->cond_full);
66 pthread_cond_destroy(&p_queue->cond_empty);
67 free(p_queue);
68 }
59 } 69 }
60 70
61 // 関数名: enqueue 71 // 関数名: enqueue
62 // キューにデータを入れる 72 // キューにデータを入れる
63 // データが満タンな場合は、ブロックします 73 // データが満タンな場合は、ブロックします
64 void enqueue(QUEUE_T *p_queue, BUFSZ *data) 74 void
65 { 75 enqueue(QUEUE_T *p_queue, BUFSZ *data)
66 pthread_mutex_lock(&p_queue->mutex); 76 {
67 // -- ここから、クリティカルセクション -- 77 pthread_mutex_lock(&p_queue->mutex);
68 78 // -- ここから、クリティカルセクション --
69 // 満タンじゃなくなるまで待つ 79
70 while(!p_queue->no_full) { 80 // 満タンじゃなくなるまで待つ
71 pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex); 81 while(!p_queue->no_full) {
72 printf("Full\n"); 82 pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex);
73 } 83 printf("Full\n");
74 84 }
75 p_queue->buffer[p_queue->in] = data; 85
76 86 p_queue->buffer[p_queue->in] = data;
77 p_queue->in++; 87
78 p_queue->in %= p_queue->size; 88 p_queue->in++;
79 89 p_queue->in %= p_queue->size;
80 p_queue->no_full--; 90
81 p_queue->no_empty++; 91 p_queue->no_full--;
82 92 p_queue->no_empty++;
83 pthread_mutex_unlock(&p_queue->mutex); 93
84 pthread_cond_signal(&p_queue->cond_empty); 94 pthread_mutex_unlock(&p_queue->mutex);
95 pthread_cond_signal(&p_queue->cond_empty);
85 } 96 }
86 97
87 // 関数名: dequeue 98 // 関数名: dequeue
88 // キューにデータを入れる 99 // キューにデータを入れる
89 // データが満タンな場合は、ブロックします 100 // データが満タンな場合は、ブロックします
90 BUFSZ *dequeue(QUEUE_T *p_queue) 101 BUFSZ *
91 { 102 dequeue(QUEUE_T *p_queue)
92 void *result; 103 {
93 104 void *result;
94 pthread_mutex_lock(&p_queue->mutex); 105
95 // -- ここから、クリティカルセクション -- 106 pthread_mutex_lock(&p_queue->mutex);
96 107 // -- ここから、クリティカルセクション --
97 // 空っぽじゃなくなるまで待つ 108
98 while (!p_queue->no_empty) { 109 // 空っぽじゃなくなるまで待つ
99 pthread_cond_wait(&p_queue->cond_empty, &p_queue->mutex); 110 while (!p_queue->no_empty) {
111 pthread_cond_wait(&p_queue->cond_empty, &p_queue->mutex);
112 }
113
114 // データを取り出す
115 result = p_queue->buffer[p_queue->out];
116
117 // 次にデータを取り出す場所をインクリメント
118 p_queue->out++;
119 p_queue->out %= p_queue->size;
120
121 // フラグの更新
122 p_queue->no_full++;
123 p_queue->no_empty--;
124
125 // -- ここまで、クリティカルセクション --
126 pthread_mutex_unlock(&p_queue->mutex);
127 pthread_cond_signal(&p_queue->cond_full);
128
129 return result;
130 }
131
132 /* this function will be a writing thread */
133 void *
134 write_func(void *p)
135 {
136 QUEUE_T *p_queue = (QUEUE_T*)p;
137 BUFSZ *ptr ;
138 ARIB_STD_B25_BUFFER sbuf, dbuf;
139
140 while(1){
141 ptr = dequeue(p_queue);
142 /* no entry in the queue */
143 if(ptr == NULL){
144 close(wfd);
145 break ;
146 }
147
148 sbuf.data = ptr->buffer;
149 sbuf.size = ptr->size;
150
151 /* write data to output file*/
152 b25_decode(dec, &sbuf, &dbuf);
153 write(wfd, dbuf.data, dbuf.size);
154 free(ptr);
155
156 /* normal exit */
157 if((f_exit) && (!p_queue->no_empty)){
158 b25_finish(dec, &sbuf, &dbuf);
159 write(wfd, dbuf.data, dbuf.size);
160 close(wfd);
161 break ;
162 }
163 }
164
165 return NULL;
166 }
167
168 int
169 main(int argc, char **argv)
170 {
171 int fd ;
172 int lp ;
173 int recsec ;
174 time_t start_time ;
175 time_t cur_time ;
176 FREQUENCY freq;
177 ISDB_T_FREQ_CONV_TABLE *ptr ;
178 pthread_t dequeue_threads;
179 QUEUE_T *p_queue = create_queue(MAX_QUEUE);
180 BUFSZ *bufptr ;
181
182 if(argc < 4){
183 printf("Usage %s: channel recsec destfile\n", argv[0]);
184 printf("channel =\n");
185 printf("151ch:BS朝日\n");
186 printf("161ch:BS-i\n");
187 printf("171ch:BSジャパン\n");
188 printf("211ch:BS11デジタル\n");
189 printf("222ch:TwellV\n");
190 printf("141ch:BS日テレ\n");
191 printf("181ch:BSフジ\n");
192 printf("101ch:NHK衛星第1放送(BS1)\n");
193 printf("102ch:NHK衛星第2放送(BS2)\n");
194 printf("103ch:NHKハイビジョン(BShi)\n");
195 return 1;
196 }
197 ptr = searchrecoff(argv[1]);
198 if(ptr == NULL){
199 printf("Channel Select Error(%s)\n", argv[1]);
200 return 1 ;
201 }
202
203 freq.frequencyno = ptr->set_freq ;
204 freq.slot = ptr->add_freq ;
205
206 if(ptr->type == CHTYPE_SATELLITE){
207 for(lp = 0 ; lp < 2 ; lp++){
208 fd = open(bsdev[lp], O_RDONLY);
209 if(fd >= 0){
210 break ;
211 }
212 }
213 if(fd < 0){
214 printf("Device Open Error\n");
215 return 1;
216 }
217 }else{
218 for(lp = 0 ; lp < 2 ; lp++){
219 fd = open(isdb_t_dev[lp], O_RDONLY);
220 if(fd >= 0){
221 break ;
222 }
223 }
224 if(fd < 0){
225 printf("Device Open Error\n");
226 return 1;
227 }
228 }
229 recsec = atoi(argv[2]);
230
231 /* initialize decoder */
232 dec = b25_startup();
233
234 /* open output file */
235 wfd = open64(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666);
236 if(wfd < 0){
237 printf("Output File Open Error(%s)\n", argv[3]);
238 return 0;
239 }
240
241 if(ioctl(fd, SET_CHANNEL, &freq) < 0){
242 printf("Tuner Select Error\n");
243 return 0 ;
244 }
245
246 /* make reading thread */
247 pthread_create(&dequeue_threads, NULL, write_func, p_queue);
248 if(ioctl(fd, START_REC, 0) < 0){
249 printf("Tuner Start Error\n");
250 return 0 ;
251 }
252
253 time(&start_time);
254
255 /* read-write loop */
256 while(1){
257 time(&cur_time);
258 bufptr = calloc(1, sizeof(BUFSZ));
259 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE);
260 if(bufptr->size <= 0){
261 if((cur_time - start_time) >= recsec){
262 f_exit = TRUE ;
263 enqueue(p_queue, NULL);
264 break ;
265 }else{
266 continue ;
267 }
268 }
269 enqueue(p_queue, bufptr);
270
271 if((cur_time - start_time) >= recsec){
272 ioctl(fd, STOP_REC, 0);
273 //なくなるまでデータを読み出す
274 while(1){
275 bufptr = calloc(1, sizeof(BUFSZ));
276 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE);
277 if(bufptr->size <= 0){
278 f_exit = TRUE ;
279 enqueue(p_queue, NULL);
280 break ;
100 } 281 }
101 282 enqueue(p_queue, bufptr);
102 // データを取り出す 283 }
103 result = p_queue->buffer[p_queue->out]; 284 break ;
104 285 }
105 // 次にデータを取り出す場所をインクリメント 286 }
106 p_queue->out++; 287 close(fd); /* close tuner */
107 p_queue->out %= p_queue->size; 288
108 289 /* wait reading thread */
109 // フラグの更新 290 pthread_join(dequeue_threads, NULL);
110 p_queue->no_full++; 291 destroy_queue(p_queue);
111 p_queue->no_empty--; 292
112 293 /* release decoder */
113 // -- ここまで、クリティカルセクション -- 294 b25_shutdown(dec);
114 pthread_mutex_unlock(&p_queue->mutex); 295
115 pthread_cond_signal(&p_queue->cond_full); 296 return 0 ;
116 297 }
117 return result;
118 }
119
120
121 void *write_func(void *p)
122 {
123 QUEUE_T *p_queue = (QUEUE_T*)p;
124 int size = 0 ;
125 BUFSZ *ptr ;
126 #if 0
127 u_char *buffer ;
128
129 buffer = calloc(WRITE_SIZE, sizeof(char));
130 if(buffer == NULL){
131 return NULL ;
132 }
133 #endif
134
135 while(1){
136 ptr = dequeue(p_queue);
137 if(ptr == NULL){
138 close(wfd);
139 break ;
140 }
141 #if 0
142 if((size + ptr->size) < WRITE_SIZE){
143 memcpy((buffer + size) , ptr->buffer, ptr->size);
144 size += ptr->size ;
145 }else{
146 write(wfd, buffer, size);
147 size = ptr->size ;
148 }
149 #endif
150 write(wfd, ptr->buffer, ptr->size);
151 free(ptr);
152 if((f_exit) && (!p_queue->no_empty)){
153 #if 0
154 if(size){
155 write(wfd, buffer, size);
156 }
157 #endif
158 close(wfd);
159 break ;
160 }
161 }
162 return NULL;
163 }
164
165 int main(int argc, char **argv)
166 {
167 int fd ;
168 int rc ;
169 int lp ;
170 int channel ;
171 int recsec ;
172 time_t start_time ;
173 time_t cur_time ;
174 FREQUENCY freq;
175 ISDB_T_FREQ_CONV_TABLE *ptr ;
176 pthread_t dequeue_threads;
177 QUEUE_T *p_queue = create_queue(MAX_QUEUE);
178 BUFSZ *bufptr ;
179
180 if(argc < 4){
181 printf("Usage %s: channel recsec destfile\n", argv[0]);
182 printf("channel =\n");
183 printf("151ch:BS朝日\n");
184 printf("161ch:BS-i\n");
185 printf("171ch:BSジャパン\n");
186 printf("211ch:BS11デジタル\n");
187 printf("222ch:TwellV\n");
188 printf("141ch:BS日テレ\n");
189 printf("181ch:BSフジ\n");
190 printf("101ch:NHK衛星第1放送(BS1)\n");
191 printf("102ch:NHK衛星第2放送(BS2)\n");
192 printf("103ch:NHKハイビジョン(BShi)\n");
193 return 1;
194 }
195 ptr = searchrecoff(argv[1]);
196 if(ptr == NULL){
197 printf("Channel Select Error(%s)\n", argv[1]);
198 return 1 ;
199 }
200
201 freq.frequencyno = ptr->set_freq ;
202 freq.slot = ptr->add_freq ;
203
204 if(ptr->type == CHTYPE_SATELLITE){
205 for(lp = 0 ; lp < 2 ; lp++){
206 fd = open(bsdev[lp], O_RDONLY);
207 if(fd >= 0){
208 break ;
209 }
210 }
211 if(fd < 0){
212 printf("Device Open Error\n");
213 return 1;
214 }
215 }else{
216 for(lp = 0 ; lp < 2 ; lp++){
217 fd = open(isdb_t_dev[lp], O_RDONLY);
218 if(fd >= 0){
219 break ;
220 }
221 }
222 if(fd < 0){
223 printf("Device Open Error\n");
224 return 1;
225 }
226 }
227 recsec = atoi(argv[2]);
228
229 wfd = open64(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666);
230 if(wfd < 0){
231 printf("Output File Open Error(%s)\n", argv[3]);
232 return 0;
233 }
234
235 if(ioctl(fd, SET_CHANNEL, &freq) < 0){
236 printf("Tuner Select Error\n");
237 return 0 ;
238 }
239 pthread_create(&dequeue_threads, NULL, write_func, p_queue);
240 if(ioctl(fd, START_REC, 0) < 0){
241 printf("Tuner Start Error\n");
242 return 0 ;
243 }
244
245 time(&start_time);
246 while(1){
247 time(&cur_time);
248 bufptr = calloc(1, sizeof(BUFSZ));
249 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE);
250 if(bufptr->size <= 0){
251 if((cur_time - start_time) >= recsec){
252 f_exit = TRUE ;
253 enqueue(p_queue, NULL);
254 break ;
255 }else{
256 continue ;
257 }
258 }
259 enqueue(p_queue, bufptr);
260
261 if((cur_time - start_time) >= recsec){
262 ioctl(fd, STOP_REC, 0);
263 //なくなるまでデータを読み出す
264 while(1){
265 bufptr = calloc(1, sizeof(BUFSZ));
266 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE);
267 if(bufptr->size <= 0){
268 f_exit = TRUE ;
269 enqueue(p_queue, NULL);
270 break ;
271 }
272 enqueue(p_queue, bufptr);
273 }
274 break ;
275 }
276 }
277 close(fd);
278 pthread_join(dequeue_threads, NULL);
279 destroy_queue(p_queue);
280 return 0 ;
281 }