examples/rawout.c

Raw VBI output example.

00001 /*
00002  *  libzvbi raw VBI output example
00003  *
00004  *  Copyright (C) 2006 Michael H. Schimek
00005  *
00006  *  Redistribution and use in source and binary forms, with or without
00007  *  modification, are permitted provided that the following conditions
00008  *  are met:
00009  *  1. Redistributions of source code must retain the above copyright
00010  *     notice, this list of conditions and the following disclaimer.
00011  *  2. Redistributions in binary form must reproduce the above copyright
00012  *     notice, this list of conditions and the following disclaimer in
00013  *     the documentation and/or other materials provided with the
00014  *     distribution.
00015  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00016  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00017  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00018  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00019  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00021  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00022  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00023  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 
00028 /* $Id: rawout.c,v 1.8 2008/02/19 00:52:04 mschimek Exp $ */
00029 
00030 /* This example shows how to convert VBI data in a DVB PES stream
00031    to raw VBI data.
00032 
00033    gcc -o rawout rawout.c `pkg-config zvbi-0.2 --cflags --libs`
00034 
00035    ./rawout <pes | mplayer - -rawvideo on:w=720:h=34:format=0x32595559 */
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; /* unused */
00090         user_data = user_data;
00091 
00092         pts &= ((int64_t) 1 << 33) - 1;
00093 
00094         /* Handle PTS wrap-around. */
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                 /* No data for this frame. */
00103 
00104                 success = vbi_raw_video_image (image, image_size, &sp,
00105                                                0, 0, 0, pixel_mask, FALSE,
00106                                                NULL, /* n_lines */ 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                                        /* blank_level: default */ 0,
00119                                        /* black_level: default */ 0,
00120                                        /* white_level: default */ 0,
00121                                        pixel_mask,
00122                                        /* swap_fields */ 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; /* success */
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         /* Helps debugging. */
00166         vbi_set_log_fn ((VBI_LOG_NOTICE |
00167                          VBI_LOG_WARNING |
00168                          VBI_LOG_ERROR),
00169                         vbi_log_on_stderr,
00170                         /* user_data */ NULL);
00171 
00172         dvb = vbi_dvb_pes_demux_new (convert, /* user_data */ NULL);
00173         assert (NULL != dvb);
00174 
00175         memset (&sp, 0, sizeof (sp));
00176 
00177 #if 1
00178         /* ITU BT.601 YUYV. */
00179 
00180         sp.scanning             = 625; /* PAL/SECAM */
00181         sp.sampling_format      = VBI_PIXFMT_YUYV;
00182         sp.sampling_rate        = 13.5e6;
00183         sp.bytes_per_line       = 720 * 2; /* 2 bpp */
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         /* Other bytes are left unmodified. */
00193         pixel_mask              = 0x000000FF; /* 0xAAVVUUYY */
00194 #else
00195         /* PAL square pixels BGRA32. */
00196 
00197         sp.scanning             = 625; /* PAL/SECAM */
00198         sp.sampling_format      = VBI_PIXFMT_BGRA32_LE;
00199         sp.sampling_rate        = 14.75e6;
00200         sp.bytes_per_line       = 768 * 4; /* 4 bpp */
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; /* 0xAABBGGRR */
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                 /* Reset Cb/Cr bytes. */
00218                 memset (image, 0x80, image_size);
00219         } else {
00220                 memset (image, 0x00, image_size);
00221         }
00222 
00223         /* To verify the generated raw VBI data we feed it back
00224            into a decoder and compare the sliced VBI data. */
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         /* Strict 0 because the function would consider the
00241            square pixel timing too tight to reliably decode
00242            Teletext. */
00243         vbi_raw_decoder_add_services (&rd,
00244                                       (VBI_SLICED_TELETEXT_B |
00245                                        VBI_SLICED_VPS |
00246                                        VBI_SLICED_CAPTION_625),
00247                                       /* strict */ 0);
00248 
00249         mainloop ();
00250 
00251         vbi_dvb_demux_delete (dvb);
00252 
00253         exit (EXIT_SUCCESS);
00254 
00255         return 0;
00256 }

Generated on Sun Jul 27 16:57:44 2008 for ZVBI Library by  doxygen 1.4.7