@ -100,6 +100,8 @@ typedef struct AppleHTTPContext {
int end_of_segment ;
int first_packet ;
int64_t first_timestamp ;
int64_t seek_timestamp ;
int seek_flags ;
AVIOInterruptCB * interrupt_callback ;
} AppleHTTPContext ;
@ -545,6 +547,7 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
c - > first_packet = 1 ;
c - > first_timestamp = AV_NOPTS_VALUE ;
c - > seek_timestamp = AV_NOPTS_VALUE ;
return 0 ;
fail :
@ -604,14 +607,44 @@ start:
/* Make sure we've got one buffered packet from each open variant
* stream */
if ( var - > needed & & ! var - > pkt . data ) {
ret = av_read_frame ( var - > ctx , & var - > pkt ) ;
if ( ret < 0 ) {
if ( ! url_feof ( & var - > pb ) )
return ret ;
reset_packet ( & var - > pkt ) ;
} else {
if ( c - > first_timestamp = = AV_NOPTS_VALUE )
c - > first_timestamp = var - > pkt . dts ;
while ( 1 ) {
int64_t ts_diff ;
ret = av_read_frame ( var - > ctx , & var - > pkt ) ;
if ( ret < 0 ) {
if ( ! url_feof ( & var - > pb ) ) {
return ret ;
} else {
if ( ( var - > cur_seq_no - var - > start_seq_no ) = = ( var - > n_segments ) ) {
return AVERROR_EOF ;
}
}
reset_packet ( & var - > pkt ) ;
} else {
if ( c - > first_timestamp = = AV_NOPTS_VALUE )
c - > first_timestamp = var - > pkt . dts ;
}
if ( c - > seek_timestamp = = AV_NOPTS_VALUE )
break ;
if ( var - > pkt . dts = = AV_NOPTS_VALUE ) {
c - > seek_timestamp = AV_NOPTS_VALUE ;
break ;
}
ts_diff = var - > pkt . dts - c - > seek_timestamp ;
if ( ts_diff > = 0 ) {
if ( c - > seek_flags & AVSEEK_FLAG_ANY ) {
c - > seek_timestamp = AV_NOPTS_VALUE ;
break ;
}
/* Seek to keyframe */
if ( var - > pkt . flags & AV_PKT_FLAG_KEY ) {
c - > seek_timestamp = AV_NOPTS_VALUE ;
break ;
}
}
}
}
/* Check if this stream has the packet with the lowest dts */
@ -652,10 +685,17 @@ static int applehttp_read_seek(AVFormatContext *s, int stream_index,
if ( ( flags & AVSEEK_FLAG_BYTE ) | | ! c - > variants [ 0 ] - > finished )
return AVERROR ( ENOSYS ) ;
c - > seek_timestamp = timestamp ;
c - > seek_flags = flags ;
timestamp = av_rescale_rnd ( timestamp , 1 , stream_index > = 0 ?
s - > streams [ stream_index ] - > time_base . den :
AV_TIME_BASE , flags & AVSEEK_FLAG_BACKWARD ?
AV_ROUND_DOWN : AV_ROUND_UP ) ;
if ( s - > duration < c - > seek_timestamp ) {
c - > seek_timestamp = AV_NOPTS_VALUE ;
return AVERROR ( EIO ) ;
}
ret = AVERROR ( EIO ) ;
for ( i = 0 ; i < c - > n_variants ; i + + ) {
/* Reset reading */
@ -683,6 +723,8 @@ static int applehttp_read_seek(AVFormatContext *s, int stream_index,
}
pos + = var - > segments [ j ] - > duration ;
}
if ( ret ! = 0 )
c - > seek_timestamp = AV_NOPTS_VALUE ;
}
return ret ;
}