Revision f23496b5 libavformat/flvenc.c

View differences:

libavformat/flvenc.c
21 21
#include "avformat.h"
22 22
#include "flv.h"
23 23
#include "riff.h"
24
#include "avc.h"
24 25

  
25 26
#undef NDEBUG
26 27
#include <assert.h>
......
30 31
    {CODEC_ID_FLASHSV, FLV_CODECID_SCREEN},
31 32
    {CODEC_ID_VP6F,    FLV_CODECID_VP6   },
32 33
    {CODEC_ID_VP6,     FLV_CODECID_VP6   },
34
    {CODEC_ID_H264,    FLV_CODECID_H264  },
33 35
    {CODEC_ID_NONE,    0}
34 36
};
35 37

  
......
39 41
    {CODEC_ID_PCM_S16BE, FLV_CODECID_PCM    >> FLV_AUDIO_CODECID_OFFSET},
40 42
    {CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET},
41 43
    {CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM  >> FLV_AUDIO_CODECID_OFFSET},
44
    {CODEC_ID_AAC,       FLV_CODECID_AAC    >> FLV_AUDIO_CODECID_OFFSET},
42 45
    {CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET},
43 46
    {CODEC_ID_NONE,      0}
44 47
};
......
48 51
    offset_t duration_offset;
49 52
    offset_t filesize_offset;
50 53
    int64_t duration;
54
    int delay; ///< first dts delay for AVC
51 55
} FLVContext;
52 56

  
53 57
static int get_audio_flags(AVCodecContext *enc){
54 58
    int flags = (enc->bits_per_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT;
55 59

  
60
    if (enc->codec_id == CODEC_ID_AAC) // specs force these parameters
61
        return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | FLV_SAMPLESSIZE_16BIT | FLV_STEREO;
62
    else {
56 63
    switch (enc->sample_rate) {
57 64
        case    44100:
58 65
            flags |= FLV_SAMPLERATE_44100HZ;
......
73 80
            av_log(enc, AV_LOG_ERROR, "flv does not support that sample rate, choose from (44100, 22050, 11025).\n");
74 81
            return -1;
75 82
    }
83
    }
76 84

  
77 85
    if (enc->channels > 1) {
78 86
        flags |= FLV_STEREO;
......
239 247
    url_fseek(pb, data_size + 10 - 3, SEEK_CUR);
240 248
    put_be32(pb, data_size + 11);
241 249

  
250
    for (i = 0; i < s->nb_streams; i++) {
251
        AVCodecContext *enc = s->streams[i]->codec;
252
        if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) {
253
            offset_t pos;
254
            put_byte(pb, enc->codec_type == CODEC_TYPE_VIDEO ?
255
                     FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
256
            put_be24(pb, 0); // size patched later
257
            put_be24(pb, 0); // ts
258
            put_byte(pb, 0); // ts ext
259
            put_be24(pb, 0); // streamid
260
            pos = url_ftell(pb);
261
            if (enc->codec_id == CODEC_ID_AAC) {
262
                put_byte(pb, get_audio_flags(enc));
263
                put_byte(pb, 0); // AAC sequence header
264
                put_buffer(pb, enc->extradata, enc->extradata_size);
265
            } else {
266
                put_byte(pb, enc->codec_tag | FLV_FRAME_KEY); // flags
267
                put_byte(pb, 0); // AVC sequence header
268
                put_be24(pb, 0); // composition time
269
                ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size);
270
            }
271
            data_size = url_ftell(pb) - pos;
272
            url_fseek(pb, -data_size - 10, SEEK_CUR);
273
            put_be24(pb, data_size);
274
            url_fseek(pb, data_size + 10 - 3, SEEK_CUR);
275
            put_be32(pb, data_size + 11); // previous tag size
276
        }
277
    }
278

  
242 279
    return 0;
243 280
}
244 281

  
......
266 303
    ByteIOContext *pb = s->pb;
267 304
    AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
268 305
    FLVContext *flv = s->priv_data;
306
    unsigned ts;
269 307
    int size= pkt->size;
270 308
    int flags, flags_size;
271 309

  
272 310
//    av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size);
273 311

  
274
    if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F)
312
    if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F ||
313
       enc->codec_id == CODEC_ID_AAC)
275 314
        flags_size= 2;
315
    else if(enc->codec_id == CODEC_ID_H264)
316
        flags_size= 5;
276 317
    else
277 318
        flags_size= 1;
278 319

  
......
295 336
        put_byte(pb, FLV_TAG_TYPE_AUDIO);
296 337
    }
297 338

  
339
    if (enc->codec_id == CODEC_ID_H264) {
340
        if (ff_avc_parse_nal_units(pkt->data, &pkt->data, &pkt->size) < 0)
341
            return -1;
342
        assert(pkt->size);
343
        size = pkt->size;
344
        /* cast needed to get negative value */
345
        if (!flv->delay && (int32_t)pkt->dts < 0)
346
            flv->delay = -(int32_t)pkt->dts;
347
    }
348

  
349
    ts = pkt->dts + flv->delay; // add delay to force positive dts
298 350
    put_be24(pb,size + flags_size);
299
    put_be24(pb,pkt->pts);
300
    put_byte(pb,pkt->pts >> 24);
351
    put_be24(pb,ts);
352
    put_byte(pb,ts >> 24);
301 353
    put_be24(pb,flv->reserved);
302 354
    put_byte(pb,flags);
303 355
    if (enc->codec_id == CODEC_ID_VP6)
304 356
        put_byte(pb,0);
305 357
    if (enc->codec_id == CODEC_ID_VP6F)
306 358
        put_byte(pb, enc->extradata_size ? enc->extradata[0] : 0);
359
    else if (enc->codec_id == CODEC_ID_AAC)
360
        put_byte(pb,1); // AAC raw
361
    else if (enc->codec_id == CODEC_ID_H264) {
362
        put_byte(pb,1); // AVC NALU
363
        put_be24(pb,pkt->pts - (int32_t)pkt->dts);
364
    }
307 365
    put_buffer(pb, pkt->data, size);
308 366
    put_be32(pb,size+flags_size+11); // previous tag size
309
    flv->duration = FFMAX(flv->duration, pkt->pts + pkt->duration);
367
    flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration);
310 368

  
311 369
    put_flush_packet(pb);
312 370
    return 0;
......
328 386
    flv_write_packet,
329 387
    flv_write_trailer,
330 388
    .codec_tag= (const AVCodecTag*[]){flv_video_codec_ids, flv_audio_codec_ids, 0},
389
    .flags= AVFMT_GLOBALHEADER,
331 390
};

Also available in: Unified diff