스마트폰 거치대 기구부 설계

by Blogger 하얀쿠아
2012. 10. 19. 19:56 수행 프로젝트 이력/스마트폰을 이용한 감시시스템 [2011.09~ 2012.09]

본 프로젝트의 기구부를 만들 필요가 있었다.

 

회로를 보관할 박스 부분과, 스마트폰 거치대를 붙일 부분, Panning 모터와 Tilting 모터를 붙일 부분 등이 필요했다.

 

일단, 손으로 대충 구상하여 설계한 뒤, 가공이 쉬운 아크릴과 MDF, 이미 가공되어있던 알루미늄 가공물등을 이용해 프로토 타입을 만들어 보았다. 프로토타입 제작에 2일 걸렸다.

 

 

 

스마트폰 거치대 초기  프로토타입의 모습

 

 

 

이후 프로토타입이 어느정도 가용하다고 판단을 하고, 프로토타입의 설계도를 기준으로 솔리드웍스로 재설계를 했다. 

솔리드웍스 재설계는 팀원중 종섭이가 전담하여 진행해 주었다.

솔리드웍스 완전 처음 사용한다고 하며 튜토리얼 보고 학습후 진행 했으나, 진행속도는 빠른 편이었다.

약 2일 가량 소요.

 

설계된 파일에서 2D 도면만을 추출하여, 알루미늄 가공업체에 의뢰하였다.

 

 

설계도면

 

견적가격은 약 16만5천원 쯤 이었던 것으로 기억한다.

2set를 의뢰 하여 33만원 가량 사용하였다.

 

가공 결과물 - 1세트

 

 

의뢰한 도면대로 가공 결과물이 나왔음을 확인 하고 수령해왔다.

가공 결과물을 열심히 조립하였다.

 

 

조립중 - 회로 보관 박스 부분이다.

 

 

조립이 완료 된 뒤, 갤럭시S2를 거치한 모습은 아래와 같았다.

 

 

 

 

 

 

회로 보관 박스 위에 스마트폰 거치대를 부착하여 사용하였다.

스마트폰 거치대는 차량용으로 판매되는 기성품을 사용하였다.

이 댓글을 비밀 댓글로

FFmpeg 참고자료

by Blogger 하얀쿠아
2012. 10. 3. 06:26 수행 프로젝트 이력/스마트폰을 이용한 감시시스템 [2011.09~ 2012.09]

* 스마트폰을 이용한 가정용 화상감시 장비 프로젝트 진행 과정에서 얻게된 지식을 공유하는 포스팅 입니다.


본 프로젝트에서는 FFmpeg와 x264 라이브러리를 안드로이드에 포팅하여 H.264 인코딩/디코딩을 사용하였다.

결국 인코딩/디코딩 모두 성공 했지만 불완전 하다. 

네트워크 전송시 Intra 코딩만 가능. Inter 코딩 시 수신 측에서 디코딩 불가 문제가 있다. 

이 문제를 해결 중에 있다.(2012. 10월)

아래 링크는 이 작업과정에서 참조했던 사이트의 링크들 이다.


- ffmpeg 사용시 참고했던 사이트 링크

ffmpeg는 레퍼런스 문서나 예제가 많지 않아서 상당히 애를 먹었던 기억이 있다.

doxygen 문서가 있긴 하지만, 필요한 걸 찾기가 개인적으로 불편했었다. 

그래서 각 섹션마다 링크를 걸어둔다.


전역함수 레퍼런스

http://ffmpeg.org/doxygen/trunk/globals_func.html


AVCodecContext 구조체 레퍼런스

http://ffmpeg.org/doxygen/trunk/structAVCodecContext.html#7abe7095de73df98df4895bf9e25fc6b


AVPacket 구조체 레퍼런스

http://ffmpeg.org/doxygen/trunk/structAVPacket.html


libavcodec/h264.h 파일 레퍼런스

http://www.ffmpeg.org/doxygen/trunk/h264_8h.html


ffmpeg 파일 목록

http://www.ffmpeg.org/doxygen/trunk/files.html


ffmpeg 와 SDL 튜토리얼

http://dranger.com/ffmpeg/tutorial01.html



- 그외에 참조했던 사이트 (인코딩/디코딩)


FFmpeg을 이용한 Android 동영상 플레이어 개발 

http://helloworld.naver.com/helloworld/8794


ffmpeg 비디오 디코더(decoder) 사용법 - how to use ffmpeg video decoder

http://greenday96.blogspot.kr/2011/07/ffmpeg-decoder.html


Using libavformat and libavcodec

http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html


x264 옵션 값

http://yg05123.blog.me/70042737774


FFmpeg에 x264 인코더 사용방법 

http://iamlow.tistory.com/entry/FFmpeg%EC%97%90-x264-%EC%9D%B8%EC%BD%94%EB%8D%94-%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95


ffmpeg의 api-example을 기반으로 한 mpeg 인코딩 방법(인코딩 시나리오 파악용으로 참조했다)

http://blog.daum.net/thflfkaus/6


이 댓글을 비밀 댓글로
    • 박가람
    • 2012.11.13 16:38
    안녕하세요~

    저도 ffmpeg + x264로 스마트폰에서 서버로 동영상 전송을 구현하려고하고 있습니다.

    혹시 ffmpeg 과 x264 포팅을 어떻게 하셨는지 여쭈어 봐도 될까요?
    • 저는 halfninja 라는 프로젝트를 참조했습니다.
      다음 URL에서 그 프로젝트의 자료를 다운로드 받을 수 있습니다.

      https://github.com/halfninja/android-ffmpeg-x264

    • 박가람
    • 2012.11.15 22:07
    감사합니다.
    • 박가람
    • 2012.11.25 23:31
    혹시 성능은 어느정도 나오는지 알 수 있을까요?

    실시간으로 적용하려고 하는데 성능이 어느정도 나오는지 궁금해서요~

    싸이즈는 몇에 몇 프레임 정도 나왔나요?

    • 320 X 240 에 대략 10~15 프레임 정도 였던것 같습니다.

      프레임 수치는 측정치는 아니고 제 느낌이(;;) 그렇다는것이므로 참고만 해주시기 바랍니다.
    • 박가람
    • 2013.01.02 10:39
    안녕하세요~ 혹시 인코드 디코드 할때 컨텍스트랑 코덱 세팅 값을 어떻게 하셨는지 알수 있을까요..
    돌아가는거 보니깐 인코딩은 되는 것 같은데 디코딩에서 에러가 나네요ㅠ
    • 김철표
    • 2013.08.16 02:47
    안녕하세요!
    박가람님과 마찬가지 이유로 문의드립니다.
    네트워크로 오디오 패킷을 전송해서 디코딩해보려고 하는데요, 코덱컨텍스트 세팅을 어떻게 하면될까요? 마찬가지고 원격으로는 자꾸 오류가나네요

libavcodec을 사용한 H.264 인코딩/디코딩 - C code

by Blogger 하얀쿠아
2012. 10. 3. 05:58 수행 프로젝트 이력/스마트폰을 이용한 감시시스템 [2011.09~ 2012.09]


* 스마트폰을 이용한 가정용 화상감시 장비 프로젝트 진행 과정에서 얻게된 지식을 공유하는 포스팅 입니다.


본 프로젝트의 전체적인 시스템 구성도는 아래와 같다.



여기에서 코덱이 필요한 이유는, 감시 영상을 네트워크를 통해 전달하기 때문이다.

raw data를 그대로 전달 할 경우, 1프레임 영상의 크기가 1메가를 상회하게 된다. 

(지원 해상도는 QCIF, QVGA 만 허용함. 이는 각각 352 x 288과 320 x 240 이다.)


네트워크 대역폭 제한으로 인해 받아 보는 쪽에서 영상의 프레임이 낮을 것이다.

또한 3G/4G 를 사용한다면 데이터 요금도 상당할 것이다.

 이를 h.264 코덱으로 인코딩 하여 네트워크로 보내게 된다면, 이런 문제를 해결 가능 할 것이라 판단하여 코덱을 사용하였다. 물론 인코딩 하는 카메라 스마트폰의 CPU사용량이 상당히 증가할 것이지만, 뷰어 측의 원할한 영상 수신을 위해서 이정도는 감수하기로 하였다.


감시카메라 Application을 구동하는 스마트폰에서는 입력되는 카메라 영상을 H.264 코덱으로 인코딩 하여 중계서버로 전송한다.


사용자뷰어 Application을 구동하는 스마트폰에서는 중계서버로부터 전송받는 인코딩된 데이터를 디코딩하여 사용자에게 보여준다.


위 과정에서 이루어지는 인코딩/디코딩은 ffmpeg 를 android 용으로 포팅하여 사용했다.

1. 안드로이드에서 ffmpeg의 라이브러리 함수를 호출할 수 있도록 C로 인터페이스 함수를 만들었다.

2. 이 인터페이스 함수들만 모아 .so파일로 만들어 dynamic link 하여 사용하였다.


아래는 인터페이스 함수 제작 과정에 참고한 예제 코드이다.


출처 : http://natnoob.blogspot.kr/search?updated-min=2011-01-01T00:00:00%2B07:00&updated-max=2012-01-01T00:00:00%2B07:00&max-results=6


이 예제는 api-example을 기반으로 구현했다.

이것은 C코드를 이용하여 raw data 영상(QCIF)을 H264로 인코딩 하는 방법과 인코딩 된 영상을 yuv로 디코딩 하는 방법을 보여준다.



 - 아래는 main 함수 부분이다.

int main(int argc, char **argv)

{


/* must be called before using avcodec lib */

avcodec_init();


/* register all the codecs */

avcodec_register_all();


h264_encode_decode("Foreman.qcif","Decoded.yuv");


return 0;

}



- 시작 부분은 언제나 코덱의 등록과 초기화이다.

그 후 이 예제에서는 h264_encode_decode( ) 함수를 호출할 것인데, 이 함수는 Foreman.qcif 라는 파일로 입력되는 영상을 h.264로 인코딩 한 뒤, 다시 yuv 파일로 디코딩 하여 Decoded.yuv 로 저장 할 것이다.


총 5단계로 나눠서 보이겠다.

1. 인코딩/디코딩에 사용할 변수 선언

AVCodec *codecEncode, *codecDecode;

AVCodecContext *ctxEncode= NULL, *ctxDecode = NULL; 


FILE *fin, *fout;

AVFrame *pictureEncoded, *pictureDecoded;


uint8_t *encoderOut, *picEncodeBuf;

int encoderOutSize, decoderOutSize;

int pic_size;


AVPacket avpkt;

int got_picture, len;


const int clip_width = 176;

const int clip_height = 144;


int frame = 0;

uint8_t *decodedOut;



2. 코덱 초기화/디코더를 위한 picture 구조체

codecDecode = avcodec_find_decoder(CODEC_ID_H264);

if (!codecDecode) {

fprintf(stderr, "codec not found\n");

exit(1);

}


ctxDecode= avcodec_alloc_context();

avcodec_get_context_defaults(ctxDecode);

ctxDecode->flags2 |= CODEC_FLAG2_FAST;

ctxDecode->pix_fmt = PIX_FMT_YUV420P;

ctxDecode->width = clip_width;

ctxDecode->height = clip_height; 

ctxDecode->dsp_mask = (FF_MM_MMX | FF_MM_MMXEXT | FF_MM_SSE);


if (avcodec_open(ctxDecode, codecDecode) < 0) {

fprintf(stderr, "could not open codec\n");

exit(1);

}


pictureDecoded= avcodec_alloc_frame();

avcodec_get_frame_defaults(pictureDecoded);

pic_size = avpicture_get_size(PIX_FMT_YUV420P, clip_width, clip_height);


decodedOut = (uint8_t *)malloc(pic_size);

fout = fopen(fileout, "wb");

if (!fout) {

fprintf(stderr, "could not open %s\n", fileout);

exit(1);

}



3. 코덱 초기화/인코더를 위한 picture 구조체

codecEncode = avcodec_find_encoder(CODEC_ID_H264);

if (!codecEncode) {

printf("codec not found\n");

exit(1);

}


ctxEncode= avcodec_alloc_context();

ctxEncode->coder_type = 0; // coder = 1

ctxEncode->flags|=CODEC_FLAG_LOOP_FILTER; // flags=+loop

ctxEncode->me_cmp|= 1; // cmp=+chroma, where CHROMA = 1

ctxEncode->partitions|=X264_PART_I8X8+X264_PART_I4X4+X264_PART_P8X8+X264_PART_B8X8; // partitions=+parti8x8+parti4x4+partp8x8+partb8x8

ctxEncode->me_method=ME_HEX; // me_method=hex

ctxEncode->me_subpel_quality = 0; // subq=7

ctxEncode->me_range = 16; // me_range=16

ctxEncode->gop_size = 30*3; // g=250

ctxEncode->keyint_min = 30; // keyint_min=25

ctxEncode->scenechange_threshold = 40; // sc_threshold=40

ctxEncode->i_quant_factor = 0.71; // i_qfactor=0.71

ctxEncode->b_frame_strategy = 1; // b_strategy=1

ctxEncode->qcompress = 0.6; // qcomp=0.6

ctxEncode->qmin = 0; // qmin=10

ctxEncode->qmax = 69; // qmax=51

ctxEncode->max_qdiff = 4; // qdiff=4

ctxEncode->max_b_frames = 3; // bf=3

ctxEncode->refs = 3; // refs=3

ctxEncode->directpred = 1; // directpred=1

ctxEncode->trellis = 1; // trellis=1

ctxEncode->flags2|=CODEC_FLAG2_FASTPSKIP; // flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip

ctxEncode->weighted_p_pred = 0; // wpredp=2

ctxEncode->bit_rate = 32000;

ctxEncode->width = clip_width;

ctxEncode->height = clip_height;

ctxEncode->time_base.num = 1;

ctxEncode->time_base.den = 30;

ctxEncode->pix_fmt = PIX_FMT_YUV420P; 

ctxEncode->dsp_mask = (FF_MM_MMX | FF_MM_MMXEXT | FF_MM_SSE);

ctxEncode->rc_lookahead = 0;

ctxEncode->max_b_frames = 0;

ctxEncode->b_frame_strategy =1;

ctxEncode->chromaoffset = 0;

ctxEncode->thread_count =1;

ctxEncode->bit_rate = (int)(128000.f * 0.80f);

ctxEncode->bit_rate_tolerance = (int) (128000.f * 0.20f);

ctxEncode->gop_size = 30*3; // Each 3 seconds


/* open codec for encoder*/

if (avcodec_open(ctxEncode, codecEncode) < 0) {

printf("could not open codec\n");

exit(1);

}


//open file to read

fin = fopen(filein, "rb");

if (!fin) {

printf("could not open %s\n", filein);

exit(1);

}


/* alloc image and output buffer for encoder*/

pictureEncoded= avcodec_alloc_frame();

avcodec_get_frame_defaults(pictureEncoded);


//encoderOutSize = 100000;

encoderOut = (uint8_t *)malloc(100000);

//int size = ctxEncode->width * ctxEncode->height;

picEncodeBuf = (uint8_t *)malloc(3*pic_size/2); /* size for YUV 420 */

pictureEncoded->data[0] = picEncodeBuf;

pictureEncoded->data[1] = pictureEncoded->data[0] + pic_size;

pictureEncoded->data[2] = pictureEncoded->data[1] + pic_size / 4;

pictureEncoded->linesize[0] = ctxEncode->width;

pictureEncoded->linesize[1] = ctxEncode->width / 2;

pictureEncoded->linesize[2] = ctxEncode->width / 2; 



4. 입력 파일로 부터 데이터를 읽고, avcodec_encode_video 를 사용해서 인코딩 한다.

인코딩된 데이터는 디코더로 보내질 것인데, yuv 포맷으로 디코딩 된 결과가 나올 것이고, avcodec_decode_video2 를 사용할 것이다. 

디코딩 된 데이터는 decoded.yuv 라는 파일로 만들 것 이다.

//encode and decode loop

for(int i=0;i<30;i++) 

{

fflush(stdout);

//read qcif 1 frame to buufer

fread(pictureEncoded->data[0],ctxEncode->width * ctxEncode->height, 1, fin);

fread(pictureEncoded->data[1],ctxEncode->width * ctxEncode->height/4, 1, fin);

fread(pictureEncoded->data[2],ctxEncode->width * ctxEncode->height/4, 1, fin); 

pictureEncoded->pts = AV_NOPTS_VALUE;


/* encode frame */

encoderOutSize = avcodec_encode_video(ctxEncode, encoderOut, 100000, pictureEncoded);

printf("encoding frame %3d (size=%5d)\n", i, encoderOutSize);

if(encoderOutSize <= 0)

continue;


//send encoderOut to decoder

avpkt.size = encoderOutSize;

avpkt.data = encoderOut;

//decode frame

len = avcodec_decode_video2(ctxDecode, pictureDecoded, &got_picture, &avpkt);

if (len < 0) {

printf("Error while decoding frame %d\n", frame);

exit(1);

}

if (got_picture) {

printf("len = %d saving frame %3d\n", len, frame);

fflush(stdout);


avpicture_layout((AVPicture *)pictureDecoded, ctxDecode->pix_fmt

, clip_width, clip_height, decodedOut, pic_size);

fwrite(decodedOut, pic_size, 1, fout);

frame++;

}

}



5. 할당된 메모리를 해제하고, 파일 포인터를 닫아준다.

fclose(fout);

fclose(fin);


avcodec_close(ctxEncode);

avcodec_close(ctxDecode);

av_free(ctxEncode);

av_free(ctxDecode);

av_free(pictureEncoded); 

av_free(pictureDecoded); 



나는 이 구현코드가 libavcodec을 사용해서 C언어로 h264의 인코딩과 디코딩을 올바르게 하는 방법을 보여주는 적절한 예제라고 생각한다.

이 예제코드를 바로 사용하긴 힘들지만, 인코딩/디코딩 하는 시나리오를 이해하는데 도움이 될 것이다.



이 댓글을 비밀 댓글로
    • 밀레니안
    • 2012.10.12 17:42
    안녕하세요..? 저랑 비슷한 프로젝트를 진행중이셔서 질문이 있어 글 남깁니다..

    저도 ffmpeg를 이용해서 동영상 인코딩을 하는데

    안드로이드에서 영상을 받을때 mediarecoder를 이용해 raw data를 받아서 하신건가요?
    미디어레코더와 로컬 소켓을 이용해 받은 것을 어떻게 활용해야 할지 모르겠어서
    현재 카메라 프리뷰 콜백을 이용해 이미지를 영상으로 인코딩해서 하고 있는데

    최저 화질을 사용해도 15초 촬영에 인코딩 시간이 20초 걸려서 활용할 수가 없어 막혀있습니다....

    미디어레코더로 받은 것을 활용하신거라면...노하우좀 전수해주세요 ㅠㅠ
    • 저 역시 카메라 프리뷰 콜백을 이용했습니다. ^^;
      콜백의 파라미터로 들어오는 byte[ ]형태의 1프레임 짜리 이미지를 콜백 호출이 될 때마다 인코더에 넣어서 인코딩 하는 방식으로 구현했습니다.

      저같은 경우는 영상을 파일로 저장하는게 목적이 아니라 네트워크를 통해 Viewer 쪽에 최대한 빠르게 전송 + 1프레임 영상 하나하나에 대한 영상처리(차영상을 통한 detection & tracking)가 목적이었기 때문에 미디어레코더를 애초에 배제하고 raw image를 받을 수 있는 카메라 프리뷰를 이용했네요.
      제 포스팅이 도움이 되지는 못할 듯 해서 아쉽습니다 ^^;
    • 밀레니안
    • 2012.10.13 01:10
    아...감사합니다..

    Dev고양이님의 글이 저에게 충분히 도움이 되고있습니다...;;

    모든 것을 ffmpeg.c에 기대어 할 생각을 했는데 따로 인코딩 소스를 짜서 할 생각이 생기게 해주셨네요..

    한가지 질문 더 할게요 ㅠㅠ

    위에 적은것 처럼 저두 콜백 이용해서 하는 중인데 저의 경우에는 콜백 통해 받은 바이트를 한 파일에 이어 붙여 그걸 인코딩 하는 식으로 했는데 Yuvimage 객체 를 이용해 사이즈를 변환 해 보려구 했지만 jpeg 로 압축하지 않으면 800X480에서 변하질 않더군여;; 352X288 로는 어떻게 변환 하신건가요?
    사이즈가 줄어들면 인코딩 시간이 줄어들까 싶어서..
    • Camera 객체를 open 한 이후에 여러가지 세팅을 하고(set 계열 메소드들을 호출함으로써) 최종적으로 startPreview( ) 메소드를 호출 하여 카메라 콜백을 하셨을 텐데요.

      그 세팅 과정에서 다음과 같이 파라메터를 카메라에 넣음으로써 콜백함수의 byte[ ] 영상의 해상도를 설정 할 수 있습니다. (try catch 는 댓글의 간략화를 위해 생략했습니다)

      Camera mCamera = Camera.open();
      Camera.Parameters parameters = mCamera.getParameters();
      parameters.setPictureSize(width, height); // width 352, height 288 넣으면.
      mCamera.setParameters(parameters);

      ** 여기서 문제가 있습니다. **
      만약 setPictureSize 에 임의의 수치를 넣게 되면 예외가 발생할 수 있는데, 이 코드가 돌고 있는 안드로이드 폰이 지원하지 않는 해상도를 넣게 되면 예외가 발생 하게됩니다.

      넥서스S 는 352x288을 지원하지만(확실) 320x240을 지원하지 않고요.(확실)
      갤럭시S2는 320x240을 지원하지만(확실), 352x288을 지원 하지 않았던것 같습니다.(긴가민가)

      다음과 같이 현재 코드가 돌고 있는 폰이 지원하는 해상도를 List 형태로 얻을수 있습니다.

      // 카메라에서 찍을 수 있는 모든 사이즈를 List 형태로 얻음

      Camera mCamera = Camera.open();
      Camera.Parameters parameters = mCamera.getParameters();
      List<Size> sizes = parameters.getSupportedPictureSizes();
      Size optimalSize;
      optimalSize = getOptimalPreviewSize(sizes, IMAGE_WIDTH, IMAGE_HEIGHT);
      parameters.setPictureSize(optimalSize.width, optimalSize.height);
      mCamera.setParameters(parameters);

      getOptimalPreviewSize( ) 함수는 뭐.. 다음과 같이 구현 하면 될 것 같습니다.
      파라메터는 지원하는 해상도 목록 sizes, 원하는 해상도의 width와 height 를 넣고요.
      그러면, getOptimalPreviewSize(sizes, 352, 288 ) 이렇게 호출했을때 352x288 지원 불가 폰이라면 가장 인접한 해상도를 리턴해주던지 null을 리턴해 줄 겁니다. (아마도 말이죠)

      private Size getOptimalPreviewSize(List<Size> sizes, int width, int height) {
      final double ASPECT_TOLERANCE = 0.05;
      double targetRatio = (double) width / height;
      if (sizes == null) {
      return null;
      }

      Size optimalSize = null;
      double minDiff = Double.MAX_VALUE;

      int targetHeight = height;

      // Try to find an size match aspect ratio and size
      for (Size size : sizes) {
      double ratio = (double) size.width / size.height;
      if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) {
      continue;
      }
      if (Math.abs(size.height - targetHeight) < minDiff) {
      optimalSize = size;
      minDiff = Math.abs(size.height - targetHeight);
      }
      }

      // Cannot find the one match the aspect ratio, ignore the requirement
      if (optimalSize == null) {
      minDiff = Double.MAX_VALUE;
      for (Size size : sizes) {
      if (Math.abs(size.height - targetHeight) < minDiff) {
      optimalSize = size;
      minDiff = Math.abs(size.height - targetHeight);
      }
      }
      }
      Log.i("optimal size", ""+optimalSize.width+" x "+optimalSize.height); //for debugging
      return optimalSize;
      }

      그럼 좋은 결과 있기를 바랍니다 ^^
    • 밀레니안
    • 2012.10.13 01:44
    헐...완전 자세한 답변에 감동했네요.. 감사합니다 (__)

    이걸로 인코딩 속도는 무조건 줄어들겠죠

    그리고 찾아보니 저랑 같은 곳에 소속되어 있는 곳이 있더군요^^; 지역은 틀리지만...

    반갑습니다. ㅋㅋ

    이 프로젝트 진행중이시던데 좋은 결과 얻길 바라겠습니다.
    • 아! 어느 지역에 계신가요?
      저는 곧 이 프로젝트 마감이라 한창 준비하고 있습니다ㅎ.
      아무튼 무척 반갑습니다. ^^
      해상도를 줄이면 아무래도 인코딩에 소요되는 시간은 줄어들거 같네요. 화이팅 입니다 ~
    • 밀레니안
    • 2012.10.14 21:51
    부산이에요..ㅎ

    15초짜리 20초에서 15초짜리 14초 정도로 줄어들었네요 ㅎㅎ 폰을 좀더 좋은걸 쓴다면 사용 하능 할 것 같아요 ^^

    도움 감사합니다.
    Dev고양이님도 화이팅이요~

[작업일지] 2012년 9월 21일 - 금

by Blogger 하얀쿠아
2012. 9. 21. 05:20 수행 프로젝트 이력/스마트폰을 이용한 감시시스템 [2011.09~ 2012.09]

중계서버 - (전영호)

  - 영상 스트리밍 부분을 수정

  - 기존의 16bit start 마크 / 고정폭raw영상데이터 /16bit end마크 를 빼고.

  - start와 end 를 문자열로 대체. start - 데이터size를나타내는int값(4byte) - 데이터 - end

  - 이렇게 4부분으로 분할

  - camclient, viewclient, clientconnection  3개 스레드의 타이밍 조정. wait( ), notify( ) 활용


카메라앱 - (전영호)

  - 영상 인코딩 h264 , (gop 를 0으로 하여 intra 코딩만 하도록 함)

  - 전송되는 스레드의 타이밍 조정


뷰어 앱 - (전영호)

  - 영상 디코딩 h264

  - ui layout 수정

  - 패키지 재분류

  - recvView 스레드를 없애고 displayer 클래스를 서피스뷰를 상속받아 만들었으며 이 클래스는 이너클래스로 워커스레드 2개를 가진다. 각각 디코딩 워커, draw 워커 이다.

  - 디코딩 워커, draw 워커, 타이밍 조정.



이 댓글을 비밀 댓글로

[ffmpeg] NDK 를 이용해 안드로이드 용 library 빌드시 문제 : codec_names.h 누락

by Blogger 하얀쿠아
2012. 9. 7. 15:46 수행 프로젝트 이력/스마트폰을 이용한 감시시스템 [2011.09~ 2012.09]

ndk version : r8

ffmpeg version : 0.10.4

host os : windows 7

terminal : cygwin


참고 자료 : [Android NDK FFmpeg 컴파일 강좌 (4/4)]

 http://www.androidpub.com/index.php?mid=android_dev_info&page=1&search_target=tag&search_keyword=FFmpeg&document_srl=1646540


문제 내용

참고 자료를 통해 ffmpeg를 빌드하던 중 codec_names.h 를 찾지 못한다는 문제가 발생.


D:/Eclipse_Workspace_Android/FFmpegBasic/jni/ffmpeg/libavcodec/utils.c:1568:36: error: libavcodec/codec_names.h: No such file or directory

/home/JeonYoungHo/android-ndk-r8/build/core/build-binary.mk:240: recipe for target `/cygdrive/d/Eclipse_Workspace_Android/FFmpegBasic/obj/local/armeabi-v7a/objs/avcodec/utils.o' failed

make: *** [/cygdrive/d/Eclipse_Workspace_Android/FFmpegBasic/obj/local/armeabi-v7a/objs/avcodec/utils.o] Error 1





문제 원인

ffmpeg 빌드시 make 파일들을 쭉 따라가다보면 

ffmpeg/libavcodec 에 보면 codec_names.sh 파일이 존재한다. (헤더가 아닌, 쉘 스크립트 프로그램 파일임)

이 쉘 스크립트를 실행 하여 codec_names.h 를 생성하는 구조이다.


codec_names.h는 보통 ndk-build 명령을 통해 build 진행시 auto generate 된다. (make 파일들을 제대로 작성했다는 가정 아래)

어떤 이유인지는 모르겠지만 본인은 codec_names.h 가 자동 생성되지 않아서 build 가 진행되다가 멈추었다.


참조 자료를 따라하며 build 를 시도한다면, libavcodec 디렉토리에 

Makefile2 를 만들었을 것이고, 그것을 열어보면 
65번 line 부터
$(SUBDIR)codec_names.h: $(CODEC_NAMES_SH) config.h $(AVCODEC_H)
$(CC) $(CPPFLAGS) $(CFLAGS) -E $(AVCODEC_H) | \
$(CODEC_NAMES_SH) config.h $@

이런 내용이 있다.
이부분이 codec_names.h 를 자동 생성하는 부분이다. config.h 는 현재 디렉토리에서 찾게 되어있지만 상위 디렉토리에 있으므로 못 찾을 것이고.. 소스상에서도 수정이 약간 필요했다.


해결 방법

요약 : codec_names.sh 를 이용해 codec_name.h 를 수동으로 생성해준다.

구체적 방법 

ffmpeg/libavcodec 디렉토리에 위치한 상태에서 gcc를 통해 다음과 같이 실행.

$ gcc -DLIBAVCODEC_VERSION_MAJOR=53 -E avcodec.h | ./codec_names.sh ../config.h codec_names.h


에러가 날 것이다.

에러내용을 자세히 읽어보면 #include "경로/헤더파일" 의 상대경로/절대경로 문제이다.

에러난 파일을 vi로 열어서 경로를 상대경로로 지정해준다.

 예) In file included from ../libavutil/avutil.h:328,

                 from ../libavutil/samplefmt.h:22,

                 from avcodec.h:30:

../libavutil/common.h:38:32: libavutil/avconfig.h: No such file or directory

avcodec.h:457:36: libavutil/audioconvert.h: No such file or directory


avcodec.h 의 457라인에서 libavutil/audioconvert.h 를 찾을수 없다는 뜻.

avcodec.h 를 열어 457라인을 보면 #include "libavutil/audioconvert.h" 가 있을 것이다.

#include "../libavutil/audioconvert.h" 로 수정해준다. (각자 자신의 기준에서 수정할 필요가 있다)


이런식으로 몇개의 include 관련 에러가 발생하는데, 모두 유사한 방법으로 수정하고  $ gcc -DLIBAVCODEC_VERSION_MAJOR=53 -E avcodec.h | ./codec_names.sh ../config.h codec_names.h 를 다시 해보면 codec_names.h 가 정상적으로 생성될 것이다.

이후, ndk-build 를 통해 다시 진행하여 정상 빌드 되었다.

결론
에러내용을 꼼꼼히 읽고 차근차근 생각해서 잘하자


이 댓글을 비밀 댓글로
    • 한기대졸업생
    • 2013.07.05 16:09
    저도 한기대 졸업했는데 05학번으로 ㅋㅋ 오랜만에 한기대 이름 보니까 반갑네요

핸드폰 Grab 해주는 부분 구매

by Blogger 하얀쿠아
2012. 8. 5. 00:32 수행 프로젝트 이력/스마트폰을 이용한 감시시스템 [2011.09~ 2012.09]

아래 것을 활용하면 괜찮을 듯.


http://www.zenuscase.co.kr/shop/goods/goods_view.php?goodsno=1484&category=004

이 댓글을 비밀 댓글로

스마트폰을 'CCTV·블랙박스'로 활용하세요

by Blogger 하얀쿠아
2012. 4. 3. 01:28 수행 프로젝트 이력/스마트폰을 이용한 감시시스템 [2011.09~ 2012.09]

출처 : http://www.ittoday.co.kr/news/articleView.html?idxno=26260

 

학교폭력을 포함한 일반 범죄 예방과 신고가 가능한 스마트폰 개인안전 서비스가 개시됐다.

앱스비즌(대표 장형규)은 스마트 폰을 CCTV와 블랙박스로 활용한 개인안전 서비스 'secu-EYE'를 출시했다고 29일 밝혔다.


 

 

▲ secu-EYE.

이 앱은 스마트 폰을 CCTV처럼 이용할 수 있다. 동영상을 촬영 전송하고 블랙박스처럼 원격 서버에 저장해 불안한 상황에서 사전대처 할 수 있다. 위험한 상황에서 한 번의 터치로 112치안센터에 말없이 신고할 수 있다. 동영상 증거 자료는 휴대폰에 남지 않고 원격 서버에 저장돼 범죄 신고시에만 치안당국에 제공된다. 사생활 침해에 대한 걱정은 하지 않아도 된다.

또 특정 상황에서만 사용 가능한 이동통신사의 ‘어린이 대상 안심서비스’나 특정용도의‘개인 안전관련 앱’과는 달리 언제 어디서나 서비스를 이용할 수 있다.

앱스비즌은 이번 'secu-EYE'앱 출시에 이어 학교나 스쿨존에 특화된 학생이나 학부모가 사용할 ‘secu-EYE Anysafe’ edition을 발표할 예정이다. 차후 가정이나 영업장과 같은 고정 장소에서 사용가능한 안전 서비스 분야로 확대해 나갈 계획이다.

‘secu–EYE'는 구글 플레이, 티스토어에서 무료로 내려받아 사용할 수 있다.

 

이 댓글을 비밀 댓글로

NETCURY NTI-300B (무선WiFi, IP카메라)

by Blogger 하얀쿠아
2011. 10. 14. 14:50 수행 프로젝트 이력/스마트폰을 이용한 감시시스템 [2011.09~ 2012.09]




이 댓글을 비밀 댓글로