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