Fix some small issues. Add MPEG-2 AAC muxing.

sdt
Kieran Kunhya 2011-01-27 23:34:51 +00:00
rodzic 5e33e876d3
commit f66d4c4c9d
11 zmienionych plików z 110 dodań i 38 usunięć

0
COPYING 100755 → 100644
Wyświetl plik

4
TODO
Wyświetl plik

@ -4,9 +4,9 @@ Most important TODO is to get streams verified with a good analyzer
Add Blu-ray formats - dealing with vbr audio?
Is the use of double precision for the PCR within its tolerance?
Is there a need to implement full T-STD modelling or use the simpler version currently implemented?
Decide on a buffering model for DVB Subtitles and Teletext
A true VBR mode? How to implement?
Write ATSC PSIP
Write DVB Tables (SIT, NIT, EIT) etc
Sort out T-STD on SMPTE packets
Add more formats
Improve the Makefile

Wyświetl plik

@ -83,6 +83,7 @@
#define PRIVATE_DATA_DESCRIPTOR_TAG 0xe
#define SMOOTHING_BUFFER_DESCRIPTOR_TAG 0x10
#define AVC_DESCRIPTOR_TAG 0x28
#define MPEG2_AAC_AUDIO_DESCRIPTOR 0x2b
#define SVC_EXTENSION_DESCRIPTOR_TAG 0x30
#define MVC_EXTENSION_DESCRIPTOR_TAG 0x31
#define USER_DEFINED_DESCRIPTOR_TAG 0xc4
@ -187,8 +188,9 @@ typedef struct
int audio_type;
/* AAC */
int is_mpeg4;
int aac_is_mpeg4;
int aac_profile;
int aac_channel_map;
/* ATSC */
@ -248,6 +250,8 @@ typedef struct
ts_int_stream_t *streams[MAX_STREAMS];
ts_int_stream_t *pcr_stream;
int pmt_version;
double cur_pcr;
uint64_t last_pcr;
@ -286,6 +290,8 @@ struct ts_writer_t
int pcr_period;
int first_input;
int pat_version;
int network_pid;
int network_id;

0
config.guess vendored 100755 → 100644
Wyświetl plik

0
config.sub vendored 100755 → 100644
Wyświetl plik

2
configure vendored
Wyświetl plik

@ -88,7 +88,7 @@ DEVNULL='/dev/null'
debug="no"
pic="no"
shared="yes"
shared="no"
CFLAGS="$CFLAGS -Wall -I."
LDFLAGS="$LDFLAGS"

0
hdmv/hdmv.c 100755 → 100644
Wyświetl plik

0
hdmv/hdmv.h 100755 → 100644
Wyświetl plik

Wyświetl plik

@ -32,7 +32,7 @@
static int steam_type_table[26][2] =
{
{ LIBMPEGTS_VIDEO_MPEG2, VIDEO_MPEG2 },
{ LIBMPEGTS_VIDEO_AVC, VIDEO_AVC },
{ LIBMPEGTS_VIDEO_AVC, VIDEO_AVC },
{ LIBMPEGTS_AUDIO_MPEG1, AUDIO_MPEG1 },
{ LIBMPEGTS_AUDIO_MPEG2, AUDIO_MPEG2 },
{ LIBMPEGTS_AUDIO_ADTS, AUDIO_ADTS },
@ -64,6 +64,7 @@ static void write_smoothing_buffer_descriptor( bs_t *s, ts_int_program_t *progra
//static void write_video_stream_descriptor( bs_t *s, ts_int_stream_t *stream );
static void write_avc_descriptor( bs_t *s, ts_int_stream_t *stream );
static void write_data_stream_alignment_descriptor( bs_t *s );
static void write_mpeg2_aac_descriptor( bs_t *s, ts_int_stream_t *stream );
static void write_ac3_descriptor( ts_writer_t *w, bs_t *s, int e_ac3 );
static int check_pcr( ts_writer_t *w, ts_int_program_t *program );
@ -267,8 +268,7 @@ int ts_setup_transport_stream( ts_writer_t *w, ts_main_t *params )
w->pcr_period = params->pcr_period ? params->pcr_period : PCR_MAX_RETRANS_TIME;
w->pat_period = params->pat_period ? params->pat_period : PAT_MAX_RETRANS_TIME;
//w->pmt_period = params->pmt_period ? params->pmt_period : PMT_MAX_RETRANS_TIME; FIXME
w->network_id = params->network_id ? params->network_id : DEFAULT_NID;
w->tb.buf_size = TB_SIZE;
@ -401,6 +401,52 @@ int ts_setup_mpegvideo_stream( ts_writer_t *w, int pid, int level, int profile,
return 0;
}
int ts_setup_mpeg2_aac_stream( ts_writer_t *w, int pid, int profile, int channel_map )
{
if( w->ts_type == TS_TYPE_BLU_RAY )
{
fprintf( stderr, "AAC not allowed in Blu-Ray\n" );
return -1;
}
ts_int_stream_t *stream = find_stream( w, pid );
if( !stream )
{
fprintf( stderr, "Invalid PID\n" );
return -1;
}
if( profile < 0 || profile > 1 )
{
fprintf( stderr, "Invalid AAC profile\n" );
return -1;
}
if( channel_map < 0 || channel_map > 7 )
{
fprintf( stderr, "Invalid AAC channel map\n" );
return -1;
}
stream->aac_profile = profile;
stream->aac_is_mpeg4 = 0;
stream->aac_channel_map = channel_map;
/* channel map index is pretty much correct so there's no point in writing a LUT */
int num_channels = channel_map == LIBMPEGTS_MPEG2_AAC_5_POINT_1_CHANNEL ? 5 : channel_map;
for( int i = 0; aac_buffers[i].max_channels != 0; i++ )
{
if( num_channels <= aac_buffers[i].max_channels )
{
stream->rx = aac_buffers[i].rxn;
stream->mb.buf_size = aac_buffers[i].bsn;
}
}
return 0;
}
int ts_setup_mpeg4_aac_stream( ts_writer_t *w, int pid, int profile_and_level, int num_channels )
{
if( w->ts_type == TS_TYPE_BLU_RAY )
@ -409,7 +455,7 @@ int ts_setup_mpeg4_aac_stream( ts_writer_t *w, int pid, int profile_and_level, i
return -1;
}
if( !profile_and_level )
if( profile_and_level <= 0 )
{
fprintf( stderr, "Invalid Profile and Level value\n" );
return -1;
@ -430,7 +476,7 @@ int ts_setup_mpeg4_aac_stream( ts_writer_t *w, int pid, int profile_and_level, i
}
stream->aac_profile = profile_and_level;
stream->is_mpeg4 = 1;
stream->aac_is_mpeg4 = 1;
for( int i = 0; aac_buffers[i].max_channels != 0; i++ )
{
@ -648,7 +694,7 @@ int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t
/* probe the first normal looking ac3 frame if extra data is needed */
if( !stream->atsc_ac3_ctx && stream->stream_format == LIBMPEGTS_AUDIO_AC3 &&
( w->ts_type == TS_TYPE_CABLELABS || w->ts_type == TS_TYPE_ATSC ) &&
frames[i].size > 100 && frames[i].data[0] == 0xb && frames[i].data[1] == 0x77 )
frames[i].size > 100 && frames[i].data[0] == 0xb && frames[i].data[1] == 0x77 )
{
stream->atsc_ac3_ctx = calloc( 1, sizeof(ts_atsc_ac3_info) );
if( !stream->atsc_ac3_ctx )
@ -794,6 +840,7 @@ int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t
pkt_bytes_left -= adapt_field_len;
}
// TODO CableLabs legacy
if( pes->bytes_left >= pkt_bytes_left )
{
write_packet_header( w, s, pes_start, stream->pid, PAYLOAD_ONLY + ((!!adapt_field_len)<<1), &stream->cc );
@ -890,7 +937,7 @@ int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t
else if( w->cbr )
write_null_packet( w );
else
increase_pcr( w, 1 ); /* write imaginary packet in vbr mode */
increase_pcr( w, 1 ); /* write imaginary packet in capped vbr mode */
}
}
@ -990,6 +1037,7 @@ void write_bytes( bs_t *s, uint8_t *bytes, int length )
}
/**** Descriptors ****/
/** MPEG-2 Systems Descriptors **/
/* Registration Descriptor */
void write_registration_descriptor( bs_t *s, int descriptor_tag, int descriptor_length, char *format_id )
{
@ -1064,6 +1112,15 @@ static void write_data_stream_alignment_descriptor( bs_t *s )
bs_write( s, 8, 1 ); // alignment_type
}
static void write_mpeg2_aac_descriptor( bs_t *s, ts_int_stream_t *stream )
{
bs_write( s, 8, MPEG2_AAC_AUDIO_DESCRIPTOR ); // descriptor_tag
bs_write( s, 8, 0x3 ); // descriptor_length
bs_write( s, 8, stream->aac_profile ); // MPEG-2_AAC_profile
bs_write( s, 8, stream->aac_channel_map ); // MPEG-2_AAC_channel_configuration
bs_write( s, 8, 0 ); // MPEG-2_AAC_additional_information (anybody use this?)
}
/* AC-3 Descriptor for DVB and Blu-Ray */
static void write_ac3_descriptor( ts_writer_t *w, bs_t *s, int e_ac3 )
{
@ -1076,6 +1133,7 @@ static void write_ac3_descriptor( ts_writer_t *w, bs_t *s, int e_ac3 )
bs_write( s, 8, 1 ); // descriptor_length
/* does anything need these set? */
bs_write1( s, 0 ); // component_type_flag
bs_write1( s, 0 ); // bsid_flag
bs_write1( s, 0 ); // mainid_flag
@ -1121,7 +1179,7 @@ void increase_pcr( ts_writer_t *w, int num_packets )
ts_int_program_t *program = w->programs[0];
double next_pcr = program->cur_pcr + (8.0 * num_packets * TS_PACKET_SIZE / w->ts_muxrate);
/* buffer drip (TODO: all buffers) */
/* buffer drip (TODO: all buffers?) */
drip_buffer( program, w->rx_sys, &w->tb, next_pcr );
for( int i = 0; i < program->num_streams; i++ )
{
@ -1300,7 +1358,7 @@ static void write_pat( ts_writer_t *w )
bs_write( s, 16, w->ts_id & 0xffff ); // transport_stream_id
bs_write( s, 2, 0x03 ); // reserved
bs_write( s, 5, 0 ); // version_number
bs_write( s, 5, w->pat_version ); // version_number
bs_write1( s, 1 ); // current_next_indicator
bs_write( s, 8, 0 ); // section_number
bs_write( s, 8, 0 ); // last_section_number
@ -1339,11 +1397,7 @@ static int write_pmt( ts_writer_t *w, ts_int_program_t *program )
/* this should never happen */
if( program->num_queued_pmt )
{
if( eject_queued_pmt( w, program, s ) < 0 )
return -1;
return 0;
}
return eject_queued_pmt( w, program, s );
start = bs_pos( s );
write_packet_header( w, s, 1, program->pmt.pid, PAYLOAD_ONLY, &program->pmt.cc );
@ -1361,7 +1415,7 @@ static int write_pmt( ts_writer_t *w, ts_int_program_t *program )
bs_write( &p, 16, program->program_num & 0xffff ); // program_number
bs_write( &p, 2, 0x3 ); // reserved
bs_write( &p, 5, 0 ); // version_number
bs_write( &p, 5, program->pmt_version ); // version_number
bs_write1( &p, 1 ); // current_next_indicator
bs_write( &p, 8, 0 ); // section_number
bs_write( &p, 8, 0 ); // last_section_number
@ -1404,8 +1458,8 @@ static int write_pmt( ts_writer_t *w, ts_int_program_t *program )
/* reset temporary bitstream context for streams loop */
bs_init( &q, temp1, 512 );
// FIXME not in certain cases
write_data_stream_alignment_descriptor( &q );
if( stream->stream_format != LIBMPEGTS_ANCILLARY_RDD11 )
write_data_stream_alignment_descriptor( &q );
if( stream->dvb_au )
{
@ -1439,7 +1493,10 @@ static int write_pmt( ts_writer_t *w, ts_int_program_t *program )
}
else if( stream->stream_format == LIBMPEGTS_AUDIO_ADTS || stream->stream_format == LIBMPEGTS_AUDIO_LATM )
{
if( w->ts_type == TS_TYPE_DVB )
/* strictly speaking in DVB only LATM is allowed for MPEG-4 AAC audio. ADTS is commonly used however */
if( stream->aac_is_mpeg4 )
write_mpeg2_aac_descriptor( &q, stream );
else if( w->ts_type == TS_TYPE_DVB )
write_aac_descriptor( &q, stream );
}
else if( stream->stream_format == LIBMPEGTS_AUDIO_AC3 )
@ -1448,7 +1505,7 @@ static int write_pmt( ts_writer_t *w, ts_int_program_t *program )
if( stream->atsc_ac3_ctx && ( w->ts_type == TS_TYPE_ATSC || w->ts_type == TS_TYPE_CABLELABS ) )
write_atsc_ac3_descriptor( &q, stream->atsc_ac3_ctx );
else
write_ac3_descriptor( w, &q, 0 );
write_ac3_descriptor( w, &q, 0 );
}
else if( stream->stream_format == LIBMPEGTS_AUDIO_EAC3 ||
stream->stream_format == LIBMPEGTS_AUDIO_EAC3_SECONDARY )
@ -1509,7 +1566,7 @@ static int write_pmt( ts_writer_t *w, ts_int_program_t *program )
increase_pcr( w, 1 );
int pos = MIN( bytes_left, length );
length -= MIN( bytes_left, length );
length -= pos;
bytes_left = 184;
@ -1641,10 +1698,7 @@ static int write_pes( ts_writer_t *w, ts_int_program_t *program, ts_frame_t *in_
bs_write( &q, 2, 0x2 ); // '10'
bs_write( &q, 2, 0 ); // PES_scrambling_control
bs_write1( &q, 0 ); // PES_priority
if( stream->stream_format == LIBMPEGTS_ANCILLARY_RDD11 )
bs_write1( &q, 0 ); // data_alignment_indicator
else
bs_write1( &q, 1 ); // data_alignment_indicator
bs_write1( &q, stream->stream_format != LIBMPEGTS_ANCILLARY_RDD11 ); // data_alignment_indicator
bs_write1( &q, 1 ); // copyright
bs_write1( &q, 1 ); // original_or_copy
@ -1690,7 +1744,9 @@ static int write_pes( ts_writer_t *w, ts_int_program_t *program, ts_frame_t *in_
if( stream->stream_format == LIBMPEGTS_VIDEO_MPEG2 || stream->stream_format == LIBMPEGTS_VIDEO_AVC )
bs_write( &s, 16, 0 ); // PES_packet_length
else if( stream->stream_format == LIBMPEGTS_DVB_TELETEXT )
bs_write( &q, 16, 0 ); // PES_packet_length FIXME
{
bs_write( &s, 16, 0 ); // PES_packet_length FIXME
}
else
bs_write( &s, 16, total_size ); // PES_packet_length

Wyświetl plik

@ -250,7 +250,7 @@ typedef struct
*
* PIDs must be between 33 and 8190 (DVB)
* program_num must be between 1 and 8190
* PCR PID can be the same as a stream in the program (usually video PID)
* PCR PID can be the same as a stream in the program (video PID or separate PID recommended)
*
* cablelabs_is_3d -
* Write 3d_MPEG2_descriptor in PMT (CableLabs OC-SP-CEP3.0-I01-100827).
@ -259,8 +259,7 @@ typedef struct
* Smoothing Buffer (Required for ATSC) -
* sb_leak_rate - smoothing buffer leak rate (in units of 400 bits/s)
* sb_size - in bytes
*
* */
*/
typedef struct
{
int pmt_pid;
@ -289,7 +288,7 @@ ts_writer_t *ts_create_writer( void );
* network_pid - PID of the network table (0 otherwise)
* legacy_constraints - Comply with CableLabs legacy contraints in Section 7.3 of Content Encoding Profiles 3.0 Specification
*
* retransmit period in (ms)
* retransmit periods in milliseconds
*
* CURRENT LIMITATIONS
*
@ -315,7 +314,6 @@ typedef struct ts_main_t
int pcr_period;
int pat_period;
int pmt_period;
// FIXME dvb land
int network_id;
@ -357,13 +355,19 @@ int ts_setup_mpegvideo_stream( ts_writer_t *w, int pid, int level, int profile,
#define LIBMPEGTS_MPEG2_AAC_MAIN_PROFILE 0
#define LIBMPEGTS_MPEG2_AAC_LC_PROFILE 1
// TODO
#define LIBMPEGTS_MPEG2_AAC_1_CHANNEL 1
#define LIBMPEGTS_MPEG2_AAC_2_CHANNEL 2
#define LIBMPEGTS_MPEG2_AAC_3_CHANNEL 3
#define LIBMPEGTS_MPEG2_AAC_4_CHANNEL 4
#define LIBMPEGTS_MPEG2_AAC_5_CHANNEL 5
#define LIBMPEGTS_MPEG2_AAC_5_POINT_1_CHANNEL 6
#define LIBMPEGTS_MPEG2_AAC_7_POINT_1_CHANNEL 7
/* Setup / Update MPEG-2 AAC Stream
*
*/
int ts_setup_mpeg2_aac_stream( ts_writer_t *w );
int ts_setup_mpeg2_aac_stream( ts_writer_t *w, int pid, int profile, int channel_map );
#define LIBMPEGTS_MPEG4_AAC_MAIN_PROFILE_LEVEL_1 0x10
#define LIBMPEGTS_MPEG4_AAC_MAIN_PROFILE_LEVEL_2 0x11
@ -380,7 +384,10 @@ int ts_setup_mpeg2_aac_stream( ts_writer_t *w );
/* Setup / Update MPEG-4 AAC Stream
* profile_and_level - self explanatory
* num_channels - number of channels (excluding LFE channel) */
* num_channels - number of channels (excluding LFE channel)
*
* It is the responsibility of the calling application to encapsulate using ADTS or LATM
*/
int ts_setup_mpeg4_aac_stream( ts_writer_t *w, int pid, int profile_and_level, int num_channels );
@ -554,9 +561,12 @@ int ts_setup_dtcp( ts_writer_t *w, uint8_t byte_1, uint8_t byte_2 );
/* ts_frame_t
*
* PID - Packet Identifier (i.e. which stream the payload is associated with)
*
* DTS - Decode Time Stamp (in 90kHz clock ticks - maximum 30 bits)
* PTS - Presentation Time Stamp (in 90kHz clock ticks - maximum 30 bits)
* (PTS and DTS may have codec-specific meanings. See ISO 13818-1 for more information.
* (PTS and DTS may have codec-specific meanings. See ISO 13818-1 for more information)
* Generally, non-video formats have PTS equal to DTS.
*
* This data does not need to be wrapped around )
* random_access - Data contains an "elementary stream access point"
* priority - Indicate payload has priority

0
version.sh 100755 → 100644
Wyświetl plik