yuv영상촬영하는 소스분석하는데 모르는 부분 질문추가

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); //이것이 의미하는것을 모르겠습니다.//
	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);
}
/**************************************************************************/

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;}  //프레임이 사용자의입력값과 같으면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;
}

    질문1. void fmalloc(int size) 함수를 이해하지 못했습니다.
    설명해주시면 감사하겠습니다.

    질문2. 촬영된 영상배열이 어떤것인지 모르겠습니다.

    질문3. gettimeofday(&start_tv, &tz);
    카메라 촬영시간을 정하는것 같은데 start_tv, tz 값이 없는데 어떻게 작동하는건지....

    질문4. 420x%d.yuv로 저장이 되는데 여기에 어떻게 배열값이 들어가는지 알고 싶습니다.

    질문5. 위의 소스에 제가 이해불능이라고 적은 곳을 분석해주시면
    감사하겠습니다.

    질문6. 나머지 소스에 대해서 주석을 달아주시면 감사하겠습니다.

자세하게 답변해 주시면 감사하겠습니다.
지금 저도 책을 찾아보면서 공부하고 있지만, 너무 어려웠어요.
부탁드리겠습니다.

[/]
장우현의 이미지

1. fmalloc 의 어떤 부분이 궁금하신지요? 제가 보기에는 메모리를 할당하고 0xff00ff00 로 초기화 하는게 전부입니다만.

2. 영상 배열은 420, 422 에 따라서 정해집니다. 구체적인것은 420이 어떤 형식인지 찾아보시는것이 좋습니다. (영상 관련 textbook에 나옵니다.) 그리고 위의 소스의 경우 device file에서 420, 422 형식에 맞춰서 데이타가 오네요.

3. gettimeofday는 RTFM (man gettimeofday)

4. 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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.