comparison recpt1/recpt1.c @ 3:6801fe7e04ff

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