kopia lustrzana https://github.com/kierank/libmpegts
Add SCTE-35 support
rodzic
3355e7dde6
commit
3a8b94f844
|
@ -38,3 +38,10 @@ void write_scte_adaptation_descriptor( bs_t *s )
|
|||
bs_write( s, 8, SCTE_ADAPTATION_FIELD_DESCRIPTOR_TAG ); // descriptor_tag
|
||||
bs_write( s, 8, 0 ); // descriptor_length
|
||||
}
|
||||
|
||||
void write_scte35_cue_identifier_descriptor( bs_t *s )
|
||||
{
|
||||
bs_write( s, 8, SCTE35_CUE_IDENTIFIER_DESCRIPTOR_TAG ); // descriptor_tag
|
||||
bs_write( s, 8, 1 ); // descriptor_length
|
||||
bs_write( s, 8, 0 ); // cue_stream_type
|
||||
}
|
|
@ -24,8 +24,10 @@
|
|||
/* Descriptors */
|
||||
#define SCTE_ADAPTATION_FIELD_DESCRIPTOR_TAG 0x97
|
||||
#define CABLELABS_3D_MPEG2_DESCRIPTOR_TAG 0xe8
|
||||
#define SCTE35_CUE_IDENTIFIER_DESCRIPTOR_TAG 0x8a
|
||||
|
||||
void write_cablelabs_3d_descriptor( bs_t *s );
|
||||
void write_scte_adaptation_descriptor( bs_t *s );
|
||||
void write_scte35_cue_identifier_descriptor( bs_t *s );
|
||||
|
||||
#endif
|
||||
|
|
2
common.h
2
common.h
|
@ -44,6 +44,8 @@
|
|||
#define PRIVATE_SECTION 0x05
|
||||
#define PRIVATE_DATA 0x06
|
||||
|
||||
#define DATA_SCTE35 0x86
|
||||
|
||||
#define TS_HEADER_SIZE 4
|
||||
#define TS_PACKET_SIZE 188
|
||||
#define TS_CLOCK 27000000LL
|
||||
|
|
46
libmpegts.c
46
libmpegts.c
|
@ -29,7 +29,7 @@
|
|||
#include "crc/crc.h"
|
||||
#include <math.h>
|
||||
|
||||
static const int stream_type_table[29][2] =
|
||||
static const int stream_type_table[30][2] =
|
||||
{
|
||||
{ LIBMPEGTS_VIDEO_MPEG2, VIDEO_MPEG2 },
|
||||
{ LIBMPEGTS_VIDEO_AVC, VIDEO_AVC },
|
||||
|
@ -59,6 +59,7 @@ static const int stream_type_table[29][2] =
|
|||
{ LIBMPEGTS_ANCILLARY_RDD11, PRIVATE_DATA },
|
||||
{ LIBMPEGTS_ANCILLARY_2038, PRIVATE_DATA },
|
||||
{ LIBMPEGTS_AUDIO_OPUS, PRIVATE_DATA },
|
||||
{ LIBMPEGTS_DATA_SCTE35, DATA_SCTE35 },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
|
@ -478,6 +479,14 @@ static int write_pmt( ts_writer_t *w, ts_int_program_t *program )
|
|||
else if( w->ts_type == TS_TYPE_BLU_RAY )
|
||||
write_registration_descriptor( &q, REGISTRATION_DESCRIPTOR_TAG, 4, "HDMV" );
|
||||
|
||||
for( int i = 0; i < program->num_streams; i++ )
|
||||
{
|
||||
ts_int_stream_t *stream = program->streams[i];
|
||||
|
||||
if( stream->stream_format == LIBMPEGTS_DATA_SCTE35 )
|
||||
write_registration_descriptor( &q, REGISTRATION_DESCRIPTOR_TAG, 4, "CUEI" );
|
||||
}
|
||||
|
||||
/* Optional descriptor(s) here */
|
||||
|
||||
bs_flush( &q );
|
||||
|
@ -496,7 +505,7 @@ 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 );
|
||||
|
||||
if( stream->stream_format != LIBMPEGTS_ANCILLARY_RDD11 )
|
||||
if( stream->stream_format != LIBMPEGTS_ANCILLARY_RDD11 && stream->stream_format != LIBMPEGTS_DATA_SCTE35 )
|
||||
write_data_stream_alignment_descriptor( &q );
|
||||
|
||||
if( stream->dvb_au )
|
||||
|
@ -577,6 +586,8 @@ static int write_pmt( ts_writer_t *w, ts_int_program_t *program )
|
|||
write_registration_descriptor( &q, REGISTRATION_DESCRIPTOR_TAG, 4, "Opus" );
|
||||
write_opus_descriptor( &q, stream );
|
||||
}
|
||||
else if( stream->stream_format == LIBMPEGTS_DATA_SCTE35 )
|
||||
write_scte35_cue_identifier_descriptor( &q );
|
||||
|
||||
// TODO other stream_type descriptors
|
||||
|
||||
|
@ -1653,7 +1664,7 @@ int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t
|
|||
new_pes[i]->write_pulldown_info = frames[i].write_pulldown_info;
|
||||
new_pes[i]->pic_struct = frames[i].pic_struct;
|
||||
}
|
||||
else if( stream->stream_format == LIBMPEGTS_AUDIO_302M )
|
||||
else if( stream->stream_format == LIBMPEGTS_AUDIO_302M || stream->stream_format == LIBMPEGTS_DATA_SCTE35 )
|
||||
new_pes[i]->initial_arrival_time = (new_pes[i]->dts * 300) - frames[i].duration;
|
||||
else if( stream->stream_format == LIBMPEGTS_DVB_TELETEXT )
|
||||
new_pes[i]->initial_arrival_time = (new_pes[i]->dts - 3600) * 300; /* Teletext is special because data can only stay in the buffer for 40ms */
|
||||
|
@ -1691,8 +1702,20 @@ int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Not technically a PES but put it through the same codepath */
|
||||
if ( stream->stream_format == LIBMPEGTS_DATA_SCTE35 )
|
||||
{
|
||||
new_pes[i]->data[0] = 0; // pointer_field
|
||||
memcpy( new_pes[i]->data+1, frames[i].data, frames[i].size );
|
||||
new_pes[i]->size = new_pes[i]->bytes_left = frames[i].size + 1;
|
||||
new_pes[i]->cur_pos = new_pes[i]->data;
|
||||
new_pes[i]->header_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_pes[i]->header_size = write_pes( w, program, &frames[i], new_pes[i] );
|
||||
}
|
||||
}
|
||||
|
||||
if( !w->lowlatency && !initial_queued_pes )
|
||||
{
|
||||
|
@ -1713,7 +1736,7 @@ int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t
|
|||
}
|
||||
|
||||
|
||||
int video_found = 0;
|
||||
int video_found = 0, start = 0;
|
||||
int64_t pcr_stop = 0;
|
||||
|
||||
cur_pcr = get_pcr_int( w, 0 );
|
||||
|
@ -1891,7 +1914,12 @@ int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t
|
|||
|
||||
/* special case where the adaptation_field_length byte is the stuffing */
|
||||
// FIXME except for cablelabs legacy
|
||||
if( stuffing == 1 && !adapt_field_len )
|
||||
|
||||
if( stream->stream_format == LIBMPEGTS_DATA_SCTE35 )
|
||||
{
|
||||
adapt_field_len = 0; /* Theoretically could be made PCR */
|
||||
}
|
||||
else if( stuffing == 1 && !adapt_field_len )
|
||||
{
|
||||
stuffing = flags = 0;
|
||||
adapt_field_len = 1;
|
||||
|
@ -1902,11 +1930,15 @@ int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t
|
|||
stuffing -= 2; /* 2 bytes for adaptation field in this case. NOTE: needs fixing if more private data added */
|
||||
}
|
||||
|
||||
start = bs_pos( s );
|
||||
write_packet_header( w, s, pes_start, stream->pid, PAYLOAD_ONLY + ((!!adapt_field_len)<<1), &stream->cc );
|
||||
if( adapt_field_len )
|
||||
write_adaptation_field( w, s, program, pes, write_pcr, flags, stuffing, 0 );
|
||||
|
||||
write_bytes( s, pes->cur_pos, pes->bytes_left );
|
||||
if( stream->stream_format == LIBMPEGTS_DATA_SCTE35 )
|
||||
write_padding( s, start );
|
||||
|
||||
pes->bytes_left = 0;
|
||||
add_to_buffer( &stream->tb );
|
||||
if( increase_pcr( w, 1, 0 ) < 0 )
|
||||
|
@ -2086,6 +2118,10 @@ int increase_pcr( ts_writer_t *w, int num_packets, int imaginary )
|
|||
drip_buffer( w, program, w->rx_sys, &w->tb, next_pcr );
|
||||
for( int i = 0; i < program->num_streams; i++ )
|
||||
{
|
||||
/* SCTE35 is PSI so not part of T-STD */
|
||||
if( program->streams[i]->stream_format == LIBMPEGTS_DATA_SCTE35 )
|
||||
program->streams[i]->tb.cur_buf = 0;
|
||||
else
|
||||
drip_buffer( w, program, program->streams[i]->rx, &program->streams[i]->tb, next_pcr );
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
|
||||
/* Misc */
|
||||
#define LIBMPEGTS_AUDIO_OPUS 160
|
||||
#define LIBMPEGTS_DATA_SCTE35 161
|
||||
|
||||
/**** Stream IDs ****/
|
||||
/* SMPTE 302M, AC3, DVB subtitles and Teletext use Private Stream 1 */
|
||||
|
|
Ładowanie…
Reference in New Issue