Monday, February 08, 2010

Function pointers

Here is an example, we have a structure named Slice, the function like ‘get_direct_motion_vectors’ should really be put inside this structure. So we can use ‘Slice->get_direct_motion_vectors(…)’instead of just call that function. So put a function pointer inside the structure is a good one:

typedef struct slice
{
int picture_id;
void (*get_direct_motion_vectors) (Macroblock *currMB);
...
}Slice;

 

// Usage:

(*currSlice)->get_direct_motion_vector = Get_MV;

 

// where ‘Get_MV’ is defined in another .h file: mv_search.h
extern void Get_MV(Macroblock *currMB);

 

// and it is implemented in .c file: mv_search.c

void Get_MV(Macroblock *currMB) { . . .}


Monday, February 01, 2010

Garbage in C

p = malloc(...);
q = malloc(...);
/* free (p); */

p = q;


p points to one memory block and q points to another.

After q is assigned to p, both point the the second memory block. There are no pointers to the first block. This memory block cannot be accessible to program, it is called ‘garbage’. A program that leaves garbage behind has memory leak. C doesn’t have garbage collector.

You can use ‘free(p)’ to release the memory block that p points to.

After you released the memory block, if you attempt to access or modify this deallocated memory block, it causes undefined behavior.

Thursday, January 28, 2010

Trivia of Preprocessor

The preprocessor's role in the compilation process is:
C program -> (Preprocessor) -> modified C program -> (Compiler) -> Object code.
The preporcessor executes the directives and remove them in the process (make those lines empty), and replace the #define directives wherever they appeared later in the file.

Three types of preprocessing directives:
  1. Macro definition: #define, #undef
  2. File inclusion: #include
  3. Condition compilation: #if, #ifdef, #ifndef, #elif, #else, #endif. (others include #error, #line, #progma)
#undef N : removes the current definition of macro N. If N has not been defined, #undef has no effect. Usually this is used to give a new definition to existing macro.

Several predefined Macros:
  • __LINE__ : line number of file being compiled
  • __FILE__ : name of file being compiled
  • __DATA__ : mm dd yyyy
  • __TIME__ : hh:mm:ss
#if defined DEBUG // same as #if defined (DEBUG)
...
#endif
Since 'defined' tests only where DEBUG is defined or not, it is not necessary to give DEBUG a value. Just use: #define DEBUG

#ifdef DEBUG // equivalent to #if defined DEBUG
#endif

#ifndef DEBUG // equivalent to #if !defined DEBUG
-------------------
#ifdef WIN32
...
#elif defined MAC
...
#elif defined LINUX
...
#else
#error no operation system chosen
#end

Use following to condition out the block of codes:
#if 0
...
#endif
Reminder: those block of codes are not completely ignored. Comments are processed before preprocessing. If you have unterminated comments between #if 0, #endif, you still get compile error (like you have /*abcdefg ). Unpaired quote could give you a warning.

#error message : usually the compiler will terminate immediately without trying to find other errors
#if MAX < 10000
# // it is legal to use null directive
#error max value is too small
#
#endif

Wednesday, January 27, 2010

Debugging

Effective debugging requires: from book 'debug it!' by Paul Butcher
  1. work out why the application is behaving unexpectedly.
  2. fix the problem
  3. avoid breaking anything else
  4. maintain or improve the overall quality
  5. ensure the same problem does not occur elsewhere and cannot occur again
  6. checkin codes and get code review
The core debugging process steps are:
  1. Reproduce
  2. Diagnose
  3. Fix
  4. Reflect: learn the lessons from the bug, does it happen elsewhere?
Make sure you know 'what is happening' and 'what should be happening'. Work on only one problem, the simplest problem at a time.
Make only one change at a time and keep a record of what you have tried.
Bugs take priority.

For the performance bugs, you need to find the bottleneck with getting an accurate profiling.

Use 'assert' to let application debugs itself.

Monday, January 25, 2010

Cut, copy, and paste block in vi

cut: dd or 4dd, then paste with p or P
copy: yy or 4yy, then past with p

if you know the start line number and end line number (Ctrl+g):
:10,25y
then p to paste. (this is copy-paste, replace y with d to cut-paste)

or set marks in both start and end lines with ma, mb
:'a,'by
then p to paste

Thursday, January 21, 2010

Access folders in vmware linux from Mac

set up the vmware linux machine following former post.

In Mac, Finder –> Go –> Connect to Server …, input
smb://10.10.1.1/usr_ubuntu
to server address. Then input your_user_name and password.

In Mac Terminal, the linux directory is at:
/Volumes/usr_ubuntu/

Sunday, January 10, 2010

Run Length Encoding (RLE)

The same color pixels in one row (or column, zigzag) are coded with a counter and pixel value. For example, aaabccccccddeee is coded to 3a1b6c2d3e

That is lossless data compression. It works well if the pixel values are the same in large regions. If every two pixel values are different, the algorithm will double the data, instead of compression.

Saturday, January 09, 2010

JPEG

Basic BMP -> JPG process:
BMP -> YUV 420
YUV420 sampling. Using one 16x16 mcu, and six 8x8 DU: Y0,Y1,Y2,Y3,U,V
DCT to every DU
Quantize DU using table, zigzag scan
Huffman coding and get bits
Write bits to file
Y/U/V components of an image, which use fixed sampling factor 2x2 for Y (luminance), and 1x1 for U/V (chrominance). Using this sampling scheme, each pixel will only require 12 bit to record the color.

For each component, a DU (data unit) in JPEG represents a 8x8 byte matrix, by using huffman coding the zigzaged 64 FDCT coefficients;

By using the YUV12 sampling scheme, a MCU (minium coded unit) in JPEG represents a 16x16 (pixel) image block, by using 6 DUs in this sequence: YDU, YDU, YDU, YDU, UDU, VDU.

default quantization tables for luminance and chrominance
provided by "ISO/IEC 10918, 1993(e)" Annex K:

luminance quantization table:

16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99

chrominance quantization table:

17 18 24 47 99 99 99 99
18 21 26 66 99 99 99 99
24 26 56 99 99 99 99 99
47 66 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99

In quantise: where vector is raw data, qt is the table.
for(i = 0; i <>

Wednesday, January 06, 2010

New Year, New Post

Great~

Wednesday, December 30, 2009

Nyquist sampling theorem

To avoid aliasing, the sampling rate should be greater than twice the highest frequency present in the signal. fs >= 2*f

In frequency domain. If the sample rate (fs) is less than 2*f, aliasing will happen.

Nyquist_FreqDomain

In time domain: From following example, the sampling waveform has aliasing.
Nyquest_Time_Domain1

In following example, there is a white dot in the wheel. Assume a 24 fps film recording the wheel. When 24 < 2*13Hz, the wheel looks like it is going backward. 

Nyquest_Time_Domain2

Monday, December 14, 2009

Spectral Flux (SF) in Audio

Spectral flux measures how quickly the power spectrum changes. Spectral flux is defined as the variation value of spectrum between the adjacent two frames in a short-time analyze window. Spectral flux can be used to determine the timbre of an audio signal. The MATLAB code:

[wav fs] = wavread('DEMO.wav');
wav = wav / max(max(wav));
window_length = 2 * fs; % assume the windows is 2 seconds
step = 1 * fs;          % and it has overlap in windows
frame_num = floor((length(wav)-window_length)/step) + 1;

H = hamming(window_length);
flux = zeros(frame_num, 1);
pos = 1;
FFT_prev = 0;

for i=1:frame_num
wav_window = H .* wav(pos:pos + window_length-1);
FFT = abs(fft(wav_window, 2*window_length));
FFT = FFT(1 : window_length);
FFT = FFT/max(FFT);

flux(i) = sum((FFT - FFT_prev) .^ 2);
FFT_prev = FFT;
pos = pos + step;
end