00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #undef NDEBUG
00038 #include <assert.h>
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <unistd.h>
00043
00044 #include <libzvbi.h>
00045
00046 static vbi_dvb_demux * dvb;
00047 static uint8_t pes_buffer[2048];
00048 static vbi_sampling_par sp;
00049 static uint8_t * image;
00050 static unsigned int image_size;
00051 static unsigned int pixel_mask;
00052 static int64_t last_pts;
00053 static vbi_raw_decoder rd;
00054
00055 static void
00056 raw_test (const vbi_sliced * expect_sliced,
00057 unsigned int expect_n_lines)
00058 {
00059 vbi_sliced sliced[50];
00060 unsigned int n_lines;
00061 unsigned int i;
00062
00063 n_lines = vbi_raw_decode (&rd, image, sliced);
00064 assert (n_lines == expect_n_lines);
00065
00066 for (i = 0; i < n_lines; ++i) {
00067 unsigned int payload;
00068
00069 assert (sliced[i].id == expect_sliced[i].id);
00070 assert (sliced[i].line == expect_sliced[i].line);
00071
00072 payload = (vbi_sliced_payload_bits (sliced[i].id) + 7) / 8;
00073 assert (0 == memcmp (sliced[i].data,
00074 expect_sliced[i].data,
00075 payload));
00076 }
00077 }
00078
00079 static vbi_bool
00080 convert (vbi_dvb_demux * dx,
00081 void * user_data,
00082 const vbi_sliced * sliced,
00083 unsigned int n_lines,
00084 int64_t pts)
00085 {
00086 vbi_bool success;
00087 ssize_t actual;
00088
00089 dx = dx;
00090 user_data = user_data;
00091
00092 pts &= ((int64_t) 1 << 33) - 1;
00093
00094
00095 if (0 == last_pts) {
00096 last_pts = pts;
00097 } else if (pts < last_pts) {
00098 last_pts -= (int64_t) 1 << 33;
00099 }
00100
00101 while (pts - last_pts > 90000 / 25 * 3 / 2) {
00102
00103
00104 success = vbi_raw_video_image (image, image_size, &sp,
00105 0, 0, 0, pixel_mask, FALSE,
00106 NULL, 0);
00107 assert (success);
00108
00109 raw_test (NULL, 0);
00110
00111 actual = write (STDOUT_FILENO, image, image_size);
00112 assert (actual == (ssize_t) image_size);
00113
00114 last_pts += 90000 / 25;
00115 }
00116
00117 success = vbi_raw_video_image (image, image_size, &sp,
00118 0,
00119 0,
00120 0,
00121 pixel_mask,
00122 FALSE,
00123 sliced, n_lines);
00124 assert (success);
00125
00126 raw_test (sliced, n_lines);
00127
00128 actual = write (STDOUT_FILENO, image, image_size);
00129 assert (actual == (ssize_t) image_size);
00130
00131 last_pts = pts;
00132
00133 return TRUE;
00134 }
00135
00136 static void
00137 mainloop (void)
00138 {
00139 while (1 == fread (pes_buffer, sizeof (pes_buffer), 1, stdin)) {
00140 vbi_bool success;
00141
00142 success = vbi_dvb_demux_feed (dvb,
00143 pes_buffer,
00144 sizeof (pes_buffer));
00145 assert (success);
00146 }
00147
00148 fprintf (stderr, "End of stream.\n");
00149 }
00150
00151 int
00152 main (void)
00153 {
00154 if (isatty (STDIN_FILENO)) {
00155 fprintf (stderr, "No DVB PES on standard input.\n");
00156 exit (EXIT_FAILURE);
00157 }
00158
00159 if (isatty (STDOUT_FILENO)) {
00160 fprintf (stderr, "Output is binary image data. Pipe to "
00161 "another tool or redirect to a file.\n");
00162 exit (EXIT_FAILURE);
00163 }
00164
00165
00166 vbi_set_log_fn ((VBI_LOG_NOTICE |
00167 VBI_LOG_WARNING |
00168 VBI_LOG_ERROR),
00169 vbi_log_on_stderr,
00170 NULL);
00171
00172 dvb = vbi_dvb_pes_demux_new (convert, NULL);
00173 assert (NULL != dvb);
00174
00175 memset (&sp, 0, sizeof (sp));
00176
00177 #if 1
00178
00179
00180 sp.scanning = 625;
00181 sp.sampling_format = VBI_PIXFMT_YUYV;
00182 sp.sampling_rate = 13.5e6;
00183 sp.bytes_per_line = 720 * 2;
00184 sp.offset = 9.5e-6 * 13.5e6;
00185 sp.start[0] = 6;
00186 sp.count[0] = 17;
00187 sp.start[1] = 319;
00188 sp.count[1] = 17;
00189 sp.interlaced = TRUE;
00190 sp.synchronous = TRUE;
00191
00192
00193 pixel_mask = 0x000000FF;
00194 #else
00195
00196
00197 sp.scanning = 625;
00198 sp.sampling_format = VBI_PIXFMT_BGRA32_LE;
00199 sp.sampling_rate = 14.75e6;
00200 sp.bytes_per_line = 768 * 4;
00201 sp.offset = 10.2e-6 * 14.75e6;
00202 sp.start[0] = 6;
00203 sp.count[0] = 17;
00204 sp.start[1] = 319;
00205 sp.count[1] = 17;
00206 sp.interlaced = TRUE;
00207 sp.synchronous = TRUE;
00208
00209 pixel_mask = 0x0000FF00;
00210 #endif
00211
00212 image_size = (sp.count[0] + sp.count[1]) * sp.bytes_per_line;
00213 image = malloc (image_size);
00214 assert (NULL != image);
00215
00216 if (VBI_PIXFMT_YUYV == sp.sampling_format) {
00217
00218 memset (image, 0x80, image_size);
00219 } else {
00220 memset (image, 0x00, image_size);
00221 }
00222
00223
00224
00225
00226 vbi_raw_decoder_init (&rd);
00227
00228 rd.scanning = sp.scanning;
00229 rd.sampling_format = sp.sampling_format;
00230 rd.sampling_rate = sp.sampling_rate;
00231 rd.bytes_per_line = sp.bytes_per_line;
00232 rd.offset = sp.offset;
00233 rd.start[0] = sp.start[0];
00234 rd.start[1] = sp.start[1];
00235 rd.count[0] = sp.count[0];
00236 rd.count[1] = sp.count[1];
00237 rd.interlaced = sp.interlaced;
00238 rd.synchronous = sp.synchronous;
00239
00240
00241
00242
00243 vbi_raw_decoder_add_services (&rd,
00244 (VBI_SLICED_TELETEXT_B |
00245 VBI_SLICED_VPS |
00246 VBI_SLICED_CAPTION_625),
00247 0);
00248
00249 mainloop ();
00250
00251 vbi_dvb_demux_delete (dvb);
00252
00253 exit (EXIT_SUCCESS);
00254
00255 return 0;
00256 }