@ -204,6 +204,9 @@ typedef struct OutputStream {
// double sync_ipts; /* dts from the AVPacket of the demuxer in second units */
struct InputStream * sync_ist ; /* input stream to sync against */
int64_t sync_opts ; /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number
/* pts of the first frame encoded for this stream, used for limiting
* recording time */
int64_t first_pts ;
AVBitStreamFilterContext * bitstream_filters ;
AVCodec * enc ;
int64_t max_frames ;
@ -918,6 +921,19 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
}
}
static int check_recording_time ( OutputStream * ost )
{
OutputFile * of = & output_files [ ost - > file_index ] ;
if ( of - > recording_time ! = INT64_MAX & &
av_compare_ts ( ost - > sync_opts - ost - > first_pts , ost - > st - > codec - > time_base , of - > recording_time ,
AV_TIME_BASE_Q ) > = 0 ) {
ost - > is_past_recording_time = 1 ;
return 0 ;
}
return 1 ;
}
static void generate_silence ( uint8_t * buf , enum AVSampleFormat sample_fmt , size_t size )
{
int fill_char = 0x00 ;
@ -958,6 +974,11 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost,
av_log ( NULL , AV_LOG_FATAL , " Audio encoding failed \n " ) ;
exit_program ( 1 ) ;
}
if ( ! check_recording_time ( ost ) )
return 0 ;
ost - > sync_opts + = frame - > nb_samples ;
}
got_packet = 0 ;
@ -977,9 +998,6 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost,
audio_size + = pkt . size ;
}
if ( frame )
ost - > sync_opts + = frame - > nb_samples ;
return pkt . size ;
}
@ -1241,6 +1259,10 @@ static void do_subtitle_out(AVFormatContext *s,
nb = 1 ;
for ( i = 0 ; i < nb ; i + + ) {
ost - > sync_opts = av_rescale_q ( pts , ist - > st - > time_base , enc - > time_base ) ;
if ( ! check_recording_time ( ost ) )
return ;
sub - > pts = av_rescale_q ( pts , ist - > st - > time_base , AV_TIME_BASE_Q ) ;
// start_display_time is required to be 0
sub - > pts + = av_rescale_q ( sub - > start_display_time , ( AVRational ) { 1 , 1000 } , AV_TIME_BASE_Q ) ;
@ -1382,11 +1404,17 @@ static void do_video_out(AVFormatContext *s,
final_picture = in_picture ;
# endif
if ( ! ost - > frame_number )
ost - > first_pts = ost - > sync_opts ;
/* duplicates frame if needed */
for ( i = 0 ; i < nb_frames ; i + + ) {
AVPacket pkt ;
av_init_packet ( & pkt ) ;
if ( ! check_recording_time ( ost ) )
return ;
if ( s - > oformat - > flags & AVFMT_RAWPICTURE & &
enc - > codec - > id = = CODEC_ID_RAWVIDEO ) {
/* raw pictures are written as AVPicture structure to
@ -1723,13 +1751,6 @@ static int check_output_constraints(InputStream *ist, OutputStream *ost)
if ( of - > start_time & & ist - > pts < of - > start_time )
return 0 ;
if ( of - > recording_time ! = INT64_MAX & &
av_compare_ts ( ist - > pts , AV_TIME_BASE_Q , of - > recording_time + of - > start_time ,
( AVRational ) { 1 , 1000000 } ) > = 0 ) {
ost - > is_past_recording_time = 1 ;
return 0 ;
}
return 1 ;
}
@ -1745,6 +1766,12 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
! ost - > copy_initial_nonkeyframes )
return ;
if ( of - > recording_time ! = INT64_MAX & &
ist - > pts > = of - > recording_time + of - > start_time ) {
ost - > is_past_recording_time = 1 ;
return ;
}
/* force the input stream PTS */
if ( ost - > st - > codec - > codec_type = = AVMEDIA_TYPE_AUDIO )
audio_size + = pkt - > size ;