@ -23,6 +23,7 @@
# include "libavutil/dict.h"
# include "libavutil/mathematics.h"
# include "avformat.h"
# include "avlanguage.h"
# include "avio_internal.h"
# include "internal.h"
# include "riff.h"
@ -220,6 +221,8 @@ typedef struct ASFContext {
uint32_t seqno ;
int is_streamed ;
ASFStream streams [ 128 ] ; ///< it's max number and it's not that big
const char * languages [ 128 ] ;
int nb_languages ;
/* non streamed additonnal info */
uint64_t nb_packets ; ///< how many packets are there in the file, invalid if broadcasting
int64_t duration ; ///< in 100ns units
@ -403,6 +406,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size,
bit_rate = 0 ;
for ( n = 0 ; n < s - > nb_streams ; n + + ) {
AVDictionaryEntry * entry ;
enc = s - > streams [ n ] - > codec ;
avpriv_set_pts_info ( s - > streams [ n ] , 32 , 1 , 1000 ) ; /* 32 bit pts in ms */
@ -412,6 +416,27 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size,
& & enc - > sample_aspect_ratio . num > 0
& & enc - > sample_aspect_ratio . den > 0 )
has_aspect_ratio + + ;
entry = av_dict_get ( s - > streams [ n ] - > metadata , " language " , NULL , 0 ) ;
if ( entry ) {
const char * iso6391lang = av_convert_lang_to ( entry - > value , AV_LANG_ISO639_1 ) ;
if ( iso6391lang ) {
int i ;
for ( i = 0 ; i < asf - > nb_languages ; i + + ) {
if ( ! strcmp ( asf - > languages [ i ] , iso6391lang ) ) {
asf - > streams [ n ] . stream_language_index = i ;
break ;
}
}
if ( i > = asf - > nb_languages ) {
asf - > languages [ asf - > nb_languages ] = iso6391lang ;
asf - > streams [ n ] . stream_language_index = asf - > nb_languages ;
asf - > nb_languages + + ;
}
}
} else {
asf - > streams [ n ] . stream_language_index = 128 ;
}
}
if ( asf - > is_streamed ) {
@ -441,13 +466,48 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size,
avio_wl32 ( pb , bit_rate ? bit_rate : - 1 ) ; /* Maximum data rate in bps */
end_header ( pb , hpos ) ;
/* unknown headers */
/* header_exten sion */
hpos = put_header ( pb , & ff_asf_head1_guid ) ;
ff_put_guid ( pb , & ff_asf_head2_guid ) ;
avio_wl16 ( pb , 6 ) ;
avio_wl32 ( pb , 0 ) ; /* length, to be filled later */
if ( asf - > nb_languages ) {
int64_t hpos2 ;
int i ;
hpos2 = put_header ( pb , & ff_asf_language_guid ) ;
avio_wl16 ( pb , asf - > nb_languages ) ;
for ( i = 0 ; i < asf - > nb_languages ; i + + ) {
avio_w8 ( pb , 6 ) ;
avio_put_str16le ( pb , asf - > languages [ i ] ) ;
}
end_header ( pb , hpos2 ) ;
for ( n = 0 ; n < s - > nb_streams ; n + + ) {
int64_t es_pos ;
if ( asf - > streams [ n ] . stream_language_index > 127 )
continue ;
es_pos = put_header ( pb , & ff_asf_extended_stream_properties_object ) ;
avio_wl64 ( pb , 0 ) ; /* start time */
avio_wl64 ( pb , 0 ) ; /* end time */
avio_wl32 ( pb , s - > streams [ n ] - > codec - > bit_rate ) ; /* data bitrate bps */
avio_wl32 ( pb , 5000 ) ; /* buffer size ms */
avio_wl32 ( pb , 0 ) ; /* initial buffer fullness */
avio_wl32 ( pb , s - > streams [ n ] - > codec - > bit_rate ) ; /* peak data bitrate */
avio_wl32 ( pb , 5000 ) ; /* maximum buffer size ms */
avio_wl32 ( pb , 0 ) ; /* max initial buffer fullness */
avio_wl32 ( pb , 0 ) ; /* max object size */
avio_wl32 ( pb , ( ! asf - > is_streamed & & pb - > seekable ) < < 1 ) ; /* flags - seekable */
avio_wl16 ( pb , n + 1 ) ; /* stream number */
avio_wl16 ( pb , asf - > streams [ n ] . stream_language_index ) ; /* language id index */
avio_wl64 ( pb , 0 ) ; /* avg time per frame */
avio_wl16 ( pb , 0 ) ; /* stream name count */
avio_wl16 ( pb , 0 ) ; /* payload extension system count */
end_header ( pb , es_pos ) ;
}
}
if ( has_aspect_ratio ) {
int64_t hpos2 ;
avio_wl32 ( pb , 26 + has_aspect_ratio * 84 ) ;
hpos2 = put_header ( pb , & ff_asf_metadata_header ) ;
avio_wl16 ( pb , 2 * has_aspect_ratio ) ;
for ( n = 0 ; n < s - > nb_streams ; n + + ) {
@ -475,8 +535,13 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size,
}
}
end_header ( pb , hpos2 ) ;
} else {
avio_wl32 ( pb , 0 ) ;
}
{
int64_t pos1 ;
pos1 = avio_tell ( pb ) ;
avio_seek ( pb , hpos + 42 , SEEK_SET ) ;
avio_wl32 ( pb , pos1 - hpos - 46 ) ;
avio_seek ( pb , pos1 , SEEK_SET ) ;
}
end_header ( pb , hpos ) ;