README.hm12 4.0 KB

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