1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: mpegvideo.c,v 1.14 2003/06/06 13:34:21 gbazin Exp $
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Eric Petit <titer@videolan.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
29 #include <vlc/decoder.h>
30 #include <vlc/input.h>
32 #include "codecs.h" /* WAVEFORMATEX BITMAPINFOHEADER */
34 #include <stdlib.h> /* malloc(), free() */
35 #include <string.h> /* strdup() */
37 /*****************************************************************************
39 *****************************************************************************/
40 typedef struct packetizer_s
42 /* Input properties */
43 decoder_fifo_t *p_fifo;
44 bit_stream_t bit_stream;
46 /* Output properties */
47 sout_packetizer_input_t *p_sout_input;
48 sout_format_t output_format;
51 mtime_t i_last_ref_pts;
53 int i_progressive_sequence;
54 uint8_t p_sequence_header[150];
55 int i_sequence_header_length;
56 int i_last_sequence_header;
58 int i_last_picture_structure;
61 static int Open ( vlc_object_t * );
62 static int Run ( decoder_fifo_t * );
64 static int InitThread ( packetizer_t * );
65 static void PacketizeThread ( packetizer_t * );
66 static void EndThread ( packetizer_t * );
68 /*****************************************************************************
70 *****************************************************************************/
73 set_description( _("MPEG-I/II video packetizer") );
74 set_capability( "packetizer", 50 );
75 set_callbacks( Open, NULL );
78 /*****************************************************************************
79 * OpenDecoder: probe the packetizer and return score
80 *****************************************************************************
81 * Tries to launch a decoder and return score so that the interface is able
83 *****************************************************************************/
84 static int Open( vlc_object_t *p_this )
86 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
88 if( p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'v') &&
89 p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', '1') &&
90 p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', '2') )
99 /*****************************************************************************
100 * RunDecoder: this function is called just after the thread is created
101 *****************************************************************************/
102 static int Run( decoder_fifo_t *p_fifo )
104 packetizer_t *p_pack;
107 msg_Info( p_fifo, "Running mpegvideo packetizer" );
108 if( !( p_pack = malloc( sizeof( packetizer_t ) ) ) )
110 msg_Err( p_fifo, "out of memory" );
111 DecoderError( p_fifo );
114 memset( p_pack, 0, sizeof( packetizer_t ) );
116 p_pack->p_fifo = p_fifo;
118 if( InitThread( p_pack ) != 0 )
120 DecoderError( p_fifo );
124 while( ( !p_pack->p_fifo->b_die )&&( !p_pack->p_fifo->b_error ) )
126 PacketizeThread( p_pack );
130 if( ( b_error = p_pack->p_fifo->b_error ) )
132 DecoderError( p_pack->p_fifo );
151 /*****************************************************************************
152 * InitThread: initialize data before entering main loop
153 *****************************************************************************/
155 static int InitThread( packetizer_t *p_pack )
158 p_pack->output_format.i_cat = VIDEO_ES;
159 p_pack->output_format.i_fourcc = VLC_FOURCC( 'm', 'p', 'g', 'v');
160 p_pack->output_format.i_width = 0;
161 p_pack->output_format.i_height = 0;
162 p_pack->output_format.i_bitrate= 0;
163 p_pack->output_format.i_extra_data = 0;
164 p_pack->output_format.p_extra_data = NULL;
166 p_pack->p_sout_input = NULL;
168 if( InitBitstream( &p_pack->bit_stream, p_pack->p_fifo,
169 NULL, NULL ) != VLC_SUCCESS )
171 msg_Err( p_pack->p_fifo, "cannot initialize bitstream" );
175 p_pack->i_last_picture_structure = 0x03; /* frame picture */
179 /* from ISO 13818-2 */
180 /* converting frame_rate_code to frame_rate */
181 static const double pd_frame_rates[16] =
183 0, 24000/1001, 24, 25, 30000/1001, 30, 50, 60000/1001, 60,
187 static int CopyUntilNextStartCode( packetizer_t *p_pack,
188 sout_buffer_t *p_sout_buffer,
189 unsigned int *pi_pos )
195 p_sout_buffer->p_buffer[(*pi_pos)++] =
196 GetBits( &p_pack->bit_stream, 8 );
199 if( *pi_pos + 2048 > p_sout_buffer->i_buffer_size )
201 sout_BufferRealloc( p_pack->p_sout_input->p_sout,
203 p_sout_buffer->i_buffer_size + 50 * 1024);
206 } while( ShowBits( &p_pack->bit_stream, 24 ) != 0x01 &&
207 !p_pack->p_fifo->b_die && !p_pack->p_fifo->b_error );
212 /*****************************************************************************
213 * PacketizeThread: packetize an unit (here copy a complete pes)
214 *****************************************************************************/
215 static void PacketizeThread( packetizer_t *p_pack )
217 sout_buffer_t *p_sout_buffer = NULL;
218 vlc_bool_t b_seen_slice = VLC_FALSE;
221 mtime_t i_duration; /* of the parsed picture */
226 /* needed to calculate pts/dts */
227 int i_temporal_ref = 0;
228 int i_picture_structure = 0x03; /* frame picture */
229 int i_top_field_first = 0;
230 int i_repeat_first_field = 0;
231 int i_progressive_frame = 0;
233 if( !p_pack->p_sout_input )
235 byte_t p_temp[512];/* 150 bytes is the maximal size
236 of a sequence_header + sequence_extension */
237 int i_frame_rate_code;
240 /* skip data until we find a sequence_header_code */
241 /* TODO: store skipped somewhere so can send it to the mux
242 * after the input is created */
244 while( ShowBits( &p_pack->bit_stream, 32 ) != 0x1B3 &&
245 !p_pack->p_fifo->b_die && !p_pack->p_fifo->b_error )
247 RemoveBits( &p_pack->bit_stream, 8 );
250 msg_Warn( p_pack->p_fifo, "sequence_header_code found (%d skipped)",
253 /* copy the start_code */
255 GetChunk( &p_pack->bit_stream, p_temp, 4 ); i_pos += 4;
257 /* horizontal_size_value */
258 p_pack->output_format.i_width = ShowBits( &p_pack->bit_stream, 12 );
259 /* vertical_size_value */
260 p_pack->output_format.i_height= ShowBits( &p_pack->bit_stream, 24 ) & 0xFFF;
261 /* frame_rate_code */
262 i_frame_rate_code = ShowBits( &p_pack->bit_stream, 32 ) & 0xF;
265 GetChunk( &p_pack->bit_stream, p_temp + i_pos, 7 ); i_pos += 7;
267 /* intra_quantiser_matrix [non_intra_quantiser_matrix] */
268 if( ShowBits( &p_pack->bit_stream, 7 ) & 0x1 )
271 GetChunk( &p_pack->bit_stream, p_temp + i_pos, 64 ); i_pos += 64;
273 if( ShowBits( &p_pack->bit_stream, 8 ) & 0x1 )
275 GetChunk( &p_pack->bit_stream, p_temp + i_pos, 65); i_pos += 65;
278 /* non_intra_quantiser_matrix */
279 else if( ShowBits( &p_pack->bit_stream, 8 ) & 0x1 )
281 GetChunk( &p_pack->bit_stream, p_temp + i_pos, 65); i_pos += 65;
286 GetChunk( &p_pack->bit_stream, p_temp + i_pos, 1 ); i_pos += 1;
289 /* sequence_extension (10 bytes) */
290 if( ShowBits( &p_pack->bit_stream, 32 ) != 0x1B5 )
292 msg_Dbg( p_pack->p_fifo, "ARRGG no extension_start_code" );
293 p_pack->i_progressive_sequence = 1;
297 GetChunk( &p_pack->bit_stream, p_temp + i_pos, 10 );
298 p_pack->i_progressive_sequence = ( p_temp[i_pos+5]&0x08 ) ? 1 : 0;
303 /* remember sequence_header and sequence_extention */
304 memcpy( p_pack->p_sequence_header, p_temp, i_pos );
305 p_pack->i_sequence_header_length = i_pos;
307 p_pack->d_frame_rate = pd_frame_rates[i_frame_rate_code];
309 msg_Warn( p_pack->p_fifo,
310 "creating input (image size %dx%d, frame rate %.2f)",
311 p_pack->output_format.i_width,
312 p_pack->output_format.i_height,
313 p_pack->d_frame_rate );
315 /* now we have informations to create the input */
316 p_pack->p_sout_input = sout_InputNew( p_pack->p_fifo,
317 &p_pack->output_format );
319 if( !p_pack->p_sout_input )
321 msg_Err( p_pack->p_fifo, "cannot add a new stream" );
322 p_pack->p_fifo->b_error = VLC_TRUE;
326 p_sout_buffer = sout_BufferNew( p_pack->p_sout_input->p_sout,
328 p_sout_buffer->i_size = i_pos;
329 memcpy( p_sout_buffer->p_buffer, p_temp, i_pos );
335 sout_BufferNew( p_pack->p_sout_input->p_sout, 100 * 1024 );
339 p_pack->i_last_sequence_header++;
344 if( p_pack->p_fifo->b_die || p_pack->p_fifo->b_error )
349 i_code = ShowBits( &p_pack->bit_stream, 32 );
351 if( b_seen_slice && ( i_code < 0x101 || i_code > 0x1af ) )
356 if( i_code == 0x1B8 ) /* GOP */
358 /* usefull for bad MPEG-1 : repeat the sequence_header
360 if( p_pack->i_last_sequence_header > (int) p_pack->d_frame_rate )
362 memcpy( p_sout_buffer->p_buffer + i_pos,
363 p_pack->p_sequence_header,
364 p_pack->i_sequence_header_length );
365 i_pos += p_pack->i_sequence_header_length;
366 p_pack->i_last_sequence_header = 0;
369 p_pack->i_last_ref_pts =
371 (mtime_t)( 1000000 / p_pack->d_frame_rate); /* FIXME */
373 CopyUntilNextStartCode( p_pack, p_sout_buffer, &i_pos );
375 else if( i_code == 0x100 ) /* Picture */
377 /* picture_start_code */
378 GetChunk( &p_pack->bit_stream,
379 p_sout_buffer->p_buffer + i_pos, 4 ); i_pos += 4;
381 NextPTS( &p_pack->bit_stream, &i_pts, &i_dts );
382 i_temporal_ref = ShowBits( &p_pack->bit_stream, 10 );
384 CopyUntilNextStartCode( p_pack, p_sout_buffer, &i_pos );
386 else if( i_code == 0x1b5 )
388 /* extention start code 32 */
389 GetChunk( &p_pack->bit_stream,
390 p_sout_buffer->p_buffer + i_pos, 4 ); i_pos += 4;
392 if( ShowBits( &p_pack->bit_stream, 4 ) == 0x08 )
394 /* picture coding extention */
396 /* extention start code identifier(b1000) 4 */
397 /* f_code[2][2] 16 */
398 /* intra_dc_precision 2 */
399 /* picture_structure 2 */
400 /* top_field_first 1 */
401 i_picture_structure =
402 ShowBits( &p_pack->bit_stream, 24 ) & 0x03;
404 ShowBits( &p_pack->bit_stream, 25 ) & 0x01;
405 i_repeat_first_field =
406 ShowBits( &p_pack->bit_stream, 31 ) & 0x01;
408 GetChunk( &p_pack->bit_stream,
409 p_sout_buffer->p_buffer + i_pos, 4 ); i_pos += 4;
411 i_progressive_frame =
412 ShowBits( &p_pack->bit_stream, 1 ) & 0x01;
414 CopyUntilNextStartCode( p_pack, p_sout_buffer, &i_pos );
418 if( i_code >= 0x101 && i_code <= 0x1af )
420 b_seen_slice = VLC_TRUE;
423 if( i_code == 0x1B3 )
425 p_pack->i_last_sequence_header = 0;
427 CopyUntilNextStartCode( p_pack, p_sout_buffer, &i_pos );
431 sout_BufferRealloc( p_pack->p_sout_input->p_sout,
432 p_sout_buffer, i_pos );
433 p_sout_buffer->i_size = i_pos;
435 /* calculate dts/pts */
436 if( p_pack->i_progressive_sequence || i_picture_structure == 0x03)
438 i_duration = (mtime_t)( 1000000 / p_pack->d_frame_rate );
442 i_duration = (mtime_t)( 1000000 / p_pack->d_frame_rate / 2);
445 /* fix i_last_dts and i_last_ref_pts with i_dts and i_pts from stream */
446 if( i_dts <= 0 && p_pack->i_last_dts <= 0 )
448 msg_Dbg( p_pack->p_fifo, "need a starting pts" );
449 sout_BufferDelete( p_pack->p_sout_input->p_sout,
457 //if( i_dts - p_pack->i_last_dts > 200000 ||
458 // i_dts - p_pack->i_last_dts < 200000 )
460 p_pack->i_last_dts = i_dts;
463 p_pack->i_last_ref_pts = i_pts -
464 i_temporal_ref * (mtime_t)( 1000000 / p_pack->d_frame_rate );
470 p_sout_buffer->i_dts = p_pack->i_last_dts;
471 p_sout_buffer->i_pts = p_pack->i_last_ref_pts +
472 i_temporal_ref * (mtime_t)( 1000000 / p_pack->d_frame_rate );
473 p_sout_buffer->i_length = i_duration;
474 p_sout_buffer->i_bitrate = (int)( 8 * i_pos * p_pack->d_frame_rate );
475 sout_InputSendBuffer( p_pack->p_sout_input, p_sout_buffer );
477 if( p_pack->i_progressive_sequence )
479 if( i_top_field_first == 0 && i_repeat_first_field == 0 )
481 p_pack->i_last_dts += i_duration;
483 else if( i_top_field_first == 0 && i_repeat_first_field == 1 )
485 p_pack->i_last_dts += 2 * i_duration;
487 else if( i_top_field_first == 1 && i_repeat_first_field == 1 )
489 p_pack->i_last_dts += 3 * i_duration;
494 if( i_picture_structure == 0x03 )
496 p_pack->i_last_dts += i_duration;
498 if( i_progressive_frame && i_repeat_first_field )
500 p_pack->i_last_dts += i_duration / 2;
503 else if( i_picture_structure == p_pack->i_last_picture_structure )
505 p_pack->i_last_dts += 2 * i_duration;
507 else if( ( !i_top_field_first && i_picture_structure == 0x01 ) ||
508 ( i_top_field_first && i_picture_structure == 0x02 ) )
510 p_pack->i_last_dts += 2 * i_duration;
513 p_pack->i_last_picture_structure = i_picture_structure;
517 /*****************************************************************************
518 * EndThread : packetizer thread destruction
519 *****************************************************************************/
520 static void EndThread ( packetizer_t *p_pack)
522 if( p_pack->p_sout_input )
524 sout_InputDelete( p_pack->p_sout_input );