videogen.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Generate a synthetic YUV video sequence suitable for codec testing.
  3. * NOTE: No floats are used to guarantee bitexact output.
  4. *
  5. * Copyright (c) 2002 Fabrice Bellard
  6. *
  7. * This file is part of FFmpeg.
  8. *
  9. * FFmpeg is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * FFmpeg is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with FFmpeg; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. #include <stdlib.h>
  24. #include <stdint.h>
  25. #include <stdio.h>
  26. #include "utils.c"
  27. static unsigned int myrnd(unsigned int *seed_ptr, int n)
  28. {
  29. unsigned int seed, val;
  30. seed = *seed_ptr;
  31. seed = (seed * 314159) + 1;
  32. if (n == 256) {
  33. val = seed >> 24;
  34. } else {
  35. val = seed % n;
  36. }
  37. *seed_ptr = seed;
  38. return val;
  39. }
  40. #define NOISE_X 10
  41. #define NOISE_Y 30
  42. #define NOISE_W 26
  43. #define FRAC_BITS 8
  44. #define FRAC_ONE (1 << FRAC_BITS)
  45. /* cosine approximate with 1-x^2 */
  46. static int int_cos(int a)
  47. {
  48. int v, neg;
  49. a = a & (FRAC_ONE - 1);
  50. if (a >= (FRAC_ONE / 2))
  51. a = FRAC_ONE - a;
  52. neg = 0;
  53. if (a > (FRAC_ONE / 4)) {
  54. neg = -1;
  55. a = (FRAC_ONE / 2) - a;
  56. }
  57. v = FRAC_ONE - ((a * a) >> 4);
  58. v = (v ^ neg) - neg;
  59. return v;
  60. }
  61. #define NB_OBJS 10
  62. typedef struct VObj {
  63. int x, y, w, h;
  64. int r, g, b;
  65. } VObj;
  66. static VObj objs[NB_OBJS];
  67. static unsigned int seed = 1;
  68. static void gen_image(int num, int w, int h)
  69. {
  70. int r, g, b, x, y, i, dx, dy, x1, y1;
  71. unsigned int seed1;
  72. if (num == 0) {
  73. for (i = 0; i < NB_OBJS; i++) {
  74. objs[i].x = myrnd(&seed, w);
  75. objs[i].y = myrnd(&seed, h);
  76. objs[i].w = myrnd(&seed, w / 4) + 10;
  77. objs[i].h = myrnd(&seed, h / 4) + 10;
  78. objs[i].r = myrnd(&seed, 256);
  79. objs[i].g = myrnd(&seed, 256);
  80. objs[i].b = myrnd(&seed, 256);
  81. }
  82. }
  83. /* first a moving background with gradients */
  84. /* test motion estimation */
  85. dx = int_cos(num * FRAC_ONE / 50) * 35;
  86. dy = int_cos(num * FRAC_ONE / 50 + FRAC_ONE / 10) * 30;
  87. for (y = 0; y < h; y++) {
  88. for (x = 0; x < w; x++) {
  89. x1 = (x << FRAC_BITS) + dx;
  90. y1 = (y << FRAC_BITS) + dy;
  91. r = ((y1 * 7) >> FRAC_BITS) & 0xff;
  92. g = (((x1 + y1) * 9) >> FRAC_BITS) & 0xff;
  93. b = ((x1 * 5) >> FRAC_BITS) & 0xff;
  94. put_pixel(x, y, r, g, b);
  95. }
  96. }
  97. /* then some noise with very high intensity to test saturation */
  98. seed1 = num;
  99. for (y = 0; y < NOISE_W; y++) {
  100. for (x = 0; x < NOISE_W; x++) {
  101. r = myrnd(&seed1, 256);
  102. g = myrnd(&seed1, 256);
  103. b = myrnd(&seed1, 256);
  104. put_pixel(x + NOISE_X, y + NOISE_Y, r, g, b);
  105. }
  106. }
  107. /* then moving objects */
  108. for (i = 0; i < NB_OBJS; i++) {
  109. VObj *p = &objs[i];
  110. seed1 = i;
  111. for (y = 0; y < p->h; y++) {
  112. for (x = 0; x < p->w; x++) {
  113. r = p->r;
  114. g = p->g;
  115. b = p->b;
  116. /* add a per object noise */
  117. r += myrnd(&seed1, 50);
  118. g += myrnd(&seed1, 50);
  119. b += myrnd(&seed1, 50);
  120. put_pixel(x + p->x, y + p->y, r, g, b);
  121. }
  122. }
  123. p->x += myrnd(&seed, 21) - 10;
  124. p->y += myrnd(&seed, 21) - 10;
  125. }
  126. }
  127. void print_help(const char* name)
  128. {
  129. printf("usage: %s file|dir [w=%i] [h=%i]\n"
  130. "generate a test video stream\n",
  131. name, DEFAULT_WIDTH, DEFAULT_HEIGHT);
  132. exit(1);
  133. }
  134. int main(int argc, char **argv)
  135. {
  136. int w, h, i;
  137. char buf[1024];
  138. int isdir = 0;
  139. if (argc < 2 || argc > 4) {
  140. print_help(argv[0]);
  141. }
  142. if (!freopen(argv[1], "wb", stdout))
  143. isdir = 1;
  144. w = DEFAULT_WIDTH;
  145. if(argc > 2) {
  146. w = atoi(argv[2]);
  147. if (w < 1) print_help(argv[0]);
  148. }
  149. h = DEFAULT_HEIGHT;
  150. if(argc > 3) {
  151. h = atoi(argv[3]);
  152. if (h < 1) print_help(argv[0]);
  153. }
  154. rgb_tab = malloc(w * h * 3);
  155. wrap = w * 3;
  156. width = w;
  157. height = h;
  158. for (i = 0; i < DEFAULT_NB_PICT; i++) {
  159. gen_image(i, w, h);
  160. if (isdir) {
  161. snprintf(buf, sizeof(buf), "%s%02d.pgm", argv[1], i);
  162. pgmyuv_save(buf, w, h, rgb_tab);
  163. } else {
  164. pgmyuv_save(NULL, w, h, rgb_tab);
  165. }
  166. }
  167. free(rgb_tab);
  168. return 0;
  169. }