Revision 86bec9a1 libav/avienc.c

View differences:

libav/avienc.c
31 31
} AVIIndex;
32 32

  
33 33
typedef struct {
34
    offset_t movi_list;
34
    offset_t movi_list, frames_hdr_all, frames_hdr_strm[MAX_STREAMS];
35
    int audio_strm_length[MAX_STREAMS];
35 36
    AVIIndex *first, *last;
36 37
} AVIContext;
37 38

  
......
109 110
    put_le32(pb, 0);
110 111
}
111 112

  
113
void parse_specific_params(AVCodecContext *stream, int *au_byterate, int *au_ssize, int *au_scale)
114
{
115
    switch(stream->codec_id) {
116
    case CODEC_ID_PCM_S16LE:
117
       *au_scale = *au_ssize = 2*stream->channels;
118
       *au_byterate = *au_ssize * stream->sample_rate;
119
        break;
120
    case CODEC_ID_PCM_U8:
121
    case CODEC_ID_PCM_ALAW:
122
    case CODEC_ID_PCM_MULAW:
123
        *au_scale = *au_ssize = stream->channels;
124
        *au_byterate = *au_ssize * stream->sample_rate;
125
        break;
126
    case CODEC_ID_MP2:
127
        *au_ssize = 1;
128
        *au_scale = 1;
129
        *au_byterate = stream->bit_rate / 8;
130
    default:
131
        *au_ssize = 1;
132
        *au_scale = 1; 
133
        *au_byterate = stream->bit_rate / 8;
134
        break;
135
    }
136
}
137

  
112 138
static int avi_write_header(AVFormatContext *s)
113 139
{
114 140
    AVIContext *avi;
115 141
    ByteIOContext *pb = &s->pb;
116
    int bitrate, n, i, nb_frames;
142
    int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;
117 143
    AVCodecContext *stream, *video_enc;
118 144
    offset_t list1, list2, strh, strf;
119 145

  
......
154 180
    put_le32(pb, bitrate / 8); /* XXX: not quite exact */
155 181
    put_le32(pb, 0); /* padding */
156 182
    put_le32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */
183
    avi->frames_hdr_all = url_ftell(pb); /* remember this offset to fill later */
157 184
    put_le32(pb, nb_frames); /* nb frames, filled later */
158 185
    put_le32(pb, 0); /* initial frame */
159 186
    put_le32(pb, s->nb_streams); /* nb streams */
......
185 212
            put_le32(pb, 1000); /* scale */
186 213
            put_le32(pb, (1000 * stream->frame_rate) / FRAME_RATE_BASE); /* rate */
187 214
            put_le32(pb, 0); /* start */
215
            avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */
188 216
            put_le32(pb, nb_frames); /* length, XXX: fill later */
189 217
            put_le32(pb, 1024 * 1024); /* suggested buffer size */
190
            put_le32(pb, 10000); /* quality */
218
            put_le32(pb, -1); /* quality */
191 219
            put_le32(pb, stream->width * stream->height * 3); /* sample size */
192 220
            put_le16(pb, 0);
193 221
            put_le16(pb, 0);
......
196 224
            break;
197 225
        case CODEC_TYPE_AUDIO:
198 226
            put_tag(pb, "auds");
199
            put_le32(pb, 0);
227
            put_le32(pb, 1); /* tag */
200 228
            put_le32(pb, 0); /* flags */
201 229
            put_le16(pb, 0); /* priority */
202 230
            put_le16(pb, 0); /* language */
203 231
            put_le32(pb, 0); /* initial frame */
204
            put_le32(pb, 1); /* scale */
205
            put_le32(pb, stream->bit_rate / 8); /* rate */
232
            parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);
233
            put_le32(pb, au_scale); /* scale */
234
            put_le32(pb, au_byterate); /* rate */
206 235
            put_le32(pb, 0); /* start */
236
            avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */
207 237
            put_le32(pb, 0); /* length, XXX: filled later */
208 238
            put_le32(pb, 12 * 1024); /* suggested buffer size */
209 239
            put_le32(pb, -1); /* quality */
210
            put_le32(pb, 1); /* sample size */
240
            put_le32(pb, au_ssize); /* sample size */
211 241
            put_le32(pb, 0);
212 242
            put_le32(pb, 0);
213 243
            break;
......
265 295
        tag[3] = 'b';
266 296
        flags = 0x10;
267 297
    }
298
    if (enc->codec_type == CODEC_TYPE_AUDIO) 
299
       avi->audio_strm_length[stream_index] += size;
268 300

  
269 301
    if (!url_is_streamed(&s->pb)) {
270 302
        idx = malloc(sizeof(AVIIndex));
......
295 327
    ByteIOContext *pb = &s->pb;
296 328
    AVIContext *avi = s->priv_data;
297 329
    offset_t file_size, idx_chunk;
330
    int n, nb_frames, au_byterate, au_ssize, au_scale;
331
    AVCodecContext *stream;
298 332
    AVIIndex *idx;
299 333

  
300 334
    if (!url_is_streamed(&s->pb)) {
......
315 349
        file_size = url_ftell(pb);
316 350
        url_fseek(pb, 4, SEEK_SET);
317 351
        put_le32(pb, (UINT32)(file_size - 8));
352

  
353
        /* Fill in frame/sample counters */
354
        nb_frames = 0;
355
        for(n=0;n<s->nb_streams;n++) {
356
            if (avi->frames_hdr_strm[n] != 0) {
357
                stream = &s->streams[n]->codec;
358
                url_fseek(pb, avi->frames_hdr_strm[n], SEEK_SET);
359
                if (stream->codec_type == CODEC_TYPE_VIDEO) {
360
                    put_le32(pb, stream->frame_number); 
361
                    if (nb_frames < stream->frame_number)
362
                        nb_frames = stream->frame_number;
363
                } else {
364
                    if (stream->codec_id == CODEC_ID_MP2) {
365
                        put_le32(pb, stream->frame_number);
366
                        nb_frames += stream->frame_number;
367
                    } else {
368
                        parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);
369
                        put_le32(pb, avi->audio_strm_length[n] / au_ssize);
370
                    }
371
                }
372
            }
373
       }
374
       if (avi->frames_hdr_all != 0) {
375
           url_fseek(pb, avi->frames_hdr_all, SEEK_SET);
376
           put_le32(pb, nb_frames); 
377
       }
318 378
        url_fseek(pb, file_size, SEEK_SET);
319 379
    }
320 380
    put_flush_packet(pb);

Also available in: Unified diff