gen_pat.c 5.54 KB
Newer Older
1 2 3
/*****************************************************************************
 * gen_pat.c: PAT generator
 *----------------------------------------------------------------------------
4
 * Copyright (C) 2001-2011 VideoLAN
5
 * $Id: gen_pat.c,v 1.3 2002/10/07 14:15:14 sam Exp $
6 7 8
 *
 * Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
 *
9 10 11 12
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
18
 *
19 20 21
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 23 24 25 26 27 28 29 30
 *
 *----------------------------------------------------------------------------
 *
 *****************************************************************************/


#include "config.h"

#include <stdio.h>
31
#include <stdbool.h>
32

33 34 35 36 37 38
#if defined(HAVE_INTTYPES_H)
#include <inttypes.h>
#elif defined(HAVE_STDINT_H)
#include <stdint.h>
#endif

39 40 41 42
/* the libdvbpsi distribution defines DVBPSI_DIST */
#ifdef DVBPSI_DIST
#include "../src/dvbpsi.h"
#include "../src/psi.h"
43
#include "../src/tables/pat.h"
44 45 46 47 48 49 50 51 52
#else
#include <dvbpsi/dvbpsi.h>
#include <dvbpsi/psi.h>
#include <dvbpsi/pat.h>
#endif

/*****************************************************************************
 * writePSI
 *****************************************************************************/
53
static void writePSI(uint8_t* p_packet, dvbpsi_psi_section_t* p_section)
54 55 56 57 58
{
  p_packet[0] = 0x47;

  while(p_section)
  {
59
    size_t i_bytes_written = 0;
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    uint8_t* p_pos_in_ts;
    uint8_t* p_byte = p_section->p_data;
    uint8_t* p_end =   p_section->p_payload_end
                     + (p_section->b_syntax_indicator ? 4 : 0);

    p_packet[1] |= 0x40;
    p_packet[3] = (p_packet[3] & 0x0f) | 0x10;

    p_packet[4] = 0x00; /* pointer_field */
    p_pos_in_ts = p_packet + 5;

    while((p_pos_in_ts < p_packet + 188) && (p_byte < p_end))
      *(p_pos_in_ts++) = *(p_byte++);
    while(p_pos_in_ts < p_packet + 188)
      *(p_pos_in_ts++) = 0xff;
75 76 77 78 79 80
    i_bytes_written = fwrite(p_packet, 1, 188, stdout);
    if(i_bytes_written == 0)
    {
      fprintf(stderr,"eof detected ... aborting\n");
      return;
    }
81 82 83 84 85 86 87 88 89 90 91 92 93
    p_packet[3] = (p_packet[3] + 1) & 0x0f;

    while(p_byte < p_end)
    {
      p_packet[1] &= 0xbf;
      p_packet[3] = (p_packet[3] & 0x0f) | 0x10;

      p_pos_in_ts = p_packet + 4;

      while((p_pos_in_ts < p_packet + 188) && (p_byte < p_end))
        *(p_pos_in_ts++) = *(p_byte++);
      while(p_pos_in_ts < p_packet + 188)
        *(p_pos_in_ts++) = 0xff;
94 95 96 97 98 99
      i_bytes_written = fwrite(p_packet, 1, 188, stdout);
      if(i_bytes_written == 0)
      {
        fprintf(stderr,"eof detected ... aborting\n");
        return;
      }
100 101 102 103 104 105 106
      p_packet[3] = (p_packet[3] + 1) & 0x0f;
    }

    p_section = p_section->p_next;
  }
}

107
static void message(dvbpsi_t *handle, const dvbpsi_msg_level_t level, const char* msg)
108
{
109 110 111 112 113 114 115 116 117
    switch(level)
    {
        case DVBPSI_MSG_ERROR: fprintf(stderr, "Error: "); break;
        case DVBPSI_MSG_WARN:  fprintf(stderr, "Warning: "); break;
        case DVBPSI_MSG_DEBUG: fprintf(stderr, "Debug: "); break;
        default: /* do nothing */
            return;
    }
    fprintf(stderr, "%s\n", msg);
118
}
119 120 121 122 123 124 125 126 127 128 129 130 131

/*****************************************************************************
 * main
 *****************************************************************************/
int main(int i_argc, char* pa_argv[])
{
  uint8_t packet[188];
  dvbpsi_pat_t pat;
  dvbpsi_psi_section_t* p_section1, * p_section2;
  dvbpsi_psi_section_t* p_section3, * p_section4;
  dvbpsi_psi_section_t* p_section5, * p_section6;
  int i;

132
  dvbpsi_t *p_dvbpsi = dvbpsi_new(&message, DVBPSI_MSG_DEBUG);
133 134 135
  if (p_dvbpsi == NULL)
      return 1;

136
  /* PAT generation */
137 138 139 140 141
  dvbpsi_pat_init(&pat, 1, 0, 0);
  dvbpsi_pat_program_add(&pat, 0, 0x12);
  dvbpsi_pat_program_add(&pat, 1, 0x42);
  dvbpsi_pat_program_add(&pat, 2, 0x21);
  dvbpsi_pat_program_add(&pat, 3, 0x24);
142
  for(i = 4; i < 43; i++)
143
    dvbpsi_pat_program_add(&pat, i, i);
144

145
  p_section1 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 4);
146
  pat.b_current_next = 1;
147
  p_section2 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 8);
148 149 150 151

  pat.i_version = 1;

  pat.b_current_next = 0;
152
  p_section3 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 16);
153
  pat.b_current_next = 1;
154
  p_section4 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 300);
155 156 157 158

  pat.i_version = 2;

  pat.b_current_next = 0;
159
  p_section5 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 16);
160
  pat.b_current_next = 1;
161
  p_section6 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 16);
162 163 164 165 166 167 168 169 170 171 172 173 174

  /* TS packets generation */
  packet[0] = 0x47;
  packet[1] = packet[2] = 0x00;
  packet[3] = 0x00;

  writePSI(packet, p_section1);
  writePSI(packet, p_section2);
  writePSI(packet, p_section3);
  writePSI(packet, p_section4);
  writePSI(packet, p_section5);
  writePSI(packet, p_section6);

175 176 177 178 179 180
  dvbpsi_DeletePSISections(p_section1);
  dvbpsi_DeletePSISections(p_section2);
  dvbpsi_DeletePSISections(p_section3);
  dvbpsi_DeletePSISections(p_section4);
  dvbpsi_DeletePSISections(p_section5);
  dvbpsi_DeletePSISections(p_section6);
181

182
  dvbpsi_pat_empty(&pat);
183

184
  dvbpsi_delete(p_dvbpsi);
185 186 187
  return 0;
}