view recpt1/recpt1.c @ 1:29f3b2bbbd67

- rename test.c to recpt1.c - divide definitions into recpt1.h
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 16 Feb 2009 15:55:46 +0900
parents recpt1/test.c@67e8eca28a80
children 8ac7c59fefc9
line wrap: on
line source

#include	<stdio.h>
#include	<sys/types.h>
#include	<sys/stat.h>
#include	<fcntl.h>
#include	<time.h>
#include	<stdlib.h>
#include	<string.h>
#include	<pthread.h>
#include        <unistd.h>

#include	<sys/ioctl.h>
#include	"pt1_ioctl.h"

#include	"recpt1.h"


// 周波数テーブル変換
ISDB_T_FREQ_CONV_TABLE	*searchrecoff(char *channel)
{
	int		lp ;

	for(lp = 0 ; lp < 113 ; lp++){
		// 文字列&長さ一致したら周波数テーブル番号を返却する
		if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, strlen(channel)) == 0) &&
			(strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){
			return &isdb_t_conv_table[lp] ;
		}
	}
	return NULL ;
}

QUEUE_T*	create_queue(size_t size)
{
	QUEUE_T*	p_queue;
	int		memsize = sizeof(QUEUE_T) + (size * sizeof(BUFSZ));

	p_queue = (QUEUE_T*)calloc(memsize, sizeof(char));

	if(p_queue != NULL){
		p_queue->size = size;
		p_queue->no_full = size;
		p_queue->no_empty = 0;
		pthread_mutex_init(&p_queue->mutex, NULL);
		pthread_cond_init(&p_queue->cond_full, NULL);
		pthread_cond_init(&p_queue->cond_empty, NULL);
	}

	return p_queue;
}

void	destroy_queue(QUEUE_T *p_queue)
{
	if(p_queue != NULL){
		pthread_mutex_destroy(&p_queue->mutex);
		pthread_cond_destroy(&p_queue->cond_full);
		pthread_cond_destroy(&p_queue->cond_empty);
		free(p_queue);
	}
}

// 関数名: enqueue
//  キューにデータを入れる
//  データが満タンな場合は、ブロックします
void	enqueue(QUEUE_T *p_queue, BUFSZ *data)
{
	pthread_mutex_lock(&p_queue->mutex);
	// -- ここから、クリティカルセクション --

	// 満タンじゃなくなるまで待つ
	while(!p_queue->no_full) {
		pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex);
		printf("Full\n");
	}

	p_queue->buffer[p_queue->in] = data;

	p_queue->in++;
	p_queue->in %= p_queue->size;

	p_queue->no_full--;
	p_queue->no_empty++;

	pthread_mutex_unlock(&p_queue->mutex);
	pthread_cond_signal(&p_queue->cond_empty);
}

// 関数名: dequeue
//  キューにデータを入れる
//  データが満タンな場合は、ブロックします
BUFSZ	*dequeue(QUEUE_T *p_queue)
{
	void	*result;

	pthread_mutex_lock(&p_queue->mutex);
	// -- ここから、クリティカルセクション --

	// 空っぽじゃなくなるまで待つ
	while (!p_queue->no_empty) {
		pthread_cond_wait(&p_queue->cond_empty, &p_queue->mutex);
	}

	// データを取り出す
	result = p_queue->buffer[p_queue->out];

	// 次にデータを取り出す場所をインクリメント
	p_queue->out++;
	p_queue->out %= p_queue->size;

	// フラグの更新
	p_queue->no_full++;
	p_queue->no_empty--;

	// -- ここまで、クリティカルセクション --
	pthread_mutex_unlock(&p_queue->mutex);
	pthread_cond_signal(&p_queue->cond_full);

	return result;
}


void	*write_func(void *p)
{
	QUEUE_T *p_queue = (QUEUE_T*)p;
	int		size = 0 ;
	BUFSZ	*ptr ;
#if 0
	u_char	*buffer ;

	buffer = calloc(WRITE_SIZE, sizeof(char));
	if(buffer == NULL){
		return NULL ;
	}
#endif

	while(1){
		ptr = dequeue(p_queue);
		if(ptr == NULL){
			close(wfd);
			break ;
		}
#if 0
		if((size + ptr->size) < WRITE_SIZE){
			memcpy((buffer + size) , ptr->buffer, ptr->size);
			size += ptr->size ;
		}else{
			write(wfd, buffer, size);
			size = ptr->size ;
		}
#endif
		write(wfd, ptr->buffer, ptr->size);
		free(ptr);
		if((f_exit) && (!p_queue->no_empty)){
#if 0
			if(size){
				write(wfd, buffer, size);
			}
#endif
			close(wfd);
			break ;
		}
	}
	return NULL;
}

int main(int argc, char **argv)
{
	int		fd ;
	int		rc ;
	int		lp ;
	int		channel ;
	int		recsec ;
	time_t	start_time ;
	time_t	cur_time ;
	FREQUENCY	freq;
	ISDB_T_FREQ_CONV_TABLE	*ptr ;
	pthread_t dequeue_threads;
	QUEUE_T *p_queue = create_queue(MAX_QUEUE);
	BUFSZ	*bufptr ;

	if(argc < 4){
		printf("Usage %s: channel recsec destfile\n", argv[0]);
		printf("channel =\n");
		printf("151ch:BS朝日\n");
		printf("161ch:BS-i\n");
		printf("171ch:BSジャパン\n");
		printf("211ch:BS11デジタル\n");
		printf("222ch:TwellV\n");
		printf("141ch:BS日テレ\n");
		printf("181ch:BSフジ\n");
		printf("101ch:NHK衛星第1放送(BS1)\n");
		printf("102ch:NHK衛星第2放送(BS2)\n");
		printf("103ch:NHKハイビジョン(BShi)\n");
		return 1;
	}
	ptr = searchrecoff(argv[1]);
	if(ptr == NULL){
		printf("Channel Select Error(%s)\n", argv[1]);
		return 1 ;
	}

	freq.frequencyno = ptr->set_freq ;
	freq.slot = ptr->add_freq ;

	if(ptr->type == CHTYPE_SATELLITE){
		for(lp = 0 ; lp < 2 ; lp++){
			fd = open(bsdev[lp], O_RDONLY);
			if(fd >= 0){
				break ;
			}
		}
		if(fd < 0){
			printf("Device Open Error\n");
			return 1;
		}
	}else{
		for(lp = 0 ; lp < 2 ; lp++){
			fd = open(isdb_t_dev[lp], O_RDONLY);
			if(fd >= 0){
				break ;
			}
		}
		if(fd < 0){
			printf("Device Open Error\n");
			return 1;
		}
	}
	recsec = atoi(argv[2]);

	wfd = open64(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666);
	if(wfd < 0){
		printf("Output File Open Error(%s)\n", argv[3]);
		return 0;
	}

	if(ioctl(fd, SET_CHANNEL, &freq) < 0){
		printf("Tuner Select Error\n");
		return 0 ;
	}
	pthread_create(&dequeue_threads, NULL, write_func, p_queue);
	if(ioctl(fd, START_REC, 0) < 0){
		printf("Tuner Start Error\n");
		return 0 ;
	}

	time(&start_time);
	while(1){
		time(&cur_time);
		bufptr = calloc(1, sizeof(BUFSZ));
		bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE);
		if(bufptr->size <= 0){
			if((cur_time - start_time) >= recsec){
				f_exit = TRUE ;
				enqueue(p_queue, NULL);
				break ;
			}else{
				continue ;
			}
		}
		enqueue(p_queue, bufptr);

		if((cur_time - start_time) >= recsec){
			ioctl(fd, STOP_REC, 0);
			//なくなるまでデータを読み出す
			while(1){
				bufptr = calloc(1, sizeof(BUFSZ));
				bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE);
				if(bufptr->size <= 0){
					f_exit = TRUE ;
					enqueue(p_queue, NULL);
					break ;
				}
				enqueue(p_queue, bufptr);
			}
			break ;
		}
	}
	close(fd);
	pthread_join(dequeue_threads, NULL);
	destroy_queue(p_queue);
	return 0 ;
}