2012年8月6日 星期一

OpenCV 2.4.2 V4L2 Camera resolution bug fix

When using camera with opencv api, the default camera resolution is ALWAYS 160x120
From source code modules/highgui/src/cap_libv4l.cpp the default resolution should be 640x480

/* Defaults - If your board can do better, set it here.  Set for the most common type inputs. */
#define DEFAULT_V4L_WIDTH  640
#define DEFAULT_V4L_HEIGHT 480

I have study a little bit of modules/highgui/src/cap_libv4l.cpp then I found the problem.

   CvCaptureCAM_V4L * capture = (CvCaptureCAM_V4L*)cvAlloc(sizeof(CvCaptureCAM_V4L));
   if (!capture) {
      fprintf( stderr, "HIGHGUI ERROR: V4L: Could not allocate memory for capture process.\n");
      return NULL;
   }

   /* set the default size */
   capture->width  = DEFAULT_V4L_WIDTH;
   capture->height = DEFAULT_V4L_HEIGHT;

...
...

   /* w/o memset some parts  arent initialized - AKA: Fill it with zeros so it is clean */
   memset(capture,0,sizeof(CvCaptureCAM_V4L));

   /* Present the routines needed for V4L funtionality.  They are inserted as part of
      the standard set of cv calls promoting transparency.  "Vector Table" insertion. */
   capture->FirstCapture = 1;

   if (_capture_V4L2 (capture, deviceName) == -1) {

The memset instruction is called after setting width & height. @@

So, just move up memset behind alloc memory.

--- modules/highgui/src/cap_libv4l.cpp.org    2012-08-06 19:28:58.746347834 +0800
+++ modules/highgui/src/cap_libv4l.cpp    2012-08-06 19:29:42.510348966 +0800
@@ -1007,6 +1007,9 @@
       return NULL;
    }
 
+   /* w/o memset some parts  arent initialized - AKA: Fill it with zeros so it is clean */
+   memset(capture,0,sizeof(CvCaptureCAM_V4L));
+
    /* set the default size */
    capture->width  = DEFAULT_V4L_WIDTH;
    capture->height = DEFAULT_V4L_HEIGHT;
@@ -1028,8 +1031,6 @@
    /* Print the CameraNumber at the end of the string with a width of one character */
    sprintf(deviceName, "/dev/video%1d", index);
 
-   /* w/o memset some parts  arent initialized - AKA: Fill it with zeros so it is clean */
-   memset(capture,0,sizeof(CvCaptureCAM_V4L));
    /* Present the routines needed for V4L funtionality.  They are inserted as part of
       the standard set of cv calls promoting transparency.  "Vector Table" insertion. */
    capture->FirstCapture = 1;



2012年7月22日 星期日

Ubuntu 12.04 stutter sound

The stuttering sound while playing mp3 or video bother me for a while.
After some googling I found solution

1.Edit
/etc/pulse/client.conf

from

; extra-arguments = --log-target=syslog

to

; extra-arguments = --log-target=syslog --resample-method=ffmpeg

2.Edit
/etc/modprobe.d/alsa-base.conf

Add

options snd-hda-intel model=generic

3.reboot

2012年5月29日 星期二

S3C6410 MFC H.264 mp4 player (Bug fix)

In the previous post, I implement an mp4 player.
There's a problem confuse me.
The start of video frame seems broken. Then after some time (maybe seconds) the video frame goes well.

Finally, I found a way to solve it.
Just to decode the first frame twice. Really strange but work. Also there's some minor fix included

https://docs.google.com/open?id=0Bx901QMLr9WlVE1ldHVCaERkRkk

Patch

--- /home/gigijoe/mp4player.c    2012-05-29 16:11:06.094007930 +0800
+++ mp4player.c    2012-05-29 16:17:55.073995127 +0800
@@ -176,8 +176,12 @@
     pp_param.dst_width              = pp_param.dst_full_width;
     pp_param.dst_height             = pp_param.dst_full_height;
     pp_param.dst_color_space        = FB0_COLOR_SPACE;
+#if 1
     pp_param.out_path               = DMA_ONESHOT;
-
+#else
+        pp_param.out_path           = FIFO_FREERUN;
+        pp_param.scan_mode            = PROGRESSIVE_MODE;
+#endif
     ioctl(pp_fd, S3C_PP_SET_PARAMS, &pp_param);
     printf("stream width %d, height %d\n", pp_param.src_full_width, pp_param.src_full_height);
 
@@ -193,7 +197,7 @@
       return -1;
     }
 
-    memset(fb_addr, 0, fb_size);
+    //memset(fb_addr, 0, fb_size);
 
     s3c_win_info_t osd_info_to_driver;
     osd_info_to_driver.Bpp          = FB0_BPP;      // RGB16
@@ -212,6 +216,13 @@
     initialize = 1;
 
     //return 0;
+/*
+* Decode first frame again to avoid problem ...
+*/
+    if(SsbSipH264DecodeExe(handle, len) != SSBSIP_H264_DEC_RET_OK)  {
+      printf("MFC Decoder Configuration Failed.\n");
+      return -1;
+    }
   }
 
   unsigned int pYUVBuf[2];
@@ -229,6 +240,12 @@
   ioctl(fb_fd, FBIOGET_FSCREENINFO, &lcd_info);
   pp_param.dst_buf_addr_phy = lcd_info.smem_start;                  // LCD frame buffer
   ioctl(pp_fd, S3C_PP_SET_DST_BUF_ADDR_PHY, &pp_param);
+
+  struct pollfd test_fd;
+  test_fd.fd = pp_fd;
+  test_fd.events = POLLOUT|POLLERR;
+  poll(&test_fd, 1, 3000);
+
   ioctl(pp_fd, S3C_PP_START);
 
   return 0;
@@ -342,12 +359,15 @@
   AVCodecContext *codecContext = is->codec;
 
   long long delay = (1000000 * is->r_frame_rate.den) / (is->r_frame_rate.num);
-
-#if 0
+#if 1
   i = 0;
 #endif
   while(1)  {
     r = av_read_frame(formatContext, &pkt);
+    if(r != 0)  { /*  No more frame, seek head and replay */
+      av_seek_frame(formatContext, 0, 1, AVSEEK_FLAG_BACKWARD);
+      r = av_read_frame(formatContext, &pkt);
+    }
     if(r != 0)
       break;  /*  No more frame */
 
@@ -367,11 +387,16 @@
         i, pkt.stream_index, pkt.dts, pkt.size, pkt.data);
     av_pkt_dump(stdout, &pkt, 0);
 #endif
+    if(pkt.flags & PKT_FLAG_KEY)
+      printf("Key frame %d\n", i);
 
     unsigned char *lp = 0;
     int len = 0;
-    filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags | PKT_FLAG_KEY));
-
+ //   filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags | PKT_FLAG_KEY));
+    r = filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags));
+    if(r != 1)
+      printf("Frame %d : Fail to filter ...\n", i);
+//printf("Frame %d: %d\n", pkt.stream_index, len);
     decode_mfc(lp, len);
 
     av_free_packet(&pkt);
@@ -393,7 +418,7 @@
       } else
         break;
     }
-#if 0
+#if 1
     i++;
 #endif
   }
@@ -403,6 +428,10 @@
 
   avcodec_close(is->codec);
 
+  munmap(fb_addr, fb_size);
+    close(pp_fd);
+    close(fb_fd);
+
   deinit_mfc();
 
   return 0;


2012年4月10日 星期二

S3C6410 MFC H.264 mp4 player

S3C6410 can do hardware video decode including H.264.
There's an example code from Samsung shows how to hardware decode H.264 raw data, but in the real world application this is not so useful.
Decode & Playing H.264 mp4 file is more reality. So I would like to share the implementation.

I use ffmpeg library to decode mp4 mux in order to get H.264 raw data and then send it to S3C6410 MFC to decode and finally play on the LCD panel.

Requirement
ffmpeg-0.6.1
Samsung FIMV_MFC_V1.0

Source code
https://docs.google.com/open?id=0Bx901QMLr9WlTTR1a0ZKaXVobW8

The most important part is to handle data from

  av_read_frame(formatContext, &pkt);

if you pass pkt.data to decode you got fail to decode. Another filter is required.

  typedef struct H264BSFContext {
    uint8_t  length_size;
    uint8_t  first_idr;
    uint8_t *sps_pps_data;
    uint32_t size;
  } H264BSFContext;

  AVBitStreamFilterContext *filterContext = (AVBitStreamFilterContext *)malloc(sizeof(AVBitStreamFilterContext));
  filterContext->priv_data = (H264BSFContext *)malloc(sizeof(H264BSFContext));
  memset(filterContext->priv_data, 0, sizeof(H264BSFContext));
  filterContext->filter = &h264_mp4toannexb_bsf;
  filterContext->parser = 0;
  filterContext->next = 0;
...
  r = av_read_frame(formatContext, &pkt);
...
    unsigned char *lp = 0;
    int len = 0;
    filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags | PKT_FLAG_KEY)); -->> filter here

    decode_mfc(lp, len);




2012年3月6日 星期二

Ubuntu Intel I5-2500K & Z68 chipset

上次組裝電腦已經是6~7年前的事了,昨天終於下定決心把公司那台半古董桌機換下來,一方面增加工作效率也讓已經逐漸老化的硬碟退休.
之前已經在網路上研究了配備一陣子,主要還是與Ubuntu的相容性要好.最後定案的配備如下

Intel I5-2500K (有K的表示可超頻,貴幾百吧)
ASRock Z68 PRO3 GEN3 (這張Ubuntu直上,還有一個COM port,重點是便宜啊)
Kongston 4GB DDR3-1333 x 2 (共8G memory,這在十年前簡直是無法想像)
Seagate SATA3 1T ST1000DM003
CM Hyper 212 PLUS 塔型散熱器 (CPU不怕著涼的,裝大顆一點就對了)
振華400W power

裝好搬回來後直接裝Ubuntu 11.10,一路順暢都沒有什麼問題.
我最擔心的Intel HD 3000 graphic controller也能正常工作,Perfect

接著是一些監控系統資訊的方式
1.CPU 溫度

modprobe coretemp
sensors

gigijoe@gigijoe-i5-2500k:~$ sensors
coretemp-isa-0000
Adapter: ISA adapter
Physical id 0:  +31.0°C  (high = +80.0°C, crit = +98.0°C)
Core 0:         +25.0°C  (high = +80.0°C, crit = +98.0°C)
Core 1:         +29.0°C  (high = +80.0°C, crit = +98.0°C)
Core 2:         +26.0°C  (high = +80.0°C, crit = +98.0°C)
Core 3:         +30.0°C  (high = +80.0°C, crit = +98.0°C)

2.硬體資訊
sudo lshw

3.CPU 超頻
現在的超頻很容易,直接在BIOS內用懶人設定選取希望的頻率即可.
3.3G -> 4.6G還蠻穩定的,CPU溫度只稍微上升.

在linux環境下cat /pro/cpuinfo會發現超頻之後的CPU clock一樣顯示是3.3G.
嗯,經過一番google後先試著用wine 跑 CPU-z這個Windows上廣泛使用的程式...失敗.
最後正解是一隻叫i7z的程式 http://code.google.com/p/i7z/


Cpu speed from cpuinfo 3292.00Mhz
cpuinfo might be wrong if cpufreq is enabled. To guess correctly try estimating
Linux's inbuilt cpu_khz code emulated now
True Frequency (without accounting Turbo) 3292 MHz
  CPU Multiplier 33x || Bus clock frequency (BCLK) 99.76 MHz

Socket [0] - [physical cores=4, logical cores=4, max online cores ever=4]
  TURBO ENABLED on 4 Cores, Hyper Threading OFF
  True Frequency 3391.76 MHz (99.76 x [34])
  Max TURBO Multiplier (if Enabled) with 1/2/3/4 Cores is  60x/60x/60x/60x
  Current Frequency 1793.89 MHz [99.76 x 17.98] (Max of below)
        Core [core-id]  :Actual Freq (Mult.)      C0%   Halt(C1)%  C3 %   C6 %
        Core 1 [0]:       1793.89 (17.98x)      38.2    38.7     9.4    31.1
        Core 2 [1]:       1655.03 (16.59x)      9.69    13.6    5.07    76.5
        Core 3 [2]:       1657.92 (16.62x)      2.77    2.38     1.3    94.9
        Core 4 [3]:       1618.08 (16.22x)         1    0.747      0    98.9



C0 = Processor running without halting
C1 = Processor running with halts (States >C0 are power saver)
C3 = Cores running with PLL turned off and core cache turned off
C6 = Everything in C3 + core state saved to last level cache
  Above values in table are in percentage over the last 1 sec

3.還有一個小問題是boot會卡在Checking Battery State.
按Ctrl+Alt+F1進 console login.
sudo apt-get install gdm
安裝過程中選lightdm

或是
sudo dpkg-reconfigure gdm

然後reboot就解決囉