Commit 8470508b authored by Laurent Aimar's avatar Laurent Aimar
Browse files

* all: use p_vlc->pf_memcpy instead of memcpy on big data block.

 * mpeg4video: removed a bad code dealing with pts discontinuity.
 * pes.c: try to avoid copying the whole  PES. (the first 64ko
ins't any more copied :)
parent 6da4dafa
......@@ -2,7 +2,7 @@
* pes.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: pes.c,v 1.3 2003/01/08 10:34:58 fenrir Exp $
* $Id: pes.c,v 1.4 2003/01/17 15:26:24 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
......@@ -46,30 +46,145 @@
#include "pes.h"
#include "bits.h"
#define PES_PAYLOAD_SIZE_MAX 65500
static inline int PESHeader( uint8_t *p_hdr, mtime_t i_pts, mtime_t i_dts, int i_es_size, int i_stream_id, int i_private_id )
{
bits_buffer_t bits;
bits_initwrite( &bits, 30, p_hdr );
/* add start code */
bits_write( &bits, 24, 0x01 );
bits_write( &bits, 8, i_stream_id );
switch( i_stream_id )
{
case PES_PROGRAM_STREAM_MAP:
case PES_PADDING:
case PES_PRIVATE_STREAM_2:
case PES_ECM:
case PES_EMM:
case PES_PROGRAM_STREAM_DIRECTORY:
case PES_DSMCC_STREAM:
case PES_ITU_T_H222_1_TYPE_E_STREAM:
/* add pes data size */
bits_write( &bits, 16, i_es_size );
bits_align( &bits );
return( bits.i_data );
default:
/* arg, a little more difficult */
// if( b_mpeg2 ) // FIXME unsupported
{
int i_pts_dts;
int i_extra = 0;
/* *** for PES_PRIVATE_STREAM_1 there is an extra header after the pes hdr *** */
if( i_stream_id == PES_PRIVATE_STREAM_1 )
{
i_extra = 1;
if( ( i_private_id&0xf0 ) == 0x80 )
{
i_extra += 3;
}
}
if( i_dts >= 0 )
{
bits_write( &bits, 16, i_es_size + i_extra+ 13 );
i_pts_dts = 0x03;
}
else
{
bits_write( &bits, 16, i_es_size + i_extra + 8 );
i_pts_dts = 0x02;
}
bits_write( &bits, 2, 0x02 ); // mpeg2 id
bits_write( &bits, 2, 0x00 ); // pes scrambling control
bits_write( &bits, 1, 0x00 ); // pes priority
bits_write( &bits, 1, 0x00 ); // data alignement indicator
bits_write( &bits, 1, 0x00 ); // copyright
bits_write( &bits, 1, 0x00 ); // original or copy
bits_write( &bits, 2, i_pts_dts ); // pts_dts flags
bits_write( &bits, 1, 0x00 ); // escr flags
bits_write( &bits, 1, 0x00 ); // es rate flag
bits_write( &bits, 1, 0x00 ); // dsm trick mode flag
bits_write( &bits, 1, 0x00 ); // additional copy info flag
bits_write( &bits, 1, 0x00 ); // pes crc flag
bits_write( &bits, 1, 0x00 ); // pes extention flags
if( i_pts_dts & 0x01 )
{
bits_write( &bits, 8, 0x0a ); // header size -> pts and dts
}
else
{
bits_write( &bits, 8, 0x05 ); // header size -> pts
}
/* write pts */
bits_write( &bits, 4, i_pts_dts ); // '0010' or '0011'
bits_write( &bits, 3, i_pts >> 30 );
bits_write( &bits, 1, 0x01 ); // marker
bits_write( &bits, 15, i_pts >> 15 );
bits_write( &bits, 1, 0x01 ); // marker
bits_write( &bits, 15, i_pts );
bits_write( &bits, 1, 0x01 ); // marker
/* write i_dts */
if( i_pts_dts & 0x01 )
{
bits_write( &bits, 4, 0x01 ); // '0001'
bits_write( &bits, 3, i_dts >> 30 );
bits_write( &bits, 1, 0x01 ); // marker
bits_write( &bits, 15, i_dts >> 15 );
bits_write( &bits, 1, 0x01 ); // marker
bits_write( &bits, 15, i_dts );
bits_write( &bits, 1, 0x01 ); // marker
}
}
/* now should be stuffing */
/* and then pes data */
bits_align( &bits );
if( i_stream_id == PES_PRIVATE_STREAM_1 && i_private_id != -1 )
{
bits_write( &bits, 8, i_private_id );
if( ( i_private_id&0xf0 ) == 0x80 )
{
bits_write( &bits, 24, 0 ); // ac3
}
}
bits_align( &bits );
return( bits.i_data );
}
}
int E_( EStoPES )( sout_instance_t *p_sout,
sout_buffer_t **pp_pes,
sout_buffer_t *p_es,
int i_stream_id,
int b_mpeg2 )
{
sout_buffer_t *p_pes;
bits_buffer_t bits;
sout_buffer_t *p_es_sav, *p_pes;
mtime_t i_pts, i_dts;
uint8_t *p_data;
int i_size;
int i_private_id;
int i_private_id = -1;
uint8_t header[30]; // PES header + extra < 30 (more like 17)
int i_pes_payload;
int i_pes_header;
/* HACK for private stream 1 in ps */
if( ( i_stream_id&0xff00 ) == 0xbd00 )
if( ( i_stream_id >> 8 ) == PES_PRIVATE_STREAM_1 )
{
i_private_id = i_stream_id & 0xff;
i_stream_id = PES_PRIVATE_STREAM_1;
}
else
{
i_private_id = -1;
}
i_pts = p_es->i_pts * 9 / 100; // 90000 units clock
i_dts = p_es->i_dts * 9 / 100; // 90000 units clock
......@@ -78,166 +193,58 @@ int E_( EStoPES )( sout_instance_t *p_sout,
p_data = p_es->p_buffer;
*pp_pes = p_pes = NULL;
p_es_sav = p_es;
do
{
int i_copy;
i_pes_payload = __MIN( i_size, PES_PAYLOAD_SIZE_MAX );
i_pes_header = PESHeader( header, i_pts, i_dts, i_pes_payload, i_stream_id, i_private_id );
i_dts = -1; // only first PES has a dts
i_copy = __MIN( i_size, 65500 );
if( *pp_pes == NULL )
if( p_es )
{
*pp_pes = p_pes = sout_BufferNew( p_sout, 100 + i_copy);
p_pes->i_dts = p_es->i_dts;
p_pes->i_pts = p_es->i_pts;
p_pes->i_length = p_es->i_length;
if( sout_BufferReallocFromPreHeader( p_sout, p_es, i_pes_header ) )
{
msg_Err( p_sout, "cannot realloc prehader (should never happen)" );
return( -1 );
}
/* reuse p_es for first frame */
*pp_pes = p_pes = p_es;
/* don't touch i_dts, i_pts, i_length as are already set :) */
p_es = NULL;
}
else
{
p_pes->p_next = sout_BufferNew( p_sout, 100 + i_copy );
p_pes->p_next = sout_BufferNew( p_sout, i_pes_header + i_pes_payload );
p_pes = p_pes->p_next;
p_pes->i_dts = 0;
p_pes->i_pts = 0;
p_pes->i_length = 0;
if( i_pes_payload > 0 )
{
p_sout->p_vlc->pf_memcpy( p_pes->p_buffer + i_pes_header, p_data, i_pes_payload );
}
}
p_pes->i_size = 0;
bits_initwrite( &bits, 100, p_pes->p_buffer );
/* first 4 bytes common pes header */
/* add start code for pes 0x000001 */
bits_write( &bits, 24, 0x01 );
/* add stream id */
bits_write( &bits, 8, i_stream_id );
switch( i_stream_id )
{
case PES_PROGRAM_STREAM_MAP:
case PES_PADDING:
case PES_PRIVATE_STREAM_2:
case PES_ECM:
case PES_EMM:
case PES_PROGRAM_STREAM_DIRECTORY:
case PES_DSMCC_STREAM:
case PES_ITU_T_H222_1_TYPE_E_STREAM:
/* add pes data size */
bits_write( &bits, 16, i_copy );
bits_align( &bits );
break;
default:
/* arg, a little more difficult */
if( b_mpeg2 )
{
int i_pts_dts;
int i_extra;
if( i_stream_id == PES_PRIVATE_STREAM_1 )
{
i_extra = 1;
if( ( i_private_id&0xf0 ) == 0x80 )
{
i_extra += 3;
}
}
else
{
i_extra = 0;
}
if( i_dts > 0 )
{
bits_write( &bits, 16, i_copy + i_extra+ 13 );
i_pts_dts = 0x03;
}
else
{
bits_write( &bits, 16, i_copy + i_extra + 8 );
i_pts_dts = 0x02;
}
bits_write( &bits, 2, 0x02 ); // mpeg2 id
bits_write( &bits, 2, 0x00 ); // pes scrambling control
bits_write( &bits, 1, 0x00 ); // pes priority
bits_write( &bits, 1, 0x00 ); // data alignement indicator
bits_write( &bits, 1, 0x00 ); // copyright
bits_write( &bits, 1, 0x00 ); // original or copy
bits_write( &bits, 2, i_pts_dts ); // pts_dts flags
bits_write( &bits, 1, 0x00 ); // escr flags
bits_write( &bits, 1, 0x00 ); // es rate flag
bits_write( &bits, 1, 0x00 ); // dsm trick mode flag
bits_write( &bits, 1, 0x00 ); // additional copy info flag
bits_write( &bits, 1, 0x00 ); // pes crc flag
bits_write( &bits, 1, 0x00 ); // pes extention flags
if( i_pts_dts & 0x01 )
{
bits_write( &bits, 8, 0x0a ); // header size -> pts and dts
}
else
{
bits_write( &bits, 8, 0x05 ); // header size -> pts
}
/* write pts */
bits_write( &bits, 4, i_pts_dts ); // '0010' or '0011'
bits_write( &bits, 3, i_pts >> 30 );
bits_write( &bits, 1, 0x01 ); // marker
bits_write( &bits, 15, i_pts >> 15 );
bits_write( &bits, 1, 0x01 ); // marker
bits_write( &bits, 15, i_pts );
bits_write( &bits, 1, 0x01 ); // marker
/* write i_dts */
if( i_pts_dts & 0x01 )
{
bits_write( &bits, 4, 0x01 ); // '0001'
bits_write( &bits, 3, i_dts >> 30 );
bits_write( &bits, 1, 0x01 ); // marker
bits_write( &bits, 15, i_dts >> 15 );
bits_write( &bits, 1, 0x01 ); // marker
bits_write( &bits, 15, i_dts );
bits_write( &bits, 1, 0x01 ); // marker
i_dts = 0; // write dts only once
}
/* copy header */
memcpy( p_pes->p_buffer, header, i_pes_header );
}
else
{
msg_Warn( p_sout, "es isn't mpeg2 -->corrupted pes" );
}
/* now should be stuffing */
/* and then pes data */
i_size -= i_pes_payload;
p_data += i_pes_payload;
p_pes->i_size = i_pes_header + i_pes_payload;
bits_align( &bits );
if( i_stream_id == PES_PRIVATE_STREAM_1 && i_private_id != -1 )
{
bits_write( &bits, 8, i_private_id );
if( ( i_private_id&0xf0 ) == 0x80 )
{
bits_write( &bits, 24, 0 ); // ac3
}
}
break;
}
} while( i_size > 0 );
if( i_copy > 0 )
{
memcpy( p_pes->p_buffer + bits.i_data, p_data, i_copy );
}
/* sav some space */
if( p_es_sav->i_size + 10*1024 < p_es_sav->i_buffer_size )
{
sout_BufferRealloc( p_sout, p_es_sav, p_es_sav->i_size );
}
i_size -= i_copy;
p_data += i_copy;
p_pes->i_size = bits.i_data + i_copy;
return( 0 );
}
} while( i_size > 0 );
sout_BufferDelete( p_sout, p_es );
return( 0 );
}
......@@ -2,7 +2,7 @@
* mpeg4video.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: mpeg4video.c,v 1.4 2003/01/12 04:11:35 fenrir Exp $
* $Id: mpeg4video.c,v 1.5 2003/01/17 15:26:24 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
......@@ -391,12 +391,13 @@ static void PacketizeThread( packetizer_thread_t *p_pack )
mtime_t i_gap;
i_gap = p_pes_next->i_pts - p_pes->i_pts;
if( i_gap > 1000000 / 80 ) // too big fps > 80 is no sense
#if 0
if( i_gap > 1000000 / 4 ) // too littl fps < 4 is no sense
{
i_gap = 1000000 / 25;
p_pack->i_pts_start =
( p_pes->i_pts - p_pack->i_pts_start ) + p_pes_next->i_pts - i_gap;
- ( p_pes->i_pts - p_pack->i_pts_start ) + p_pes_next->i_pts - i_gap;
}
else if( i_gap < 0 )
{
......@@ -404,6 +405,15 @@ static void PacketizeThread( packetizer_thread_t *p_pack )
( p_pes->i_pts - p_pack->i_pts_start ) + p_pes_next->i_pts;
i_gap = 0;
}
if( i_gap < 0 )
{
msg_Dbg( p_pack->p_fifo, "pts:%lld next_pts:%lld", p_pes->i_pts, p_pes_next->i_pts );
/* work around for seek */
p_pack->i_pts_start -= i_gap;
}
// msg_Dbg( p_pack->p_fifo, "gap %lld date %lld next diff %lld", i_gap, p_pes->i_pts, p_pes_next->i_pts-p_pack->i_pts_start );
#endif
p_sout_buffer->i_length = i_gap;
}
sout_InputSendBuffer( p_pack->p_sout_input,
......
......@@ -2,7 +2,7 @@
* stream_output.c : stream output module
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: stream_output.c,v 1.11 2003/01/14 04:34:13 fenrir Exp $
* $Id: stream_output.c,v 1.12 2003/01/17 15:26:24 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Laurent Aimar <fenrir@via.ecp.fr>
......@@ -590,7 +590,7 @@ sout_buffer_t *sout_BufferDuplicate( sout_instance_t *p_sout,
p_dup->i_dts = p_buffer->i_dts;
p_dup->i_pts = p_buffer->i_pts;
p_dup->i_length = p_buffer->i_length;
memcpy( p_dup->p_buffer, p_buffer->p_buffer, p_buffer->i_size );
p_sout->p_vlc->pf_memcpy( p_dup->p_buffer, p_buffer->p_buffer, p_buffer->i_size );
return( p_dup );
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment