대충분석을 끝낸 카메라로 영상을 찍는 소스입니다.

aninly의 이미지
    제가 분석을 했는데 모르는 함수도 몇개 있습니다.
    제가 알고 싶은것은 카메라가 영상을 촬영하고 어딘가 배열로
    저장하고 있을것 같은데 어떤함수(변수)가 영상을 가지고
    있는지 알고 싶습니다.
    그 영상을 받아서 제가 만든 필터를 커친 후 저장할려고 하는데
    어떤변수에 영상이 있는지, 필터를 커친 후 저장하는 방법을
    알고 싶습니다.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/ioctl.h>

/* maximum */
#define CAM_WIDTH 720                //카메라 가로의 크기
#define CAM_HEIGHT 240               //카메라 세로의 크기

static int cam_fp = -1;

#include "userapp.h"                 //camif_param_t 불러오기//
camif_param_t camif_cfg;

static unsigned char *g_yuv;         //포인터 전역변수 *g_yuv

#define CODEC_NAME  "/dev/misc/codec"

/*****************메모리 할당*********************/    
/*             i가 size/4될때 까지 g_yuv를 증가시킴 */
/*         size=cam_width*cam_height*bpp/8        */

void fmalloc(int size)                          //메모리할당 함수//
{
	unsigned int i=0;
	unsigned int *ptr32;

	g_yuv = (unsigned char*)malloc(size);       //size 메모리할당의 주소
	if(!g_yuv)  
	{                                                       
		printf("Memory Allcation Failed \n");          
		exit(1);
	}
	ptr32 = (unsigned int *)g_yuv;             //size메모리 할당의 주소 
	for (;i<size/4; i++)                                               
		*ptr32++ = 0xff00ff00; /* Red */       //  i가 size/4될때 까지  ptr32가 가르키는 곳의 값을 증가
}                                              //  g_yuv를 증가시킴

/******CODEC_NAME 열어서 열린 값을 dev_fp에 저장후 리턴**********/

static inline int cam_init(void)                                    
{
	int dev_fp = -1;

	dev_fp = open(CODEC_NAME, O_RDWR);     //CODEC_NAME 열어서 dev_fp에 저장
	if (dev_fp < 0)                        //CODEC_NAME이 열리는지 확인
	{
		perror(CODEC_NAME);
		printf("Open Failed \n");
		return -1;
	}
	return dev_fp;
}

/***  width=가로 크기 , height= 세로크기 , bpp=비트 퍼 픽셀 16or12 , iter=파일 번호****/
/***cam_fp와 g_yuv를 읽어서 bpp에 맞게 저장 하는 함수 file_name[]  으로 yuv_fp를 넣는다***/

static inline void save_yuv(int width, int height, int bpp, int iter)
{
 	FILE *yuv_fp = NULL;
	char file_name[100];
	
	 /* read from device */
	if (read(cam_fp, g_yuv, width*height*bpp/8) < 0) {
		perror("read()");
	}

	if (bpp == 16 ) {
		sprintf(&file_name[0], "422X%d.yuv", iter);
		printf("422X%d.yuv", iter);
	}
	else { 
		sprintf(&file_name[0], "420X%d.yuv", iter);
		printf("420X%d.yuv\n", iter);
	}
	fflush(stdout);                                            
	/* file create/open, note to "wb" */
	yuv_fp = fopen(&file_name[0], "wb");        //파일을 오픈해서 yuv_fp로 넣어 준다//file 생성//
	if (!yuv_fp) {
		perror(&file_name[0]);
	}
	fwrite(g_yuv, 1, width * height * bpp / 8, yuv_fp); //파일 정보(g_yuv)를 yuv_fp에다가 쓴다//
	fclose(yuv_fp);
}


/*******************************/
/*  시간당 프레임   시간 계산 함수 */

static inline void print_fps(struct timeval *s, struct timeval *e)
{
        unsigned long time;
        unsigned long sec;
        unsigned long usec;
        int fps = 0;
                                                                                
        sec = e->tv_sec - s->tv_sec;
        if (e->tv_usec > s->tv_usec)
                usec = e->tv_usec - s->tv_usec;
        else {
                usec = e->tv_usec + 1000000 - s->tv_usec;
                sec--;
        }
        time = sec * 1000 + (usec+1) / 1000;
        fps = 1000 / (time / 30);
        printf("%d fps\n", fps);
}
                                                                                
/****Main 함수************/

int main(int argc, char *argv[])
{
	char cmdLine[100];
	struct timeval start_tv, end_tv;
	struct timezone tz;
	int cam_width = CAM_WIDTH;
	int cam_height = CAM_HEIGHT;
	int i, goal, bpp,frames =0;
	int  found = 0;

	if (argc != 6) {  
                printf("%s <width> <height> <bpp> <num> <flip>\n", argv[0]);
                printf("          width:  < 240 \n");
                printf("          height: < 320 \n");
                printf("          bpp: 420, 422 \n");
                printf("          num:\n");
                printf("                0 is non-stop capturing\n"
                       "                X is the capture count\n");
                printf("          flip: \n"
                       "                0 is normal \n"
                       "                1 is x-axis mirrorX \n"
                       "                2 is y-axis mirrorX \n"
                       "                3 is 180 rotation \n");
                printf("EX) \n"
                       "   T_SHELL>  %s 240 320 420 0 0 \n", argv[0]);
		goto err;		
	}
	camif_cfg.dst_x = cam_width = atoi(argv[1]);
	camif_cfg.dst_y = cam_height = atoi(argv[2]);
	bpp = atoi(argv[3]);
	switch (bpp) {
		case 422: 
			camif_cfg.bpp = 422;	  
			bpp = 16;
			break;
		case 420:
			camif_cfg.bpp = 420;	  
			bpp = 12;
			break;
		default:
			printf("Wrong Bpp format 422:420 \n");
			return;
	}
	fmalloc(cam_width*cam_height*bpp/8);
	goal = atoi(argv[4]);
	camif_cfg.flip = atoi(argv[5]);	
	if ((cam_fp = cam_init()) < 0)      //CODEC_NAME=dev_fp를 cam_fp로넣고 확인
		goto err;
	if (ioctl(cam_fp, CMD_CAMERA_INIT, &camif_cfg)) {   //모르는 함수
		perror("ioctl");
		goto err;
	}
	gettimeofday(&start_tv, &tz);             //////모르는 함수

	/* Start Camera Codec */
	write(cam_fp,"O",2);           //에 write 한다
	while (!found) {              //found에 값이 올때 까지  프레임과 골이 같아 질때 까지
			frames++;            //프레임을 하나씩 늘려라
			save_yuv(cam_width, cam_height, bpp, frames);
			if( frames == goal ) { found = 1; break;} 
			if ((frames % 30) == 0) {                    // 프레임이 30의 배수 이면
				gettimeofday(&end_tv, &tz);
				print_fps(&start_tv, &end_tv);
				gettimeofday(&start_tv, &tz);
			}
	}
err:
	/* Stop Camera Codec */
	write(cam_fp,"X",2);
	if (cam_fp)                 //카메라 파일 포인터가 들어오면 파일 포인터를 닫는다
		close(cam_fp);
	free(g_yuv);                //할당되 메모리 영역 해제

	return 0;
}


[/]
elien의 이미지

대강 살펴보니
static unsigned char *g_yuv;
가 yuv 영상을 담고 있는 변수네요.

save_yuv() 함수의 23번째 라인을 보면 영상을 yuv_fp 가 가리키는 파일에 기록하고 있습니다.
fwrite(g_yuv, 1, width * height * bpp / 8, yuv_fp);

필터를 사용하시려면 yuv 영상이 저장되어있는 구조를 파악하셔야 하겠지요.

모르는 함수에 대해서는 아래의 링크를 참조하세요
http://man.kldp.org/wiki/FrontPage?action=ManPageIndex&sec=2

훗, 못 믿겠나?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.