summaryrefslogtreecommitdiff
path: root/server/iso11172-1.h
blob: 48c77267ba62f050ad54b1b55b2f6f359a9770bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
 *            iso11172-1.h
 *
 *  Wed Aug 31 13:48:30 CEST 2005
 *  Copyright  2005 Bent Bisballe Nyeng
 *  deva@aasimon.org
 ****************************************************************************/

/*
 *  This file is part of MIaV.
 *
 *  MIaV is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  MIaV is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with MIaV; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 */

/*
 *  This file contains symbols used to create an ISO11172-1 compatible multiplexed 
 *  MPEG stream.
 */

#include "config.h"
#ifndef __MIAV_ISO11172_1_H__
#define __MIAV_ISO11172_1_H__

#define CLOCK_90KHZ 90000

namespace ISO11172_1 {
  ////////////////////////////////////////////////////
  // Types
  ////////////////////////////////////////////////////
  // 64 bits (8 bytes)
  typedef union {
    struct {
      unsigned long long int marker_bit3:1;
      unsigned long long int system_clock_reference3:15;
      unsigned long long int marker_bit2:1;
      unsigned long long int system_clock_reference2:15;
      unsigned long long int marker_bit1:1;
      unsigned long long int system_clock_reference1:3;
      unsigned long long int padding:4;
      unsigned long long int stuffing_byte:8;
      unsigned long long int packet_length:16;
    } bits;
    unsigned long long int ulli;
  } packet_header;

  typedef union {
    struct {
      unsigned long long int marker_bit5:1;
      unsigned long long int mux_rate:22;
      unsigned long long int marker_bit4:1;
      unsigned long long int marker_bit3:1;
      unsigned long long int system_clock_reference3:15;
      unsigned long long int marker_bit2:1;
      unsigned long long int system_clock_reference2:15;
      unsigned long long int marker_bit1:1;
      unsigned long long int system_clock_reference1:3;
      unsigned long long int padding:4;
    } bits;
    unsigned long long int ulli;
  } pack_header;

  typedef union {
    struct {
      unsigned long long int reserved_byte:8;
      unsigned long long int video_bound:5;
      unsigned long long int marker_bit3:1;
      unsigned long long int system_video_clock_flag:1;
      unsigned long long int system_audio_clock_flag:1;
      unsigned long long int CSPS_flag:1;
      unsigned long long int fixed_flag:1;
      unsigned long long int audio_bound:6;
      unsigned long long int marker_bit2:1;
      unsigned long long int rate_bound:22;
      unsigned long long int marker_bit1:1;
      unsigned long long int header_length:16;
      unsigned long long int ulli;
    } bits;
    unsigned long long int ulli;
  } system_header;

  typedef union {
    struct {
      unsigned long int STD_buffer_size_bound:13;
      unsigned long int STD_buffer_bound_scale:1;
      unsigned long int market_bits:2;
      unsigned long int stream_id:8;
    } bits;
    unsigned long int uli;
  } stream_description;

  ////////////////////////////////////////////////////
  // Constants
  ////////////////////////////////////////////////////
  const char pack_start_code[]          = "\x00\x00\x01\xBA";
  const char system_header_start_code[] = "\x00\x00\x01\xBB";
  const char packet_start_code_prefix[] = "\x00\x00\x01";
  const char stream_id_video1[]         = "\xE3";
  const char stream_id_video2[]         = "\xE4";
  const char stream_id_video3[]         = "\xE5";
  const char stream_id_video4[]         = "\xE6";
  const char stream_id_video5[]         = "\xE7";
  const char stream_id_video6[]         = "\xE8";
  const char stream_id_video7[]         = "\xE9";
  const char stream_id_video8[]         = "\xEA";
  const char stream_id_audio1[]         = "\xC0";
  const char stream_id_audio2[]         = "\xC1";
  const char stream_id_audio3[]         = "\xC2";
  const char stream_id_audio4[]         = "\xC3";
  const char stream_id_audio5[]         = "\xC4";
  const char stream_id_audio6[]         = "\xC5";
  const char stream_id_audio7[]         = "\xC6";
  const char stream_id_audio8[]         = "\xC7";
  const char stream_id_padding[]        = "\xBE";
  const char end_code[]                 = "\x00\x00\x01\xB9";

  ////////////////////////////////////////////////////
  // Methods
  ////////////////////////////////////////////////////
  /**
   * SCR stands for System Clock Reference
   */
  inline unsigned int SCR(unsigned int previous_SCR,
                          unsigned int pack_header_size,
                          unsigned int packets_per_pack,
                          unsigned int packet_data_size,
                          unsigned int Rmux)
  {
    // To prevent a crash when doing division.
    if(Rmux == 0) Rmux = 1;
    return previous_SCR + (unsigned int)((double)(pack_header_size + 
                                                  (packets_per_pack * packet_data_size)) * 
                                         (double)CLOCK_90KHZ / (double)Rmux);
  }

  /**
   * Calculates Rmux according to subclause A.5.4
   * mux stands for multiplexing and R for Rate,
   * so Rmux is the rate of the multiplexing.
   */
  inline unsigned int Rmux(unsigned int video_data_rate,
                           unsigned int audio_data_rate,
                           unsigned int packet_header_size,
                           unsigned int pack_header_size,
                           unsigned int packets_per_pack,
                           unsigned int packet_data_size)
  {
    // To prevent a crash when doing division.
    if(packets_per_pack == 0) packets_per_pack = 1;
    if(packet_data_size == 0) packet_data_size = 1;
    
    return (unsigned int)(
                          ((double)video_data_rate + (double)audio_data_rate) *
                          (1.0 + ((double)packet_header_size + (double)pack_header_size / (double)packets_per_pack) 
                           / (double)packet_data_size)
                          );
  }

  
};

#endif/*__MIAV_ISO11172_1_H__*/