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 #include <stdlib.h>
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include <string.h>
00032 #include <errno.h>
00033 #include <fcntl.h>
00034
00035 #include <vlc/vlc.h>
00036 #include <vlc/input.h>
00037 #include <vlc/sout.h>
00038
00039 #ifdef HAVE_UNISTD_H
00040 # include <unistd.h>
00041 #endif
00042
00043 #include "codecs.h"
00044 #include "pes.h"
00045 #include "bits.h"
00046
00047 static inline int PESHeader( uint8_t *p_hdr, mtime_t i_pts, mtime_t i_dts,
00048 int i_es_size, es_format_t *p_fmt,
00049 int i_stream_id, int i_private_id,
00050 vlc_bool_t b_mpeg2, vlc_bool_t b_data_alignment,
00051 int i_header_size )
00052 {
00053 bits_buffer_t bits;
00054 int i_extra = 0;
00055
00056
00057
00058
00059 if( i_stream_id == PES_PRIVATE_STREAM_1 && i_private_id != -1 )
00060 {
00061 i_extra = 1;
00062 if( ( i_private_id & 0xf0 ) == 0x80 )
00063 {
00064 i_extra += 3;
00065 }
00066 }
00067
00068 bits_initwrite( &bits, 50, p_hdr );
00069
00070
00071 bits_write( &bits, 24, 0x01 );
00072 bits_write( &bits, 8, i_stream_id );
00073 switch( i_stream_id )
00074 {
00075 case PES_PROGRAM_STREAM_MAP:
00076 case PES_PADDING:
00077 case PES_PRIVATE_STREAM_2:
00078 case PES_ECM:
00079 case PES_EMM:
00080 case PES_PROGRAM_STREAM_DIRECTORY:
00081 case PES_DSMCC_STREAM:
00082 case PES_ITU_T_H222_1_TYPE_E_STREAM:
00083
00084 bits_write( &bits, 16, i_es_size );
00085 bits_align( &bits );
00086 return( bits.i_data );
00087
00088 default:
00089
00090 if( b_mpeg2 )
00091 {
00092 int i_pts_dts;
00093
00094 if( i_pts > 0 && i_dts > 0 &&
00095 ( i_pts != i_dts || ( p_fmt->i_cat == VIDEO_ES &&
00096 p_fmt->i_codec != VLC_FOURCC('m','p','g','v') ) ) )
00097 {
00098 i_pts_dts = 0x03;
00099 if ( !i_header_size ) i_header_size = 0xa;
00100 }
00101 else if( i_pts > 0 )
00102 {
00103 i_pts_dts = 0x02;
00104 if ( !i_header_size ) i_header_size = 0x5;
00105 }
00106 else
00107 {
00108 i_pts_dts = 0x00;
00109 if ( !i_header_size ) i_header_size = 0x0;
00110 }
00111
00112 bits_write( &bits, 16, i_es_size + i_extra + 3
00113 + i_header_size );
00114 bits_write( &bits, 2, 0x02 );
00115 bits_write( &bits, 2, 0x00 );
00116 bits_write( &bits, 1, 0x00 );
00117 bits_write( &bits, 1, b_data_alignment );
00118 bits_write( &bits, 1, 0x00 );
00119 bits_write( &bits, 1, 0x00 );
00120
00121 bits_write( &bits, 2, i_pts_dts );
00122 bits_write( &bits, 1, 0x00 );
00123 bits_write( &bits, 1, 0x00 );
00124 bits_write( &bits, 1, 0x00 );
00125 bits_write( &bits, 1, 0x00 );
00126 bits_write( &bits, 1, 0x00 );
00127 bits_write( &bits, 1, 0x00 );
00128 bits_write( &bits, 8, i_header_size );
00129
00130
00131 if( i_pts_dts & 0x02 )
00132 {
00133 bits_write( &bits, 4, i_pts_dts );
00134 bits_write( &bits, 3, i_pts >> 30 );
00135 bits_write( &bits, 1, 0x01 );
00136 bits_write( &bits, 15, i_pts >> 15 );
00137 bits_write( &bits, 1, 0x01 );
00138 bits_write( &bits, 15, i_pts );
00139 bits_write( &bits, 1, 0x01 );
00140 i_header_size -= 0x5;
00141 }
00142
00143 if( i_pts_dts & 0x01 )
00144 {
00145 bits_write( &bits, 4, 0x01 );
00146 bits_write( &bits, 3, i_dts >> 30 );
00147 bits_write( &bits, 1, 0x01 );
00148 bits_write( &bits, 15, i_dts >> 15 );
00149 bits_write( &bits, 1, 0x01 );
00150 bits_write( &bits, 15, i_dts );
00151 bits_write( &bits, 1, 0x01 );
00152 i_header_size -= 0x5;
00153 }
00154 while ( i_header_size )
00155 {
00156 bits_write( &bits, 8, 0xff );
00157 i_header_size--;
00158 }
00159 }
00160 else
00161 {
00162 int i_pts_dts;
00163
00164 if( i_pts > 0 && i_dts > 0 &&
00165 ( i_pts != i_dts || p_fmt->i_cat == VIDEO_ES ) )
00166 {
00167 bits_write( &bits, 16, i_es_size + i_extra + 10 );
00168 i_pts_dts = 0x03;
00169 }
00170 else if( i_pts > 0 )
00171 {
00172 bits_write( &bits, 16, i_es_size + i_extra + 5 );
00173 i_pts_dts = 0x02;
00174 }
00175 else
00176 {
00177 bits_write( &bits, 16, i_es_size + i_extra + 1 );
00178 i_pts_dts = 0x00;
00179 }
00180
00181
00182
00183
00184
00185
00186 if( i_pts_dts & 0x02 )
00187 {
00188 bits_write( &bits, 4, i_pts_dts );
00189 bits_write( &bits, 3, i_pts >> 30 );
00190 bits_write( &bits, 1, 0x01 );
00191 bits_write( &bits, 15, i_pts >> 15 );
00192 bits_write( &bits, 1, 0x01 );
00193 bits_write( &bits, 15, i_pts );
00194 bits_write( &bits, 1, 0x01 );
00195 }
00196
00197 if( i_pts_dts & 0x01 )
00198 {
00199 bits_write( &bits, 4, 0x01 );
00200 bits_write( &bits, 3, i_dts >> 30 );
00201 bits_write( &bits, 1, 0x01 );
00202 bits_write( &bits, 15, i_dts >> 15 );
00203 bits_write( &bits, 1, 0x01 );
00204 bits_write( &bits, 15, i_dts );
00205 bits_write( &bits, 1, 0x01 );
00206 }
00207 if( !i_pts_dts )
00208 {
00209 bits_write( &bits, 8, 0x0F );
00210 }
00211
00212 }
00213
00214
00215
00216
00217 bits_align( &bits );
00218 if( i_stream_id == PES_PRIVATE_STREAM_1 && i_private_id != -1 )
00219 {
00220 bits_write( &bits, 8, i_private_id );
00221 if( ( i_private_id&0xf0 ) == 0x80 )
00222 {
00223 bits_write( &bits, 24, 0 );
00224 }
00225 }
00226 bits_align( &bits );
00227 return( bits.i_data );
00228 }
00229 }
00230
00231 int E_( EStoPES )( sout_instance_t *p_sout, block_t **pp_pes, block_t *p_es,
00232 es_format_t *p_fmt, int i_stream_id,
00233 int b_mpeg2, int b_data_alignment, int i_header_size,
00234 int i_max_pes_size )
00235 {
00236 block_t *p_pes;
00237 mtime_t i_pts, i_dts, i_length;
00238
00239 uint8_t *p_data;
00240 int i_size;
00241
00242 int i_private_id = -1;
00243
00244 uint8_t header[50];
00245 int i_pes_payload;
00246 int i_pes_header;
00247
00248 int i_pes_count = 1;
00249
00250
00251 if( ( i_stream_id >> 8 ) == PES_PRIVATE_STREAM_1 )
00252 {
00253 i_private_id = i_stream_id & 0xff;
00254 i_stream_id = PES_PRIVATE_STREAM_1;
00255 }
00256
00257 if( p_fmt->i_codec == VLC_FOURCC( 'm', 'p','4', 'v' ) &&
00258 p_es->i_flags & BLOCK_FLAG_TYPE_I )
00259 {
00260
00261 p_es = block_Realloc( p_es, p_fmt->i_extra, p_es->i_buffer );
00262
00263 memcpy( p_es->p_buffer, p_fmt->p_extra, p_fmt->i_extra );
00264 }
00265
00266 i_pts = p_es->i_pts <= 0 ? 0 : p_es->i_pts * 9 / 100;
00267 i_dts = p_es->i_dts <= 0 ? 0 : p_es->i_dts * 9 / 100;
00268
00269 i_size = p_es->i_buffer;
00270 p_data = p_es->p_buffer;
00271
00272 *pp_pes = p_pes = NULL;
00273
00274 #ifdef DEBUG
00275 memset( header, 0, 50 );
00276 #endif
00277
00278 do
00279 {
00280 i_pes_payload = __MIN( i_size, (i_max_pes_size ?
00281 i_max_pes_size : PES_PAYLOAD_SIZE_MAX) );
00282 i_pes_header = PESHeader( header, i_pts, i_dts, i_pes_payload,
00283 p_fmt, i_stream_id, i_private_id, b_mpeg2,
00284 b_data_alignment, i_header_size );
00285 i_dts = 0;
00286 i_pts = 0;
00287
00288 if( p_es )
00289 {
00290 p_es = block_Realloc( p_es, i_pes_header, p_es->i_buffer );
00291
00292 *pp_pes = p_pes = p_es;
00293
00294 p_es = NULL;
00295 }
00296 else
00297 {
00298 p_pes->p_next = block_New( p_sout, i_pes_header + i_pes_payload );
00299 p_pes = p_pes->p_next;
00300
00301 p_pes->i_dts = 0;
00302 p_pes->i_pts = 0;
00303 p_pes->i_length = 0;
00304 if( i_pes_payload > 0 )
00305 {
00306 p_sout->p_vlc->pf_memcpy( p_pes->p_buffer + i_pes_header,
00307 p_data, i_pes_payload );
00308 }
00309 i_pes_count++;
00310 }
00311
00312
00313 memcpy( p_pes->p_buffer, header, i_pes_header );
00314
00315 i_size -= i_pes_payload;
00316 p_data += i_pes_payload;
00317 p_pes->i_buffer = i_pes_header + i_pes_payload;
00318
00319 } while( i_size > 0 );
00320
00321
00322 i_dts = (*pp_pes)->i_dts;
00323 i_length = (*pp_pes)->i_length / i_pes_count;
00324 for( p_pes = *pp_pes; p_pes != NULL; p_pes = p_pes->p_next )
00325 {
00326 p_pes->i_dts = i_dts;
00327 p_pes->i_length = i_length;
00328
00329 i_dts += i_length;
00330 }
00331
00332 return 0;
00333 }