인터넷에 나와 있는 대부분의 예제가 잘못되어 있다.
msgsnd(), msgrcv() 함수의 3번째 인자에 설정 시 주의해야 함.

아래는 맨페이지 내용임.
========================================================================================
       The  msgsnd()  and  msgrcv() system calls are used, respectively, to send messages to, and receive messages from, a message queue.  The calling process must have write
       permission on the message queue in order to send a message, and read permission to receive a message.

       The msgp argument is a pointer to caller-defined structure of the following general form:

           struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[1];    /* message data */
           };

       The mtext field is an array (or other structure) whose size is specified by msgsz, a nonnegative integer value.  Messages of zero length (i.e.,  no  mtext  field)  are
       permitted.  The mtype field must have a strictly positive integer value.  This value can be used by the receiving process for message selection (see the description of
       msgrcv() below).

.
.
.

   msgrcv()
       The msgrcv() system call removes a message from the queue specified by msqid and places it in the buffer pointed to by msgp.

       The argument msgsz specifies the maximum size in bytes for the member mtext of the structure pointed to by the msgp argument.  If the message text has  length  greater
       than  msgsz,  then  the  behavior depends on whether MSG_NOERROR is specified in msgflg.  If MSG_NOERROR is specified, then the message text will be truncated (and the
       truncated part will be lost); if MSG_NOERROR is not specified, then the message isn't removed from the queue and the system call fails returning -1 with errno  set  to
       E2BIG.
========================================================================================
위 내용에 명시한 것처럼 실제 사용할 때에는 struct msgbuf 구조체에서 mtype만큼의 데이터 크기를 빼고 msgsz 값을 설정해 주어야 한다. 아래는 예제이다.

ret = msgrcv(key_id, &mbuf,
                sizeof(struct msgbuf) - sizeof(long), msgtype, MSG_NOERROR);
if (-1 == ret) {
        perror("msgrcv error");
        exit(0);
}

이상!!

Posted by 원자이
이 글도 테스트 과정을 적었다.

0. 환경은 MPEG4 테스트와 동일

1. 설정도 동일하다. 그러나 실행시켜 보면 아래와 같은 메시지가 나타난다.

[h263 @ 0x91a3020] warning, clipping 1 dct coefficients to -127..127

2. 코드 검색

  $ grep -R "dct coefficients to" ../../*
../../libavcodec/mpegvideo_enc.c:        av_log(s->avctx, AV_LOG_INFO, "warning, clipping %d dct coefficients to %d..%d\n", overflow, minlevel, maxlevel);

3. 코드를 보자
  $ vi ../../libavcodec/mpegvideo_enc.c

1461     if(overflow && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE)
1462         av_log(s->avctx, AV_LOG_INFO, "warning, clipping %d dct coefficients to %d..%d\n", overflow, minlevel, maxlevel);

 - ctags를 활용하여 "FF_MB_DECISION_SIMPLE" 추적..

2030     /**    
2031      * macroblock decision mode
2032      * - encoding: Set by user.
2033      * - decoding: unused
2034      */
2035     int mb_decision;
2036 #define FF_MB_DECISION_SIMPLE 0        ///< uses mb_cmp
2037 #define FF_MB_DECISION_BITS   1        ///< chooses the one which needs the fewest bits
2038 #define FF_MB_DECISION_RD     2        ///< rate distortion

  - mb_cmp 라는 주석을 보고 또 추적.. 

1836      * macroblock comparison function (not supported yet)
1837      * - encoding: Set by user.
1838      * - decoding: unused
1839      */
1840     int mb_cmp;

  - not supported yet 이란다...
    avctx->mb_decision = FF_MB_DECISION_SIMPLE;
    avctx->mb_cmp = -127 ~ ... 127 설정;

   테스트 결과 not supported yet 이 검증됨...ㅋㅋ

  - FFmpeg 홈페이지에도 아래와 같은 문구가 있음.
`-mbd mode'
macroblock decision
`0'
FF_MB_DECISION_SIMPLE: Use mb_cmp (cannot change it yet in ffmpeg).
`1'
FF_MB_DECISION_BITS: Choose the one which needs the fewest bits.
`2'
FF_MB_DECISION_RD: rate distortion
 

4. MB_DECISION 이 뭔가 인터넷 검색...
   매크로블럭을 결정하는 방법들 이라는데.. 영상처리와 관련된 약간은 난이도가 있는 부분인듯하다.. 
  FF_MB_DECISION_BITS ==> 잘 모르겠음..
  FF_MB_DECISION_RD ==> 이 녀석이 화질이 가장 좋다고 하나, 처리하는데 시간이 오래 걸린덴다.. (모든 MB를 검색하여 가장 좋은 MB 모드를 설정한다고 한다.) 인터넷에 검색하니 약자로 RDO(Rate-distortion Optimization) 라고 불린다.

 아래처럼 설정하면 경고메시지가 사라지고 정상동작한다.

 avctx->mb_decision = FF_MB_DECISION_BITS; // or FF_MB_DECISION_RD;

이상!!!
그리고 비트레이트가 딱 떨어지게 영상이 인코딩되지는 않는다.

* 참고로.. 영상확인은 VLC 플레이어를 사용하여 정상적으로 인코딩 되었는지 확인했다..

Posted by 원자이
여기에는 테스트한 발자취를 남긴다. 따라서 삽질하는 과정도 포함되어 있다.

이 작업을 한 이유는 이전에 작업한 libx264 라이브러리가 안드로이드 플랫폼에서 영상을 인코딩할 때 성능문제가 발생했기 때문이다. 약 6프레임 정도 밖에 나오지 않는다.. 그래서 대체할 코덱을 찾느라고 작업했다.

0. FFmpeg 0.8.2 버전을 가지고 테스트하였고, 예제는 ffmpeg-0.8.2/doc/example/encoding_example.c 파일을 사용하였다.

1. FFmpeg을 가지고 MPEG4 Video 영상을 인코딩 하기 위해 사용한 옵션은 아래와 같다.

249     /* put sample parameters */                                    
255     c->bit_rate         = 300 * 1000;                              
257     /* resolution must be a multiple of two */                     
258     c->width = 352;                                                
259     c->height = 288;                                               
260     /* frames per second */                                        
261     c->time_base= (AVRational){1,25};                              
262     c->gop_size = 25; /* emit one intra frame every ten frames */  
263     c->pix_fmt = PIX_FMT_YUV420P;

2. H.264와 달리 PTS 값을 매번 설정하지 않고 아래와 같이 설정하면 경고나 오류없이 동작한다.

221     AVFrame *picture;
326     picture->pts = AV_NOPTS_VALUE;

3. 그러나 문제는... CBR 비트레이트 컨트롤이 제대로 안되는 문제가 발생하였다.
   구글링과 삽질을 통하여 옵션을 찾았다. bufsize와 maxrate 옵션을 설정하니 CBR 비트레이트 설정이 가능하였다. (bufsize maxrate 옵션이 무것인지는 인터넷 찾아보면 어렵지 않게 찾을 수 있다.) 이 설정은 영상을 네트워크로 전송할 때와 같은 경우에 쓰면 된다.
   ffmpeg 바이너리를 가지고 아래와 같이 설정하면 된다.

   $ ffmpeg -i example.y4m -vcodec mpeg4 -bufsize 300K -b 300K -maxrate 300K video_300k.mp4
   
4. 테스트 코드에 적용시켜 보았다.

249 /* put sample parameters */
250 c->rc_max_rate = 300 * 1000;
251 c->bit_rate = c->rc_max_rate >> 1;
252 c->rc_buffer_size = c->rc_max_rate;
254 /* resolution must be a multiple of two */
255 c->width = 352;
256 c->height = 288;
257 /* frames per second */
258 c->time_base= (AVRational){1,25};
259 c->gop_size = 25; /* emit one intra frame every ten frames */
260 c->pix_fmt = PIX_FMT_YUV420P; 

   테스트 결과 동작은 하는데.... 아래와 같은

   [mpeg4 @ 0x90ba020] rc buffer underflow

   메시지가 발생한다... 내가 뭔가 빠뜨린것 같은데... 설정이 부족한거 같다.
   구글링했으나 못찾았다..

   그래서 코드를 뒤졌다..

   $ grep -R "rc buffer underflow" ../../*
../../libavcodec/ratecontrol.c:            av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n");

   뭔가 있다..

  $ vi ../../libavcodec/ratecontrol.c
  
266 int ff_vbv_update(MpegEncContext *s, int frame_size){
267     RateControlContext *rcc= &s->rc_context;
268     const double fps= 1/av_q2d(s->avctx->time_base);
269     const int buffer_size= s->avctx->rc_buffer_size;
270     const double min_rate= s->avctx->rc_min_rate/fps;
271     const double max_rate= s->avctx->rc_max_rate/fps;
272
273 //printf("%d %f %d %f %f\n", buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate);
274         av_log(s->avctx, AV_LOG_ERROR, "%d %f %d %f %f\n", buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate);
275     if(buffer_size){
276         int left;
277
278         rcc->buffer_index-= frame_size;
279         if(rcc->buffer_index < 0){
280             av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n");
281             rcc->buffer_index= 0;
282         }

   279 라인에서 rcc->buffer_index 값 때문에 메시지를 찍네..
   buffer_index 값으로 검색 또 해봤다..

66 int ff_rate_control_init(MpegEncContext *s)
.
.
.
127     rcc->buffer_index= s->avctx->rc_initial_buffer_occupancy;

   127 라인에서 avctx->rc_initial_buffer_occupancy 값을 설정하네.. 빙고!!!
   구글링 해보니 rc_max_rate값과 동일하게 설정을 하더라...
   그래서 아래와 같이 설정을 했다.

249     /* put sample parameters */                                    
250     c->rc_max_rate      = 300 * 1000;                              
251     c->bit_rate         = c->rc_max_rate >> 1;                     
252     c->rc_buffer_size   = c->rc_max_rate;                          
253     c->rc_initial_buffer_occupancy = c->rc_max_rate;               
254     /* resolution must be a multiple of two */                     
255     c->width = 352;                                                
256     c->height = 288;                                               
257     /* frames per second */                                        
258     c->time_base= (AVRational){1,25};                              
259     c->gop_size = 25; /* emit one intra frame every ten frames */  
260     c->pix_fmt = PIX_FMT_YUV420P;                                   
 
   아래 경고 문구가 사라짐..ㅋㅋ 행복하구나..

 [mpeg4 @ 0x90ba020] rc buffer underflow

이렇게 쓰면 될 듯... 이상!!
위 코드를 보면 알겠지만 비트레이트 설정한데로 정확하게 나오지는 않는다.
rc_max_rate와 bit_rate 항목을 알맞게 설정해서 써야한다.

테스트 코드 아래 첨부..



* 성능 테스트 결과
  - 비트레이트가 낮을 수록 성능이 떨어지는 것 같음.
  - rc_initial_buffer_occupancy 값을 어떻게 설정하느냐에 따라 비트레이트가 달라지는 것 같음.
  - [mpeg4 @ 0x8d60020] impossible bitrate constraints, this will fail 이런 메시지가 발생함.
     비트레이트와 최대 비트레이트를 같게 하면 나타남..
  - 테스트 중 낮은 비트레이트를 설정하면   [mpeg4 @ 0x90ba020] rc buffer underflow] 
     메시지가 동일하게 발생함. 비트레이트를 터무니 없게 낮게 설정할 경우 발생하는 것으로 판단됨. CIF 영상에 비트레이트를 100K 로 설정하면 발생하나 QCIF에 비트레이트 100K로 설정하면 정상적으로 영상이 출력됨.
  - 비트레이트를 맞추기 위해서 해상도, 프레임레이트 별로 설정하는 rc_max_rate, rc_buffer_size, rc_initial_buffer_occupancy 값을 테스트하여 표로 만들어서 정리해야 할 것으로 생각됨.

249 /* put sample parameters */
250 c->rc_max_rate = 300 * 1000;
251 c->bit_rate = c->rc_max_rate >> 1;
252 c->rc_buffer_size = c->rc_max_rate;
253 c->rc_initial_buffer_occupancy = c->rc_max_rate;              
Posted by 원자이

vim 설정 파일

2011/09/07 09:43
- 내용
  1 set nu
  2 set ai
  3 set si


- .pc 확장자(proc 파일 하이라이트 기능 설정)
  $ sudo vi /usr/share/vim/vim72/filetype.vim
 
1384 " Oracle Pro*C/C++
1385 "au BufNewFile,BufRead *.pc                     setf proc
1386 au BufNewFile,BufRead *.pc                      setf esqlc

기존 1385 라인은 주석처리하고
1386 라인을 추가한다.
Posted by 원자이


1. adduser를 사용하자!
  이 녀석을 사용하면 사용자 디렉토리와 패스워드까지 모든 것을 한방에 할 수 있다.

  $ sudo adduser [사용자 ID]

2. sudo 추가
  $ sudo vi /etc/sudoers

  파일내용
# User privilege specification
root    ALL=(ALL) ALL
[사용자ID] ALL=(ALL) ALL  # 이부분을 추가
 
3. samba 추가
 이 녀석은 아래 명령으로 프로그램을 설치해야 한다.
  $ sudo vi /etc/samba/smb.conf 아래

#======================= Share Definitions =======================

# Un-comment the following (and tweak the other settings below to suit)
# to enable the default home directory shares. This will share each
# user's home director as \\server\username
[homes]
   comment = Home Directories
   browseable = yes

# By default, the home directories are exported read-only. Change the
# next parameter to 'no' if you want to be able to write to them.
   read only = no


  $ sudo apt-get install samba smbfs
  $ sudo smbpasswd -a [사용자ID]

Posted by 원자이
1. FFmpeg을 통하여 x264를 사용하고자 하였다.
   용도는 카메라 영상을 H.264 로 인코딩하여 실시간으로 전송하는데 사용하려고 한다.
   이에 알맞는 x264 코덱의 환경 설정 방법들 중 중요한 부분을 아래 적는다.
   - Baseline Profile을 사용(B Frame 사용안함)
     * x264는 Constrained baseline 만 지원하고 Baseline Profile는 지원 안한댄다..
       그래서 Constrained baseline을 사용하기로 했다. ffmpeg에서 baseline으로 설정하면 자동으로 Constrained baseline으로 설정된다.
   - Level 1.3을 사용
   - RC(Rate Control): ABR(Average Bit Rate)
   * Baseline Profile/Level 1.3 등의 정보는 H.264 로 검색하면 쉽게 찾을 수 있다.
   * RC와 관련된 사항은 x264로 검색하면 어렵지 않게 찾을 수 있다.
      --> 참고 사이트: http://yg05123.blog.me/70042737774

2. x264 코덱은 설정항목이 엄청 많다.. 30개는 넘는 거 같다.
 --> 참고사이트
111 /**
112  * @remark reference sites for x264 setting
113  * http://vidcorea.net/lecture/2156
114  * http://avidemux.org/admWiki/doku.php?id=tutorial:h.264
115  * http://vidcorea.net/2146
116  * http://sites.google.com/site/linuxencoding/x264-ffmpeg-mapping
117  * http://mewiki.project357.com/wiki/X264_Settings
118  */
   게다가 인터넷을 검색해보면 ffmpeg 실행파일에 command arguement를 사용하여 영상을 인코딩 하는 코드는 쉽게 찾을 수 있다.
   그러나 ffmpeg API를 사용하여 코드 상에서 설정하는 방법이 있으나 대부분 미흡한 부분이 많았다. (내가 못 찾았을 확률이 크다.)
   그래서 ffmpeg.c 파일을 분석했다.. 함수포인터에다가.. command arguement 파싱하는 부분들이 많아서 코드보기 무지하게 난해했다.
   가장 문제가 되었던 부분은 2 부분이다.
   1) profile 설정 ==> 설정하는 방법을 인터넷에서 못찾았다.
   2) bitrate 설정 ==> 설정하는 부분을 찾았으나 실제 테스트 해보니 정상동작 안했다.
   이 두 부분은 4번 항목에서 설명하고 3번항목에서 x264 간단한 설정 방법을 아래서 설명한다.


3. ffmpeg에서 x264 영상설정하기
  - ffmpeg 0.8.2 버전을 사용하였다.
  - 테스트 코드는 ffmpeg 소스를 받아보면 doc/example 디렉토리에 encoding_example.c 파일을 수정하면서 테스트 했다. (여기 예제로만 x264 영상설정.... 택도없다...)
  - 일단 H.264 코드를 찾는다.
    codec = avcodec_find_encoder(CODEC_ID_H264);
  - 찾은 후 AVCodecContext 구조체에 영상 설정을 해야 한다.
    AVCodecContext *c = avcodec_alloc_context();
    이 구조체에 영상설정과 관련된 항목이 모여있다. x264 뿐만 아니라 다른 코덱도 동일하게 이 구조체를 사용한다.( 공통적으로 사용하려다 보니.. 변수명들이 x264에 어느 변수들이랑 매핑되는지 찾기가 좀 힘들다. libavcodec/libx264.c 파일에 X264_init함수보면 대충 알 수 있다.)
  - AVCodecContext 구조체에는 엄청나게 많은 필드가 있으나, 실제 사용을 위해 설정할 필드는 몇 개 안된다. 내가 사용한 필드 들은 아래와 같다.
    coder_type ==> CAVLC or CABAC 엔트로피 모드를 설정한다.(참고로 baseline profile은 CAVLC만 지원한다.)
    gop_size ==> group of picture 이다. 자세한건 인터넷 검색...
    bitrate ==> 말그대로 bitrate
    qmin ==> quality min~~ 영상화질의 범위의 최소값을 지정한다.
    qmax  ==> quality max ~~ 영상화질의 범위의 최대값을 지정한다.
    max_qdiff ==> quality 값이 변화량을 지정한다. 즉 여기에 정해진 값 단위로 증가되거나 감소된다는 뜻이다. 예를 들어 현재 q값이 10이면 14, 18이런식으로 증가되거나 감소된다는 말이다.
    pix_fmt ==> pixel format을 말한다.. RGB, YUV 이런거 말이다.
    width, height ==> 해상도다..
    time_base.num ==> 프레임레이트 설정할 때 쓰는데 그냥 1쓰면된다.
    time_base.den ==> 프레임레이트 넣으면 된다. 25프레임이면 25 넣으면 된다.

내가 코드에 설정한 값들은 아래와 같다.

 200         c->coder_type                   = FF_CODER_TYPE_VLC;
 201 //      c->refs                         = 3;
 202         c->flags                        |= CODEC_FLAG_LOOP_FILTER;
 203         c->deblockalpha                 = 0;
 204         c->deblockbeta                  = 0;
 205         c->partitions                   = X264_PART_I4X4
 206                                         | X264_PART_P8X8
 207                                         | X264_PART_B8X8;
 208 //      c->me_method                    = ME_HEX;
 209 //      c->me_subpel_quality            = 7;
 210 //      c->flags2                       |= CODEC_FLAG2_PSY;
 211 //      c->psy_rd                       = 1.0;
 212 //      c->psy_trellis                  = 0.0;
 213 //      c->flags2                       |= CODEC_FLAG2_MIXED_REFS;
 214 //      c->me_range                     = 16;
 215 //      c->me_cmp                       = FF_CMP_CHROMA;
 216 //      c->trellis                      = 0;    // 0: speed up!
 217 //      c->flags2                       &= ~CODEC_FLAG2_8X8DCT;
 218 //      c->flags2                       |= CODEC_FLAG2_FASTPSKIP;
 219 //      c->chromaoffset                 = -2;
 220 //      c->thread_count                 = 1;
 221 //      c->slices                       = 0;
 222 //      c->noise_reduction              = 0;
 223 //      c->flags                        |= CODEC_FLAG_INTERLACED_DCT;
 224 //      c->max_b_frames                 = 0;
 225 //      c->weighted_p_pred              = 0;
 226         c->gop_size                     = 25;
 227 //      c->keyint_min                   = 25;
 228 //      c->scenechange_threshold        = 40;  
 229 //      c->flags2                       &= ~CODEC_FLAG2_INTRA_REFRESH;
 230 //      c->rc_lookahead                 = 40;
 231 //      c->crf                          = 23.0; // ABR
 232 //      c->cqp                          = -1;   // ABR
 233 //      c->flags2                       |= CODEC_FLAG2_MBTREE;
 234         c->bit_rate                     = 10 * 1000 * 1000;
 235 //      c->bit_rate_tolerance           = 1.0;  //not config
 236 //      c->qcompress                    = 0.6;
 237         c->qmin                         = 10;
 238         c->qmax                         = 51;
 239         c->max_qdiff                    = 4;
 240 //      c->i_quant_factor               = 10/14; // i_qfactor=0.71
 241 //      c->aq_mode                      = 1;
 242 //      c->aq_strength                  = 1.00;
 243
 244 //      c->rc_max_rate                  = 200 * 1000;
 245 //      c->rc_min_rate                  = 300 * 1000;
 246 //      c->rc_buffer_size               = c->rc_max_rate * 100;
 247 //      c->flags                        |= CODEC_FLAG_GLOBAL_HEADER;
 248 //      c->flags                        |= CODEC_FLAG_PASS1;
 249
 250         /* */
 251         c->pix_fmt                      = PIX_FMT_YUV420P;
 252         c->width                        = 384; // 320; //176;
 253         c->height                       = 288; //240; // 144;
 254         c->time_base.num                = 1;
 255         c->time_base.den                = 25; //15;


이렇게만 설정하고 예제 프로그램을 돌렸다.
out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
테스트 프로그램은 동작은 하는데 인코딩 되어 나오는 데이터가 0바이트라고 나온다.
뭐지?? 이런..
근데 인코딩 함수를 호출하는 루프문이 있는데.. 루프문을 더 오래 돌려보니까 인코딩된 데이터가 나온다. 예제 소스를 자세히 보면 알겠지만. 인코더에 YUV영상을 넣으면 인코딩된 영상이 바로 나오는 것이 아니라 나중에 호출한 함수에서 이전에 입력했던 YUV영상이 나온다. 그래서 예제 소스를 자세히 보면 아래와 같은 부분이 있다.

 923     /* get the delayed frames */
 924     for(out_size = 1; out_size; i++) {
 925         fflush(stdout);
 926
 927         out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
 928         printf("write frame %3d (size=%5d)\n", i, out_size);
 929         fwrite(outbuf, 1, out_size, f);
 930         total_size += out_size;
 931     }
 932 

이 부분이 딜레이 된 인코딩 영상이 나오는 것을 처리한다.

일단 영상은 나온다. 그런데...

문제점이 있는게.. 난 baseline profile을 서야하는데 x264가 계속 Main Profile로 설정되는 것이다.
그리고 비트레이트 컨트롤이 안된다. 아까 앞서 말한 2 가지 문제점이다.

4. 두가지 문제점을 나누어 설명한다.

1) Baseline Profile 설정하기
  - 일단 설정하는 코드는 아래와 같다.

 306     c->priv_data = alloc_priv_context(codec->priv_data_size, codec->priv_class);
 307     int flags = AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
 308     if (av_find_opt(c->priv_data, "profile", NULL, flags, flags)) {
 309             if (av_set_string3(c->priv_data, "profile", "baseline", 1, NULL) < 0) {
 310                     fprintf(stderr, "Invalid value '%s' for option '%s'\n",
 311                                     "profile", "baseline");
 312                     exit(1);
 313             }
 314     }

 - 이 코드를 cmdutils.c 에서 찾았다. 인터넷 아무리 뒤져도 이렇게 쓰라는 설명 없다..ㅠㅠ
 - 알고나니 별거 없다.
 - 309번 라인 처럼 문자열을 설정하면 x264 라이브러리에 설정된다.
 - 원하는 프로파일을 그냥 문자열로 쓰면 설정할 수 있다.

2) Bitrate 설정하기
  - 프로그램을 실행하면 아래와 같은 경고 메시지가 뜬다.
    [libx264 @ 0x8455020] non-strictly-monotonic PTS
 
- 이것을 설정하는 방법은 인터넷에 나와 있다.
    ==> http://lists.libav.org/pipermail/libav-user/2011-February/005995.html
  - 근데 이대로 하면 안된다. 다른 곳 찾아봐도 안나온다.
  - 그래서 정상동작하는 ffmpeg 라이브러리에 이 값을 어떻게 쓰는지 로그를 찍어보았다. 근데.. 허무하다.. 그냥 1씩 증가 시켜써 썼다.. 그래서 나도 picture->pts = i++; 이렇게 쓰니.. bitrate 제어가 된다. 허무하다..

위 사항을 모두 반영하니 영상 설정도 된다.
단 위 사항들은 경험적으로 얻은 방법이기에 올바른 사용법이 아닐 확률이 높다.
참고만 합시다..!!

* 첨부파일로 내가 사용한 지저분한 테스트 프로그램을 올린다.
   나중에 정리가 되면 좀 더 깨끗한 코드를 올릴 수도 있겠지만.. 
   보는데 별 무리 없을 듯..



5. 이건 테스트 시 참고하세요.
  - ffmpeg 프로그램이나 x264 프로그램을 을 실행하여 인코딩 할 때 보면 예제로 사용하는 영상 타입이 y4m이라는 확장자를 사용하는데, 이 예제 영상이 필요하시면 여기서 다운받아 쓰세요.
 예제 사이트: http://samples.mplayerhq.hu/yuv4mpeg2/
  - ffmpeg API를 통하여 설정한 항목이 x264 라이브러리에 정상적으로 설정이 되는지를 확인하고 싶을 때 아래처럼 추가해서 테스트 하세요.
    (AVCodecContext *)c->flags                        |= CODEC_FLAG_GLOBAL_HEADER;
    그러면 libx264에서 설정된 옵션을 화면에 텍스트로 뿌려 줍니다.

[libx264 @ 0x974f020] 264 - core 116 r2057 0ba8a9c - H.264/MPEG-4 AVC codec - Copyleft 2003-2011 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=1:0:0 analyse=0x1:0x111 me=dia subme=8 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=4 chroma_me=0 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=25 keyint_min=13 scenecut=0 intra_refresh=0 rc_lookahead=25 rc=abr mbtree=1 bitrate=10000 ratetol=1.0 qcomp=0.50 qpmin=10 qpmax=51 qpstep=4 ip_ratio=1.25 aq=1:1.00

  H.264 영상은 SPS, PPS 정보를 가지고 있는데, 이 정보는 avcodec_encode_video() 함수를 맨 처음 호출할 때 인코딩된 영상데이터 제일 앞에 포함되어 있다. 
  그러나 SDP를 사용하거나 기타 등등 의 경우 SPS, PPS 정보를 따로 추출하여 사용해야 할 경우가 있다. 이럴 때 CODEC_FLAG_GLOBAL_HEADER 옵션을 사용하면 된다.
  이 옵션을 설정한 다음에 avcodec_encode_video() 함수를 호출하면 SPS, PPS 정보가 들어있지 않게 된다. 따라서 아래 방법을 통하여 SPS, PPS 정보를 얻어야 한다.

206         /* open codec */
207         ret = avcodec_open(f->ctx, codec);
208         assert(!ret, "avcodec_open is failed!");
209
210         /* get sps, pps */
211 #if 0
212         trace_sprop(f->ctx);
213 #endif
214         f->extradata_size = f->ctx->extradata_size;
215         memcpy(f->extradata, f->ctx->extradata, f->ctx->extradata_size);

  AVCodecContext 구조체 안에 extradata_size에는 SPS, PPS 크기정보가 들어있고, 실제 데이터는 extradata에 들어있다. 이 값은 avcodec_open() 호출한 후에 얻을 수 있다.

6. x264 라이브러리는 기본설정으로 SPS, PPS가 주기적으로 나온다.. 참고하시길....
    주기적으로 나오는 것을 설정하는 방법은 모름.

7. x264에 보면 아래와 같은 SEI 정보를 생성하여 인코딩된 영상에 들어가게 된다.

 264 - core 116 r2057 0ba8a9c - H.264/MPEG-4 AVC codec - Copyleft 2003-2011 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=1:0:0 analyse=0x1:0x111 me=dia subme=8 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=4 chroma_me=0 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=25 keyint_min=13 scenecut=0 intra_refresh=0 rc_lookahead=25 rc=abr mbtree=1 bitrate=10000 ratetol=1.0 qcomp=0.50 qpmin=10 qpmax=51 qpstep=4 ip_ratio=1.25 aq=1:1.00

  - SEI 라는 것은 사용자가 독자적으로 정의하는 정보인데 x264가 이러한 정보를 넣는다.
  테스트 결과 이 정보가 없어도 인코딩된 영상을 디코딩하는데 아무런 문제가 없다.
  x264 API를 통하여서는 이 정보를 제거할 수는 없는 것 같다.
  아래는 실제 설정하는 코드가 위치하는 곳이다.
          
int x264_encoder_headers( x264_t *h, x264_nal_t **pp_nal, int *pi_nal )
{
...
 /* identify ourselves */                             
 x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
 if( x264_sei_version_write( h, &h->out.bs ) )        
     return -1;                                       
 if( x264_nal_end( h ) )                              
     return -1;                                        
 ...
}                                                 
                                                      

  - FFmpeg에서는 libavcodec/libx264.c 라는 파일에서 x264와의 I/F를 정의하고 있다. 아래는 코드다

    avctx->extradata      = av_malloc(s);                                        
    avctx->extradata_size = encode_nals(avctx, avctx->extradata, s, nal, nnal, 1);

    마지막 인자의 값을 1 을 설정하면 avcodec_encode_video() 함수 호출 시에 SEI 정보가 나오고, 0으로 설정하면, extradata안에 SEI 정보가 들어있게 된다.
   

Posted by 원자이
config.log 파일 확인해 보면 어디서 문제가 발생했는디 디버깅이 가능함.
Posted by 원자이
0. 환경
  - OS: Ubuntu 10.04
  - FFmpeg 0.8.2

1. NDK 다운로드
  - 사이트: http://developer.android.com/sdk/ndk/index.html 에서 다운로드
  - 다운로드
    $ wget http://dl.google.com/android/ndk/android-ndk-r6-linux-x86.tar.bz2

2. NDK 설치
    $ tar xvfj android-ndk-r6-linux-x86.tar.bz2
    $ cd android/android-ndk-r6/build/tools
    $ ./make-standalone-toolchain.sh  --ndk-dir=/home/iamlow/android/android-ndk-r6 
 Auto-config: --toolchain=arm-linux-androideabi-4.4.3
 Copying prebuilt binaries...
 Copying sysroot headers and libraries...
 Copying libstdc++ headers and libraries...
 Creating package file: /tmp/ndk-iamlow/arm-linux-androideabi-4.4.3.tar.bz2
    $ tar xvfj arm-linux-androideabi-4.4.3.tar.bz2
    * 특이사항: 쉘 스크립트를 가지고 툴체인 패키지를 만들어 준다. 그러면 이것을 빌드시 사용하면 된다.

3. 환경변수
  - $ vi /etc/profile 에 경로 추가
     export PATH=/opt/android-toolchain/bin:$PATH



4. x264 다운로드
  - 사이트: http://www.videolan.org/developers/x264.html
  - 다운로드
    $ git clone git://git.videolan.org/x264.git
    (우분투에서 git 없으면 apt-get install git 하면 될듯..)

5. x264 빌드
  - 다운받은 디렉토리로 이동하고 아래 명령 실행.
   $ ./configure --host=arm-linux --cross-prefix=arm-linux-androideabi- --enable-shared --enable-static --prefix=/opt/android-8-toolchain/sysroot/usr
   $ make
   $ make install
   (--prefix 는 안드로이드 툴체인이 있는 곳으로 설정해야하며, 하지 않을 경우 make install 시 /usr/local/include 와 /usr/local/lib에 header와 library가 위치해서 ffmpeg 빌드시에 libx264 header와 library를 찾지 못함)
   
6. 테스트는 안해봤지만 빌드는 잘됨.



7. FFMPEG 다운로드
  - 사이트: http://www.ffmpeg.org/
  - 다운로드: wget http://www.ffmpeg.org/releases/ffmpeg-0.8.2.tar.bz2
    (git 또는 svn을 이용해서도 다운로드 가능)

8. FFMPEG 빌드
  - 압축을 풀고 압축 푼 디렉토리로 이동
  - $./configure --enable-shared --enable-libx264 --cross-prefix=arm-linux-androideabi- --enable-cross-compile --target-os=linux --arch=arm --enable-gpl --prefix=/opt/android-8-toolchain/sysroot/usr
    (--prefix를 안드로이드 툴체인이 있는 곳으로 설정)
  (참고) 반드시 필요한 모듈만 선택하여 빌드
./configure --prefix=../ffmpeg_build \
        --enable-gpl \
        --enable-shared \
        --disable-doc \
        --disable-ffmpeg \
        --disable-ffplay \
        --disable-ffprobe \
        --disable-ffserver \
        --disable-avdevice \
        --disable-debug \
        --disable-network \
        --disable-protocols \
        --disable-devices \
        --disable-encoders \
        --disable-decoders \
        --disable-muxers \
        --disable-demuxers \
        --disable-parsers \
        --disable-bsfs \
        --disable-filters \
        --enable-encoder=h264 \
        --enable-libx264 \
        --extra-cflags=-U__STRICT_ANSI__ \
        --target-os=linux \
        --extra-cflags="-fno-short-enums" \
        --extra-ldflags="-mandroid -lm" \
        --enable-cross-compile  \
        --cross-prefix=arm-linux-androideabi- \
        --arch=arm
   $ make & make install

이상!! 아직 테스트는 못함..ㅋㅋ
Posted by 원자이

Doxygen 툴을 사용하여 RTF문서를 만든 후 문서를 열어보면 아래와 같은 문제가 발생한다.

1. 문서의 1페이지는 제목이 있어야 할 자리에 TITLE 문구만 있다.
2. 색인에 달린 모든 페이시 수는 pagenum 이라고 표시될 뿐이다.

해결책은??

1. 문서전체를 선택한다.(Ctrl + A)
2. 마우스 오른쪽 버튼 클릭
3. 필드 업데이트 클릭

이러면 이쁜문서가 되어 나온다..

MS Word 2010에서는 다른이름으로 저장하여 PDF로 사용할 수 도 있다.

Posted by 원자이

이제 두 사람은 비를 맞지 않으리라.
서로가 서로에게 지붕이 되어 줄 테니까.

이제 두 사람은 춥지 않으리라.
서로가 서로에게 따뜻함이 될 테니까.

이제 두 사람은 더 이상 외롭지 않으리라.
서로가 서로에게 동행이 될 테니까.

이제 두 사람은 두 개의 몸이지만
두 사람의 앞에는 오직 하나의 인생만이 있으리라.

이제 그대들의 집으로 들어가라.
함께 있는 날들 속으로 들어가라.

이 대지 위에서 그대들은
오랫동안 행복하리라.

Posted by 원자이
◀ PREV : [1] : [2] : [3] : [4] : [5] : ... [7] : NEXT ▶

BLOG main image
by 원자이

공지사항

카테고리

분류 전체보기 (70)
영어공부 연습장 (26)
밥벌이 (14)
그냥.. (6)
말씀묵상 (17)
찬양 (5)

최근에 받은 트랙백

글 보관함

달력

«   2012/01   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Total : 7,359
Today : 5 Yesterday : 6