From b4f0e04c99062267377605eb35e6a6f82e760855 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 28 Jan 2010 02:45:17 +0000 Subject: [PATCH] Introduce AVIStream struct and move stream based variables to it. This removes all but one MAX_STREAM from avienc.c. Originally committed as revision 21498 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/avienc.c | 100 ++++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 39 deletions(-) diff --git a/libavformat/avienc.c b/libavformat/avienc.c index 5ae95e2b6a..72aa8ea7da 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -42,14 +42,18 @@ typedef struct AVIIndex { typedef struct { int64_t riff_start, movi_list, odml_list; - int64_t frames_hdr_all, frames_hdr_strm[MAX_STREAMS]; - int audio_strm_length[MAX_STREAMS]; + int64_t frames_hdr_all; int riff_id; - int packet_count[MAX_STREAMS]; - - AVIIndex indexes[MAX_STREAMS]; } AVIContext; +typedef struct { + int64_t frames_hdr_strm; + int audio_strm_length; + int packet_count; + + AVIIndex indexes; +} AVIStream ; + static inline AVIIentry* avi_get_ientry(AVIIndex* idx, int ent_id) { int cl = ent_id / AVI_INDEX_CLUSTER_SIZE; @@ -57,15 +61,18 @@ static inline AVIIentry* avi_get_ientry(AVIIndex* idx, int ent_id) return &idx->cluster[cl][id]; } -static int64_t avi_start_new_riff(AVIContext *avi, ByteIOContext *pb, +static int64_t avi_start_new_riff(AVFormatContext *s, ByteIOContext *pb, const char* riff_tag, const char* list_tag) { + AVIContext *avi= s->priv_data; int64_t loff; int i; avi->riff_id++; - for (i=0; iindexes[i].entry = 0; + for (i=0; inb_streams; i++){ + AVIStream *avist= s->streams[i]->priv_data; + avist->indexes.entry = 0; + } avi->riff_start = ff_start_tag(pb, "RIFF"); put_tag(pb, riff_tag); @@ -125,17 +132,19 @@ static int avi_write_counters(AVFormatContext* s, int riff_id) file_size = url_ftell(pb); for(n = 0; n < s->nb_streams; n++) { - assert(avi->frames_hdr_strm[n]); + AVIStream *avist= s->streams[n]->priv_data; + + assert(avist->frames_hdr_strm); stream = s->streams[n]->codec; - url_fseek(pb, avi->frames_hdr_strm[n], SEEK_SET); + url_fseek(pb, avist->frames_hdr_strm, SEEK_SET); ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); if(au_ssize == 0) { - put_le32(pb, avi->packet_count[n]); + put_le32(pb, avist->packet_count); } else { - put_le32(pb, avi->audio_strm_length[n] / au_ssize); + put_le32(pb, avist->audio_strm_length / au_ssize); } if(stream->codec_type == CODEC_TYPE_VIDEO) - nb_frames = FFMAX(nb_frames, avi->packet_count[n]); + nb_frames = FFMAX(nb_frames, avist->packet_count); } if(riff_id == 1) { assert(avi->frames_hdr_all); @@ -155,9 +164,15 @@ static int avi_write_header(AVFormatContext *s) AVCodecContext *stream, *video_enc; int64_t list1, list2, strh, strf; + for(n=0;nnb_streams;n++) { + s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream)); + if(!s->streams[n]->priv_data) + return AVERROR(ENOMEM); + } + /* header list */ avi->riff_id = 0; - list1 = avi_start_new_riff(avi, pb, "AVI ", "hdrl"); + list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl"); /* avi header */ put_tag(pb, "avih"); @@ -204,6 +219,7 @@ static int avi_write_header(AVFormatContext *s) /* stream list */ for(i=0;istreams[i]->priv_data; list2 = ff_start_tag(pb, "LIST"); put_tag(pb, "strl"); @@ -238,7 +254,7 @@ static int avi_write_header(AVFormatContext *s) av_set_pts_info(s->streams[i], 64, au_scale, au_byterate); put_le32(pb, 0); /* start */ - avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */ + avist->frames_hdr_strm = url_ftell(pb); /* remember this offset to fill later */ if (url_is_streamed(pb)) put_le32(pb, AVI_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */ else @@ -288,8 +304,8 @@ static int avi_write_header(AVFormatContext *s) * like to get away without making AVI an OpenDML one * for compatibility reasons. */ - avi->indexes[i].entry = avi->indexes[i].ents_allocated = 0; - avi->indexes[i].indx_start = ff_start_tag(pb, "JUNK"); + avist->indexes.entry = avist->indexes.ents_allocated = 0; + avist->indexes.indx_start = ff_start_tag(pb, "JUNK"); put_le16(pb, 4); /* wLongsPerEntry */ put_byte(pb, 0); /* bIndexSubType (0 == frame index) */ put_byte(pb, 0); /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */ @@ -300,7 +316,7 @@ static int avi_write_header(AVFormatContext *s) put_le32(pb, 0); Must be 0. */ for (j=0; j < AVI_MASTER_INDEX_SIZE * 2; j++) put_le64(pb, 0); - ff_end_tag(pb, avi->indexes[i].indx_start); + ff_end_tag(pb, avist->indexes.indx_start); } if( stream->codec_type == CODEC_TYPE_VIDEO @@ -392,6 +408,7 @@ static int avi_write_ix(AVFormatContext *s) return -1; for (i=0;inb_streams;i++) { + AVIStream *avist= s->streams[i]->priv_data; int64_t ix, pos; avi_stream2fourcc(&tag[0], i, s->streams[i]->codec->codec_type); @@ -400,19 +417,19 @@ static int avi_write_ix(AVFormatContext *s) /* Writing AVI OpenDML leaf index chunk */ ix = url_ftell(pb); put_tag(pb, &ix_tag[0]); /* ix?? */ - put_le32(pb, avi->indexes[i].entry * 8 + 24); + put_le32(pb, avist->indexes.entry * 8 + 24); /* chunk size */ put_le16(pb, 2); /* wLongsPerEntry */ put_byte(pb, 0); /* bIndexSubType (0 == frame index) */ put_byte(pb, 1); /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */ - put_le32(pb, avi->indexes[i].entry); + put_le32(pb, avist->indexes.entry); /* nEntriesInUse */ put_tag(pb, &tag[0]); /* dwChunkId */ put_le64(pb, avi->movi_list);/* qwBaseOffset */ put_le32(pb, 0); /* dwReserved_3 (must be 0) */ - for (j=0; jindexes[i].entry; j++) { - AVIIentry* ie = avi_get_ientry(&avi->indexes[i], j); + for (j=0; jindexes.entry; j++) { + AVIIentry* ie = avi_get_ientry(&avist->indexes, j); put_le32(pb, ie->pos + 8); put_le32(pb, ((uint32_t)ie->len & ~0x80000000) | (ie->flags & 0x10 ? 0 : 0x80000000)); @@ -421,14 +438,14 @@ static int avi_write_ix(AVFormatContext *s) pos = url_ftell(pb); /* Updating one entry in the AVI OpenDML master index */ - url_fseek(pb, avi->indexes[i].indx_start - 8, SEEK_SET); + url_fseek(pb, avist->indexes.indx_start - 8, SEEK_SET); put_tag(pb, "indx"); /* enabling this entry */ url_fskip(pb, 8); put_le32(pb, avi->riff_id); /* nEntriesInUse */ url_fskip(pb, 16*avi->riff_id); put_le64(pb, ix); /* qwOffset */ put_le32(pb, pos - ix); /* dwSize */ - put_le32(pb, avi->indexes[i].entry); /* dwDuration */ + put_le32(pb, avist->indexes.entry); /* dwDuration */ url_fseek(pb, pos, SEEK_SET); } @@ -453,10 +470,11 @@ static int avi_write_idx1(AVFormatContext *s) do { empty = 1; for (i=0; inb_streams; i++) { - if (avi->indexes[i].entry <= entry[i]) + AVIStream *avist= s->streams[i]->priv_data; + if (avist->indexes.entry <= entry[i]) continue; - tie = avi_get_ientry(&avi->indexes[i], entry[i]); + tie = avi_get_ientry(&avist->indexes, entry[i]); if (empty || tie->pos < ie->pos) { ie = tie; stream_id = i; @@ -487,11 +505,12 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) unsigned char tag[5]; unsigned int flags=0; const int stream_index= pkt->stream_index; + AVIStream *avist= s->streams[stream_index]->priv_data; AVCodecContext *enc= s->streams[stream_index]->codec; int size= pkt->size; // av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %d\n", pkt->dts, avi->packet_count[stream_index], stream_index); - while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avi->packet_count[stream_index]){ + while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count){ AVPacket empty_packet; av_init_packet(&empty_packet); @@ -501,7 +520,7 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) avi_write_packet(s, &empty_packet); // av_log(s, AV_LOG_DEBUG, "dup %"PRId64" %d\n", pkt->dts, avi->packet_count[stream_index]); } - avi->packet_count[stream_index]++; + avist->packet_count++; // Make sure to put an OpenDML chunk when the file size exceeds the limits if (!url_is_streamed(pb) && @@ -514,18 +533,18 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) avi_write_idx1(s); ff_end_tag(pb, avi->riff_start); - avi->movi_list = avi_start_new_riff(avi, pb, "AVIX", "movi"); + avi->movi_list = avi_start_new_riff(s, pb, "AVIX", "movi"); } avi_stream2fourcc(&tag[0], stream_index, enc->codec_type); if(pkt->flags&PKT_FLAG_KEY) flags = 0x10; if (enc->codec_type == CODEC_TYPE_AUDIO) { - avi->audio_strm_length[stream_index] += size; + avist->audio_strm_length += size; } if (!url_is_streamed(s->pb)) { - AVIIndex* idx = &avi->indexes[stream_index]; + AVIIndex* idx = &avist->indexes; int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE; int id = idx->entry % AVI_INDEX_CLUSTER_SIZE; if (idx->ents_allocated <= idx->entry) { @@ -579,12 +598,14 @@ static int avi_write_trailer(AVFormatContext *s) for (n=nb_frames=0;nnb_streams;n++) { AVCodecContext *stream = s->streams[n]->codec; + AVIStream *avist= s->streams[n]->priv_data; + if (stream->codec_type == CODEC_TYPE_VIDEO) { - if (nb_frames < avi->packet_count[n]) - nb_frames = avi->packet_count[n]; + if (nb_frames < avist->packet_count) + nb_frames = avist->packet_count; } else { if (stream->codec_id == CODEC_ID_MP2 || stream->codec_id == CODEC_ID_MP3) { - nb_frames += avi->packet_count[n]; + nb_frames += avist->packet_count; } } } @@ -596,11 +617,12 @@ static int avi_write_trailer(AVFormatContext *s) } put_flush_packet(pb); - for (i=0; iindexes[i].ents_allocated/AVI_INDEX_CLUSTER_SIZE; j++) - av_free(avi->indexes[i].cluster[j]); - av_freep(&avi->indexes[i].cluster); - avi->indexes[i].ents_allocated = avi->indexes[i].entry = 0; + for (i=0; inb_streams; i++) { + AVIStream *avist= s->streams[i]->priv_data; + for (j=0; jindexes.ents_allocated/AVI_INDEX_CLUSTER_SIZE; j++) + av_free(avist->indexes.cluster[j]); + av_freep(&avist->indexes.cluster); + avist->indexes.ents_allocated = avist->indexes.entry = 0; } return res;