linux/Documentation/video4linux/cx2341x/README.hm12
<<
>>
Prefs
   1The cx23416 can produce (and the cx23415 can also read) raw YUV output. The
   2format of a YUV frame is specific to this chip and is called HM12. 'HM' stands
   3for 'Hauppauge Macroblock', which is a misnomer as 'Conexant Macroblock' would
   4be more accurate.
   5
   6The format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per
   7four pixels.
   8
   9The data is encoded as two macroblock planes, the first containing the Y
  10values, the second containing UV macroblocks.
  11
  12The Y plane is divided into blocks of 16x16 pixels from left to right
  13and from top to bottom. Each block is transmitted in turn, line-by-line.
  14
  15So the first 16 bytes are the first line of the top-left block, the
  16second 16 bytes are the second line of the top-left block, etc. After
  17transmitting this block the first line of the block on the right to the
  18first block is transmitted, etc.
  19
  20The UV plane is divided into blocks of 16x8 UV values going from left
  21to right, top to bottom. Each block is transmitted in turn, line-by-line.
  22
  23So the first 16 bytes are the first line of the top-left block and
  24contain 8 UV value pairs (16 bytes in total). The second 16 bytes are the
  25second line of 8 UV pairs of the top-left block, etc. After transmitting
  26this block the first line of the block on the right to the first block is
  27transmitted, etc.
  28
  29The code below is given as an example on how to convert HM12 to separate
  30Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels.
  31
  32The width of a frame is always 720 pixels, regardless of the actual specified
  33width.
  34
  35If the height is not a multiple of 32 lines, then the captured video is
  36missing macroblocks at the end and is unusable. So the height must be a
  37multiple of 32.
  38
  39--------------------------------------------------------------------------
  40
  41#include <stdio.h>
  42#include <stdlib.h>
  43#include <string.h>
  44
  45static unsigned char frame[576*720*3/2];
  46static unsigned char framey[576*720];
  47static unsigned char frameu[576*720 / 4];
  48static unsigned char framev[576*720 / 4];
  49
  50static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h)
  51{
  52    unsigned int y, x, i;
  53
  54    // descramble Y plane
  55    // dstride = 720 = w
  56    // The Y plane is divided into blocks of 16x16 pixels
  57    // Each block in transmitted in turn, line-by-line.
  58    for (y = 0; y < h; y += 16) {
  59        for (x = 0; x < w; x += 16) {
  60            for (i = 0; i < 16; i++) {
  61                memcpy(dst + x + (y + i) * dstride, src, 16);
  62                src += 16;
  63            }
  64        }
  65    }
  66}
  67
  68static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h)
  69{
  70    unsigned int y, x, i;
  71
  72    // descramble U/V plane
  73    // dstride = 720 / 2 = w
  74    // The U/V values are interlaced (UVUV...).
  75    // Again, the UV plane is divided into blocks of 16x16 UV values.
  76    // Each block in transmitted in turn, line-by-line.
  77    for (y = 0; y < h; y += 16) {
  78        for (x = 0; x < w; x += 8) {
  79            for (i = 0; i < 16; i++) {
  80                int idx = x + (y + i) * dstride;
  81
  82                dstu[idx+0] = src[0];  dstv[idx+0] = src[1];
  83                dstu[idx+1] = src[2];  dstv[idx+1] = src[3];
  84                dstu[idx+2] = src[4];  dstv[idx+2] = src[5];
  85                dstu[idx+3] = src[6];  dstv[idx+3] = src[7];
  86                dstu[idx+4] = src[8];  dstv[idx+4] = src[9];
  87                dstu[idx+5] = src[10]; dstv[idx+5] = src[11];
  88                dstu[idx+6] = src[12]; dstv[idx+6] = src[13];
  89                dstu[idx+7] = src[14]; dstv[idx+7] = src[15];
  90                src += 16;
  91            }
  92        }
  93    }
  94}
  95
  96/*************************************************************************/
  97int main(int argc, char **argv)
  98{
  99    FILE *fin;
 100    int i;
 101
 102    if (argc == 1) fin = stdin;
 103    else fin = fopen(argv[1], "r");
 104
 105    if (fin == NULL) {
 106        fprintf(stderr, "cannot open input\n");
 107        exit(-1);
 108    }
 109    while (fread(frame, sizeof(frame), 1, fin) == 1) {
 110        de_macro_y(framey, frame, 720, 720, 576);
 111        de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2);
 112        fwrite(framey, sizeof(framey), 1, stdout);
 113        fwrite(framev, sizeof(framev), 1, stdout);
 114        fwrite(frameu, sizeof(frameu), 1, stdout);
 115    }
 116    fclose(fin);
 117    return 0;
 118}
 119
 120--------------------------------------------------------------------------
 121