From: Vadim Belov <vad...@vadimb-t440.nice.com> --- libavformat/Makefile | 2 +- libavformat/asf.c | 4 + libavformat/asf.h | 17 ++-- libavformat/asf_ex.h | 27 ++----- libavformat/asf_trim.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++- libavformat/asf_trim.h | 86 +++++++++++++++------ libavformat/asfdec.c | 29 ++----- libavformat/asfenc.c | 93 ++++++++++++---------- 8 files changed, 345 insertions(+), 119 deletions(-)
diff --git a/libavformat/Makefile b/libavformat/Makefile index bca9d5b..2743467 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -84,7 +84,7 @@ OBJS-$(CONFIG_APNG_MUXER) += apngenc.o OBJS-$(CONFIG_AQTITLE_DEMUXER) += aqtitledec.o subtitles.o OBJS-$(CONFIG_ASF_DEMUXER) += asfdec.o asf.o asfcrypt.o \ avlanguage.o -OBJS-$(CONFIG_ASF_MUXER) += asfenc.o asf.o +OBJS-$(CONFIG_ASF_MUXER) += asfenc.o asf.o asf_trim.o OBJS-$(CONFIG_ASS_DEMUXER) += assdec.o subtitles.o OBJS-$(CONFIG_ASS_MUXER) += assenc.o OBJS-$(CONFIG_AST_DEMUXER) += ast.o astdec.o diff --git a/libavformat/asf.c b/libavformat/asf.c index 80d24db..d2a0a8f 100644 --- a/libavformat/asf.c +++ b/libavformat/asf.c @@ -143,6 +143,10 @@ const ff_asf_guid ff_asf_digital_signature = { 0xfc, 0xb3, 0x11, 0x22, 0x23, 0xbd, 0xd2, 0x11, 0xb4, 0xb7, 0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e }; +const ff_asf_guid ff_asf_index_header = { + 0xd3, 0x29, 0xe2, 0xd6, 0xda, 0x35, 0xd1, 0x11, 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe +}; + /* List of official tags at http://msdn.microsoft.com/en-us/library/dd743066(VS.85).aspx */ const AVMetadataConv ff_asf_metadata_conv[] = { { "WM/AlbumArtist", "album_artist" }, diff --git a/libavformat/asf.h b/libavformat/asf.h index 6dce410..7e8d8d3 100644 --- a/libavformat/asf.h +++ b/libavformat/asf.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2015 Vadim Belov * * This file is part of FFmpeg. * @@ -26,11 +27,10 @@ #include "metadata.h" #include "riff.h" -// Packet size according to the size that ACX File Creator writes to its output packets: -// ASF_PACKET_SIZE is 8192, but in CASFFile::InitAsfPckt it is decremented! Most possibly by 100 -// Bottom line: in the ASF core file the value is 8032 -#define PACKET_SIZE 8032 -//#define PACKET_SIZE 3200 +#define PACKET_SIZE 3200 + +// "asf_ex.h" is IMPORTANT to be placed After PACKET_SIZE definition +#include "asf_ex.h" typedef struct ASFPayload { uint8_t type; @@ -62,6 +62,8 @@ typedef struct ASFStream { int payload_ext_ct; ASFPayload payload[8]; + + ASFIndexData idx_data; } ASFStream; typedef struct ASFMainHeader { @@ -127,7 +129,7 @@ extern const ff_asf_guid ff_asf_language_guid; extern const ff_asf_guid ff_asf_content_encryption; extern const ff_asf_guid ff_asf_ext_content_encryption; extern const ff_asf_guid ff_asf_digital_signature; - +extern const ff_asf_guid ff_asf_index_header; extern const AVMetadataConv ff_asf_metadata_conv[]; #define ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT 0x80 //1000 0000 @@ -193,7 +195,4 @@ extern const AVMetadataConv ff_asf_metadata_conv[]; extern AVInputFormat ff_asf_demuxer; -// TODO: move to .c ? -#define DIRECTION_DICT_KEY "direction" - #endif /* AVFORMAT_ASF_H */ diff --git a/libavformat/asf_ex.h b/libavformat/asf_ex.h index 206bf62..6655424 100644 --- a/libavformat/asf_ex.h +++ b/libavformat/asf_ex.h @@ -18,12 +18,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVFORMAT_ASF_STREAM_IDX_H -#define AVFORMAT_ASF_STREAM_IDX_H +#ifndef AVFORMAT_ASF_EX_H +#define AVFORMAT_ASF_EX_H #include <stdint.h> -#include "avformat.h" - // Packet size according to the size that ACX File Creator writes to its output packets: // ASF_PACKET_SIZE is 8192, but in CASFFile::InitAsfPckt it is decremented. @@ -33,8 +31,10 @@ #endif #define PACKET_SIZE 8032 +#define STREAM_DIRECTION_STR "streamDirection" #define DIRECTION_DICT_KEY "direction" - +#define NO_STREAM_DIRECTION -1 +#define ASF_MAX_STREAMS_NUM 128 typedef struct ASFStreamIndex { // Index Entry value uint64_t offset; @@ -48,19 +48,4 @@ typedef struct ASFIndexData { int64_t duration_overall; } ASFIndexData; - -int upadte_indices( - ASFStream streams[MAX_STREAMS_NUM], //AVFormatContext *s, - uint64_t pkt_time, - uint32_t pkt_num, - uint64_t packet_offset, - int stream_index, - int64_t pkt_duration); - -int asf_write_indices(AVFormatContext *s); - -int should_iterate_block(int i, ASFIndexData *idx, uint64_t curr_offset); - -int get_num_entries(AVFormatContext *s); - -#endif /* AVFORMAT_ASF_STREAM_IDX_H */ +#endif /* AVFORMAT_ASF_EX_H */ diff --git a/libavformat/asf_trim.c b/libavformat/asf_trim.c index d4ef5a6..60017e4 100644 --- a/libavformat/asf_trim.c +++ b/libavformat/asf_trim.c @@ -18,9 +18,207 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "asfstreamindex.h" +#include "asf_trim.h" +#define ASF_INDEX_ENTRY_TIME_INTERVAL 10000 +#define SPECIFIER_INDEX_TYPE 3 -const ff_asf_guid ff_asf_index_header = { - 0xd3, 0x29, 0xe2, 0xd6, 0xda, 0x35, 0xd1, 0x11, 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe -}; +#define BLOCK_PART 0xFFFFFFFF00000000 +#define OFFSET_PART 0x00000000FFFFFFFF +#define INVALID_OFFSET 0xFFFFFFFF + +int asf_get_streams_direction(AVFormatContext *s) +{ + int ret = 0; + int n; + for (n = 0; n < s->nb_streams; n++) { + AVDictionaryEntry *t = av_dict_get( + s->streams[n]->metadata, DIRECTION_DICT_KEY, NULL, 0); + + av_log(s, AV_LOG_DEBUG, "direction metadata ptr is %p\n", t); + + if (t) ret++; + } + return ret; +} + +void set_stream_direction( + AVFormatContext *s, + int direction[ASF_MAX_STREAMS_NUM], + AVStream *st, + int i) +{ + if(direction[i] != NO_STREAM_DIRECTION) { + char buffer[32]; + sprintf(buffer, "%d %d", i, direction[i]); + av_dict_set(&st->metadata, DIRECTION_DICT_KEY, buffer, 0); + } +} + +int asf_alloc_streams_index( + ASFStream streams[ASF_MAX_STREAMS_NUM], + int num_streams, + int block_size) +{ + int i; + for (i = 0; i < num_streams; ++i){ + ASFIndexData *idx = &streams[i].idx_data; + + idx->indices = av_malloc(sizeof(ASFStreamIndex)* block_size); + if (!idx->indices) return AVERROR(ENOMEM); + + idx->indices_max_count = block_size; + idx->duration_overall = 0; + idx->next_duration_mark = 0; + idx->indices_count = 0; + } + + return 0; +} + +void asf_free_streams_index( + ASFStream streams[ASF_MAX_STREAMS_NUM], + int num_streams) +{ + int i; + for (i = 0; i < num_streams; ++i) { + av_freep(&streams[i].idx_data.indices); + } +} + +int upadte_indices( + ASFStream streams[ASF_MAX_STREAMS_NUM], + uint64_t pkt_time, + uint64_t packet_offset, + int stream_index, + int64_t pkt_duration, + uint32_t asf_index_block, + uint64_t asf_data_start) +{ + ASFIndexData *idx = &streams[stream_index].idx_data; + + // reallocate if size too small + if (idx->indices_count > idx->indices_max_count) { + int err; + idx->indices_max_count = (pkt_time + asf_index_block) & ~(asf_index_block - 1); + if ((err = av_reallocp_array(&idx, + idx->indices_max_count, + sizeof(*idx->indices))) < 0) { + idx->indices_max_count = 0; + return err; + } + } + + // update offset if reached the duration mark + idx->duration_overall += pkt_duration; + if (idx->duration_overall > idx->next_duration_mark) { + idx->indices[idx->indices_count].offset = packet_offset - asf_data_start; + idx->indices_count++; + idx->next_duration_mark += ASF_INDEX_ENTRY_TIME_INTERVAL; + } + + return 0; +} + +static int get_num_entries( + ASFStream streams[ASF_MAX_STREAMS_NUM], + int num_streams) +{ + int i; + int ret = 0; + for (i = 0; i < num_streams; ++i){ + ASFIndexData *idx = &(streams[i].idx_data); + ret = FFMAX(ret, idx->indices_count); + } + return ret; +} + +static int should_iterate_block(int i, ASFIndexData *idx, uint64_t curr_offset) +{ + if (i + 1 < idx->indices_count) { + uint64_t next_offset = idx->indices[i + 1].offset; + uint64_t curr_block = curr_offset & BLOCK_PART; + uint64_t next_block = next_offset & BLOCK_PART; + return curr_block != next_block; + } + + return 0; +} + +int asf_write_indices( + AVFormatContext *s, + ASFStream streams[ASF_MAX_STREAMS_NUM], + int num_streams) +{ + AVIOContext *pb = s->pb; + + int i, j; + int num_blocks = 0; + int num_entries = get_num_entries(streams, num_streams); + + int64_t blocks_pos, end_of_indices; + + char write_index = 1; + char iterate_block = 1; + + av_log(s, AV_LOG_DEBUG, "Write Index object for %d streams with %d entries.\n", + num_streams, num_entries); + + ff_put_guid(pb, &ff_asf_index_header); + avio_wl64(pb, 34 + 4 * num_streams + 4 + 8 * num_streams + 4 * num_entries*num_streams); + avio_wl32(pb, ASF_INDEX_ENTRY_TIME_INTERVAL); // interval + avio_wl16(pb, num_streams); // specifiers count + + blocks_pos = avio_tell(pb); + avio_wl32(pb, 0); // rewrite later + + // write specifiers + for (i = 0; i < num_streams; i++) { + avio_wl16(pb, i + 1); + avio_wl16(pb, SPECIFIER_INDEX_TYPE); + } + + avio_wl32(pb, num_entries); // Index Entry Count + + for (i = 0; write_index && i < num_entries; ++i) { + + // block header + if (iterate_block) { + ++num_blocks; + + for (j = 0; j < num_streams; ++j) { + avio_wl64(pb, 0); + } + iterate_block = 0; + } + + // block content + for (j = 0; j < num_streams; ++j) { + ASFIndexData *idx = &(streams[j].idx_data); + uint32_t offset = INVALID_OFFSET; + if (i < idx->indices_count) { + uint64_t full_offset = idx->indices[i].offset; + offset = (uint32_t)full_offset & OFFSET_PART; + iterate_block = should_iterate_block(i, idx, full_offset); + } + else { + write_index = 0; + offset = INVALID_OFFSET; + av_log(s, AV_LOG_WARNING, "Index: invalid offset (%d,%d)\n", i, j); + } + avio_wl32(pb, offset); + } + } + + end_of_indices = avio_tell(pb); + + // rewrite blocks count and return file descriptor to end + avio_seek(pb, blocks_pos, SEEK_SET); + avio_wl32(pb, num_blocks); + avio_seek(pb, end_of_indices, SEEK_SET); + + av_log(s, AV_LOG_DEBUG, "Write Index object for %d streams with %d entries done.\n", + num_streams, num_entries); + + return 0; +} diff --git a/libavformat/asf_trim.h b/libavformat/asf_trim.h index 424bf6d..506b2f8 100644 --- a/libavformat/asf_trim.h +++ b/libavformat/asf_trim.h @@ -18,32 +18,74 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVFORMAT_ASF_STREAM_IDX_H -#define AVFORMAT_ASF_STREAM_IDX_H +#ifndef ASF_TRIM_H +#define ASF_TRIM_H -// Packet size according to the size that ACX File Creator writes to its output packets: -// ASF_PACKET_SIZE is 8192, but in CASFFile::InitAsfPckt it is decremented. -// Bottom line: in the ASF core file the value is 8032 -#ifdef PACKET_SIZE -#undef PACKET_SIZE -#endif -#define PACKET_SIZE 8032 +#include "asf.h" +#include "avformat.h" -typedef struct ASFStreamIndex { // Index Entry value - uint64_t offset; -} ASFStreamIndex; +/** +* Get stream direction attributes values from input ASF file +* +* @return number of stream direction attributes in all streams +*/ +int asf_get_streams_direction(AVFormatContext *s); -typedef struct ASFIndexData { - ASFStreamIndex* indices; // array of ASFStreamIndex - uint32_t indices_max_count; // allocated size - uint32_t next_duration_mark; // TODO: check type - uint32_t indices_count; // current index - int64_t duration_overall; -} ASFIndexData; +/** +* Set stream direction attributes in output ASF file +*/ +void set_stream_direction( + AVFormatContext *s, + int direction[ASF_MAX_STREAMS_NUM], + AVStream *st, + int i); -extern const ff_asf_guid ff_asf_index_header; -#define DIRECTION_DICT_KEY "direction" +/** +* Allocate index object for a stream +* +* @return error code: 0 iff success +*/ +int asf_alloc_streams_index( + ASFStream streams[ASF_MAX_STREAMS_NUM], + int num_streams, + int block_size); -#endif /* AVFORMAT_ASF_STREAM_IDX_H */ + +/** +* Free index object for a stream +*/ +void asf_free_streams_index( + ASFStream streams[ASF_MAX_STREAMS_NUM], + int num_streams); + + +/** +* Update index object of the packet's stream if necessary: +* when packet time has reached the defined interval between +* the indices +* +* @return error code: 0 iff success +*/ +int upadte_indices( + ASFStream streams[ASF_MAX_STREAMS_NUM], + uint64_t pkt_time, + uint64_t packet_offset, + int stream_index, + int64_t pkt_duration, + uint32_t asf_index_block, + uint64_t asf_data_start); + + +/** +* Allocate index object for a stream +* +* @return error code: 0 iff success +*/ +int asf_write_indices( + AVFormatContext *s, + ASFStream streams[ASF_MAX_STREAMS_NUM], + int num_streams); + +#endif /* ASF_TRIM_H */ diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index bf4ef75..826b80f 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -1,6 +1,7 @@ /* * ASF compatible demuxer * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2015 Vadim Belov * * This file is part of FFmpeg. * @@ -38,8 +39,7 @@ #include "riff.h" #include "asf.h" #include "asfcrypt.h" - -#define NO_STREAM_DIRECTION -1 +#include "asf_trim.h" typedef struct ASFContext { const AVClass *class; @@ -83,10 +83,7 @@ typedef struct ASFContext { int no_resync_search; int export_xmp; - int direction[128]; - //AVRational direction[128]; ///< pair: num={ 0 = doesn't have direction, 1 = has direction } - // ///< den={ direction value } - + int direction[ASF_MAX_STREAMS_NUM]; } ASFContext; static const AVOption options[] = { @@ -677,7 +674,7 @@ static int asf_read_metadata(AVFormatContext *s, int64_t size) avio_skip(pb, name_len - ret); av_log(s, AV_LOG_TRACE, "%d stream %d name_len %2d type %d len %4d <%s>\n", i, stream_num, name_len, value_type, value_len, name); - + asf->direction[stream_num] = NO_STREAM_DIRECTION; if (!strcmp(name, "AspectRatioX")){ @@ -688,15 +685,14 @@ static int asf_read_metadata(AVFormatContext *s, int64_t size) int aspect_y = get_value(s->pb, value_type, 16); if(stream_num < 128) asf->dar[stream_num].den = aspect_y; - } else if(!strcmp(name, "streamDirection") && // V - 0 < stream_num){ // V + } else if(!strcmp(name, STREAM_DIRECTION_STR) && + 0 < stream_num && stream_num < 128){ int direction = get_value(s->pb, value_type, value_len); - av_log(s, AV_LOG_INFO, "+++++++++++++++ stream %d Direction is %d\n", // V + av_log(s, AV_LOG_DEBUG, "stream %d Direction is %d\n", stream_num, direction); asf->direction[stream_num] = direction; - } else { get_tag(s, name, value_type, value_len, 16); } @@ -872,17 +868,8 @@ static int asf_read_header(AVFormatContext *s) &st->sample_aspect_ratio.den, asf->dar[0].num, asf->dar[0].den, INT_MAX); + set_stream_direction(s, asf->direction, st, i); - if(asf->direction[i] != NO_STREAM_DIRECTION) { - char buffer[32]; - sprintf(buffer, "%d %d", i, asf->direction[i]); - - av_log(s, AV_LOG_INFO, "++++++++++++ setting str direction %s in stream (%d,%d)\n", - buffer, i, stream_num); - //av_dict_set(&s->streams[i]->metadata, DIRECTION_DICT_KEY, buffer, 0); - av_dict_set(&st->metadata, DIRECTION_DICT_KEY, buffer, 0); - } - av_log(s, AV_LOG_TRACE, "i=%d, st->codec->codec_type:%d, asf->dar %d:%d sar=%d:%d\n", i, st->codec->codec_type, asf->dar[i].num, asf->dar[i].den, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index 59673d2..a554da5 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -1,6 +1,7 @@ /* * ASF muxer * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2015 Vadim Belov * * This file is part of FFmpeg. * @@ -27,6 +28,7 @@ #include "internal.h" #include "riff.h" #include "asf.h" +#include "asf_trim.h" #define ASF_INDEXED_INTERVAL 10000000 #define ASF_INDEX_BLOCK (1<<9) @@ -218,7 +220,7 @@ static const AVCodecTag codec_asf_bmp_tags[] = { { AV_CODEC_ID_NONE, 0 }, }; -// V: in order to keep preroll time 0 redefine: +// Preroll must be 0 in order to be consistent with player #define PREROLL_TIME 0 //#define PREROLL_TIME 3100 @@ -352,33 +354,28 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, AVDictionaryEntry *tags[5]; int header_size, n, extra_size, extra_size2, wav_extra_size, file_time; int has_title, has_aspect_ratio = 0; - int has_direction = 0; // V - int metadata_count; + int has_direction = 0; + int metadata_count; AVCodecContext *enc; int64_t header_offset, cur_pos, hpos; int bit_rate; int64_t duration; ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL); - - av_log(s, AV_LOG_ERROR, "============ ASF Streams num is %d\n", s->nb_streams); // V - + tags[0] = av_dict_get(s->metadata, "title", NULL, 0); tags[1] = av_dict_get(s->metadata, "author", NULL, 0); tags[2] = av_dict_get(s->metadata, "copyright", NULL, 0); tags[3] = av_dict_get(s->metadata, "comment", NULL, 0); tags[4] = av_dict_get(s->metadata, "rating", NULL, 0); - + duration = asf->duration + PREROLL_TIME * 10000; has_title = tags[0] || tags[1] || tags[2] || tags[3] || tags[4]; metadata_count = av_dict_count(s->metadata); bit_rate = 0; - - for (n = 0; n < s->nb_streams; n++) { - AVDictionaryEntry *t = av_dict_get(s->streams[n]->metadata, DIRECTION_DICT_KEY, NULL, 0); - - enc = s->streams[n]->codec; + for (n = 0; n < s->nb_streams; n++) { + enc = s->streams[n]->codec; avpriv_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */ @@ -387,9 +384,9 @@ 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++; + } - if (t) has_direction++; - } + has_direction = asf_get_streams_direction(s); if (asf->is_streamed) { put_chunk(s, 0x4824, 0, 0xc00); /* start of stream (length will be patched later) */ @@ -424,39 +421,34 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, avio_wl16(pb, 6); if (has_direction) { - - int64_t hpos2; - + int64_t hpos2; avio_wl32(pb, 26 + has_direction * 46); - hpos2 = put_header(pb, &ff_asf_metadata_header); - avio_wl16(pb, has_direction); - - for (n = 0; n < s->nb_streams; n++) { - AVDictionaryEntry *t = av_dict_get(s->streams[n]->metadata, DIRECTION_DICT_KEY, NULL, 0); + hpos2 = put_header(pb, &ff_asf_metadata_header); + avio_wl16(pb, has_direction); + for (n = 0; n < s->nb_streams; n++) { int streamId; int direction; - sscanf(t->value,"%d %d",&streamId, &direction); - - av_log(s, AV_LOG_INFO, "=============== Value from DEC %d: %s\n", // V - n, t ? t->value : "NULL"); - - av_log(s, AV_LOG_INFO, - "============== Writing stream[%d] direction of stream %d, (%d)\n", - n+1, streamId, direction); // writes Metadata - + + AVDictionaryEntry *t = av_dict_get( + s->streams[n]->metadata, DIRECTION_DICT_KEY, NULL, 0); + + sscanf(t->value, "%d %d", &streamId, &direction); + + av_log(s, AV_LOG_DEBUG, "Writing stream[%d] direction of stream %d, (%d)\n", + n + 1, streamId, direction); + avio_wl16(pb, 0); // Reserved - avio_wl16(pb, streamId); // Stream Number + avio_wl16(pb, streamId);// Stream Number avio_wl16(pb, 32); // Name Length - avio_wl16(pb, 5); // Data Type - avio_wl32(pb, 2); // Data Length - avio_put_str16le(pb, "streamDirection"); // 32 + avio_wl16(pb, 5); // Data Type + avio_wl32(pb, 2); // Data Length + avio_put_str16le(pb, STREAM_DIRECTION_STR); // 32 avio_wl16(pb, direction); - } - end_header(pb, hpos2); - - } else if (has_aspect_ratio) { // V + } + end_header(pb, hpos2); + + } else if (has_aspect_ratio) { -// if (has_aspect_ratio) { int64_t hpos2; avio_wl32(pb, 26 + has_aspect_ratio * 84); hpos2 = put_header(pb, &ff_asf_metadata_header); @@ -701,12 +693,16 @@ static int asf_write_header(AVFormatContext *s) asf->nb_index_memory_alloc = ASF_INDEX_BLOCK; asf->maximum_packet = 0; + if (asf_alloc_streams_index(asf->streams, s->nb_streams, ASF_INDEX_BLOCK) + != 0) return -1; + /* the data-chunk-size has to be 50 (DATA_HEADER_SIZE), which is * data_size - asf->data_offset at the moment this function is done. * It is needed to use asf as a streamable format. */ if (asf_write_header1(s, 0, DATA_HEADER_SIZE) < 0) { //av_free(asf); av_freep(&asf->index_ptr); + asf_free_streams_index(asf->streams, s->nb_streams); return -1; } @@ -989,7 +985,17 @@ static int asf_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } asf->end_sec = start_sec; - + + ret = upadte_indices( + asf->streams, + pts, + offset, + pkt->stream_index, + pkt->duration, + ASF_INDEX_BLOCK, + asf->data_offset + DATA_HEADER_SIZE); + if (ret < 0) return ret; + return 0; } @@ -1032,6 +1038,10 @@ static int asf_write_trailer(AVFormatContext *s) } avio_flush(s->pb); + /* write indices with duration */ + asf_write_indices(s, asf->streams, s->nb_streams); + avio_flush(s->pb); + if (asf->is_streamed || !s->pb->seekable) { put_chunk(s, 0x4524, 0, 0); /* end of stream */ } else { @@ -1041,6 +1051,7 @@ static int asf_write_trailer(AVFormatContext *s) asf_write_header1(s, file_size, data_size - asf->data_offset); } + asf_free_streams_index(asf->streams, s->nb_streams); av_freep(&asf->index_ptr); return 0; } -- 1.9.5.msysgit.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel