@ -68,7 +68,7 @@ typedef struct OutputStream {
int init_range_length ;
int nb_segments , segments_size , segment_index ;
Segment * * segments ;
int64_t first_dts , start_dts , end_d ts ;
int64_t first_pts , start_pts , max_p ts ;
int bit_rate ;
char bandwidth_str [ 64 ] ;
@ -627,6 +627,7 @@ static int dash_write_header(AVFormatContext *s)
os - > init_start_pos = 0 ;
av_dict_set ( & opts , " movflags " , " frag_custom+dash+delay_moov " , 0 ) ;
av_dict_set ( & opts , " use_editlist " , " 1 " , 0 ) ;
if ( ( ret = avformat_write_header ( ctx , & opts ) ) < 0 ) {
goto fail ;
}
@ -647,8 +648,8 @@ static int dash_write_header(AVFormatContext *s)
c - > has_audio = 1 ;
set_codec_str ( s , os - > ctx - > streams [ 0 ] - > codec , os - > codec_str , sizeof ( os - > codec_str ) ) ;
os - > first_d ts = AV_NOPTS_VALUE ;
os - > end_d ts = AV_NOPTS_VALUE ;
os - > first_p ts = AV_NOPTS_VALUE ;
os - > max_p ts = AV_NOPTS_VALUE ;
os - > segment_index = 1 ;
}
@ -687,6 +688,8 @@ static int add_segment(OutputStream *os, const char *file,
return AVERROR ( ENOMEM ) ;
av_strlcpy ( seg - > file , file , sizeof ( seg - > file ) ) ;
seg - > time = time ;
if ( seg - > time < 0 ) // If pts<0, it is expected to be cut away with an edit list
seg - > time = 0 ;
seg - > duration = duration ;
seg - > start_pos = start_pos ;
seg - > range_length = range_length ;
@ -770,7 +773,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream)
start_pos = avio_tell ( os - > ctx - > pb ) ;
if ( ! c - > single_file ) {
dash_fill_tmpl_params ( filename , sizeof ( filename ) , c - > media_seg_name , i , os - > segment_index , os - > bit_rate , os - > start_d ts ) ;
dash_fill_tmpl_params ( filename , sizeof ( filename ) , c - > media_seg_name , i , os - > segment_index , os - > bit_rate , os - > start_p ts ) ;
snprintf ( full_path , sizeof ( full_path ) , " %s%s " , c - > dirname , filename ) ;
snprintf ( temp_path , sizeof ( temp_path ) , " %s.tmp " , full_path ) ;
ret = ffurl_open ( & os - > out , temp_path , AVIO_FLAG_WRITE , & s - > interrupt_callback , NULL ) ;
@ -795,7 +798,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream)
if ( ret < 0 )
break ;
}
add_segment ( os , filename , os - > start_d ts , os - > end_d ts - os - > start_d ts , start_pos , range_length , index_length ) ;
add_segment ( os , filename , os - > start_p ts , os - > max_p ts - os - > start_p ts , start_pos , range_length , index_length ) ;
av_log ( s , AV_LOG_VERBOSE , " Representation %d media segment %d written to: %s \n " , i , os - > segment_index , full_path ) ;
}
@ -834,25 +837,25 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt)
// If forcing the stream to start at 0, the mp4 muxer will set the start
// timestamps to 0. Do the same here, to avoid mismatches in duration/timestamps.
if ( os - > first_d ts = = AV_NOPTS_VALUE & &
if ( os - > first_p ts = = AV_NOPTS_VALUE & &
s - > avoid_negative_ts = = AVFMT_AVOID_NEG_TS_MAKE_ZERO ) {
pkt - > pts - = pkt - > dts ;
pkt - > dts = 0 ;
}
if ( os - > first_d ts = = AV_NOPTS_VALUE )
os - > first_d ts = pkt - > d ts;
if ( os - > first_p ts = = AV_NOPTS_VALUE )
os - > first_p ts = pkt - > p ts;
if ( ( ! c - > has_video | | st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO ) & &
pkt - > flags & AV_PKT_FLAG_KEY & & os - > packets_written & &
av_compare_ts ( pkt - > d ts - os - > first_d ts , st - > time_base ,
av_compare_ts ( pkt - > p ts - os - > first_p ts , st - > time_base ,
seg_end_duration , AV_TIME_BASE_Q ) > = 0 ) {
int64_t prev_duration = c - > last_duration ;
c - > last_duration = av_rescale_q ( pkt - > d ts - os - > start_d ts ,
c - > last_duration = av_rescale_q ( pkt - > p ts - os - > start_p ts ,
st - > time_base ,
AV_TIME_BASE_Q ) ;
c - > total_duration = av_rescale_q ( pkt - > d ts - os - > first_d ts ,
c - > total_duration = av_rescale_q ( pkt - > p ts - os - > first_p ts ,
st - > time_base ,
AV_TIME_BASE_Q ) ;
@ -873,12 +876,15 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt)
// If we wrote a previous segment, adjust the start time of the segment
// to the end of the previous one (which is the same as the mp4 muxer
// does). This avoids gaps in the timeline.
if ( os - > end_d ts ! = AV_NOPTS_VALUE )
os - > start_d ts = os - > end_d ts;
if ( os - > max_p ts ! = AV_NOPTS_VALUE )
os - > start_p ts = os - > max_p ts;
else
os - > start_d ts = pkt - > d ts;
os - > start_p ts = pkt - > p ts;
}
os - > end_dts = pkt - > dts + pkt - > duration ;
if ( os - > max_pts = = AV_NOPTS_VALUE )
os - > max_pts = pkt - > pts + pkt - > duration ;
else
os - > max_pts = FFMAX ( os - > max_pts , pkt - > pts + pkt - > duration ) ;
os - > packets_written + + ;
return ff_write_chained ( os - > ctx , 0 , pkt , s ) ;
}
@ -892,10 +898,10 @@ static int dash_write_trailer(AVFormatContext *s)
// If no segments have been written so far, try to do a crude
// guess of the segment duration
if ( ! c - > last_duration )
c - > last_duration = av_rescale_q ( os - > end_d ts - os - > start_d ts ,
c - > last_duration = av_rescale_q ( os - > max_p ts - os - > start_p ts ,
s - > streams [ 0 ] - > time_base ,
AV_TIME_BASE_Q ) ;
c - > total_duration = av_rescale_q ( os - > end_d ts - os - > first_d ts ,
c - > total_duration = av_rescale_q ( os - > max_p ts - os - > first_p ts ,
s - > streams [ 0 ] - > time_base ,
AV_TIME_BASE_Q ) ;
}