flvenc.c 38.7 KB
Newer Older
1
/*
2
 * FLV muxer
3
 * Copyright (c) 2003 The FFmpeg Project
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21 22

#include "libavutil/intreadwrite.h"
23
#include "libavutil/dict.h"
24
#include "libavutil/intfloat.h"
25
#include "libavutil/avassert.h"
26
#include "libavutil/mathematics.h"
27 28
#include "avio_internal.h"
#include "avio.h"
29
#include "avc.h"
30
#include "avformat.h"
31
#include "flv.h"
32
#include "internal.h"
Tomás Touceda's avatar
Tomás Touceda committed
33
#include "metadata.h"
34 35 36
#include "libavutil/opt.h"
#include "libavcodec/put_bits.h"
#include "libavcodec/aacenctab.h"
37

Michael Niedermayer's avatar
Michael Niedermayer committed
38

39
static const AVCodecTag flv_video_codec_ids[] = {
40
    { AV_CODEC_ID_FLV1,     FLV_CODECID_H263 },
41 42
    { AV_CODEC_ID_H263,     FLV_CODECID_REALH263 },
    { AV_CODEC_ID_MPEG4,    FLV_CODECID_MPEG4 },
43 44 45
    { AV_CODEC_ID_FLASHSV,  FLV_CODECID_SCREEN },
    { AV_CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2 },
    { AV_CODEC_ID_VP6F,     FLV_CODECID_VP6 },
46
    { AV_CODEC_ID_VP6,      FLV_CODECID_VP6 },
47
    { AV_CODEC_ID_VP6A,     FLV_CODECID_VP6A },
48 49
    { AV_CODEC_ID_H264,     FLV_CODECID_H264 },
    { AV_CODEC_ID_NONE,     0 }
50 51
};

52
static const AVCodecTag flv_audio_codec_ids[] = {
53 54 55 56 57 58 59 60 61 62 63
    { AV_CODEC_ID_MP3,        FLV_CODECID_MP3        >> FLV_AUDIO_CODECID_OFFSET },
    { AV_CODEC_ID_PCM_U8,     FLV_CODECID_PCM        >> FLV_AUDIO_CODECID_OFFSET },
    { AV_CODEC_ID_PCM_S16BE,  FLV_CODECID_PCM        >> FLV_AUDIO_CODECID_OFFSET },
    { AV_CODEC_ID_PCM_S16LE,  FLV_CODECID_PCM_LE     >> FLV_AUDIO_CODECID_OFFSET },
    { AV_CODEC_ID_ADPCM_SWF,  FLV_CODECID_ADPCM      >> FLV_AUDIO_CODECID_OFFSET },
    { AV_CODEC_ID_AAC,        FLV_CODECID_AAC        >> FLV_AUDIO_CODECID_OFFSET },
    { AV_CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET },
    { AV_CODEC_ID_PCM_MULAW,  FLV_CODECID_PCM_MULAW  >> FLV_AUDIO_CODECID_OFFSET },
    { AV_CODEC_ID_PCM_ALAW,   FLV_CODECID_PCM_ALAW   >> FLV_AUDIO_CODECID_OFFSET },
    { AV_CODEC_ID_SPEEX,      FLV_CODECID_SPEEX      >> FLV_AUDIO_CODECID_OFFSET },
    { AV_CODEC_ID_NONE,       0 }
64 65
};

66 67
typedef enum {
    FLV_AAC_SEQ_HEADER_DETECT = (1 << 0),
68
    FLV_NO_SEQUENCE_END = (1 << 1),
69
    FLV_ADD_KEYFRAME_INDEX = (1 << 2),
70
    FLV_NO_METADATA = (1 << 3),
71
    FLV_NO_DURATION_FILESIZE = (1 << 4),
72 73
} FLVFlags;

74 75 76 77 78 79
typedef struct FLVFileposition {
    int64_t keyframe_position;
    double keyframe_timestamp;
    struct FLVFileposition *next;
} FLVFileposition;

80
typedef struct FLVContext {
81
    AVClass *av_class;
82
    int     reserved;
83 84
    int64_t duration_offset;
    int64_t filesize_offset;
85
    int64_t duration;
86
    int64_t delay;      ///< first dts delay (needed for AVC & Speex)
87

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
    int64_t datastart_offset;
    int64_t datasize_offset;
    int64_t datasize;
    int64_t videosize_offset;
    int64_t videosize;
    int64_t audiosize_offset;
    int64_t audiosize;

    int64_t metadata_size_pos;
    int64_t metadata_totalsize_pos;
    int64_t metadata_totalsize;
    int64_t keyframe_index_size;

    int64_t lasttimestamp_offset;
    double lasttimestamp;
    int64_t lastkeyframetimestamp_offset;
    double lastkeyframetimestamp;
    int64_t lastkeyframelocation_offset;
    int64_t lastkeyframelocation;

    int acurframeindex;
    int64_t keyframes_info_offset;

    int64_t filepositions_count;
    FLVFileposition *filepositions;
    FLVFileposition *head_filepositions;

115 116
    AVCodecParameters *audio_par;
    AVCodecParameters *video_par;
117
    double framerate;
118
    AVCodecParameters *data_par;
119 120

    int flags;
121 122
} FLVContext;

123 124 125 126
typedef struct FLVStreamContext {
    int64_t last_ts;    ///< last timestamp for each stream
} FLVStreamContext;

127
static int get_audio_flags(AVFormatContext *s, AVCodecParameters *par)
128
{
129
    int flags = (par->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT
130
                                                   : FLV_SAMPLESSIZE_8BIT;
131

132
    if (par->codec_id == AV_CODEC_ID_AAC) // specs force these parameters
133 134
        return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ |
               FLV_SAMPLESSIZE_16BIT | FLV_STEREO;
135 136
    else if (par->codec_id == AV_CODEC_ID_SPEEX) {
        if (par->sample_rate != 16000) {
137
            av_log(s, AV_LOG_ERROR,
138
                   "FLV only supports wideband (16kHz) Speex audio\n");
139
            return AVERROR(EINVAL);
140
        }
141
        if (par->channels != 1) {
142
            av_log(s, AV_LOG_ERROR, "FLV only supports mono Speex audio\n");
143
            return AVERROR(EINVAL);
144 145 146
        }
        return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT;
    } else {
147
        switch (par->sample_rate) {
148 149 150 151 152 153 154 155
        case 48000:
            // 48khz mp3 is stored with 44k1 samplerate identifer
            if (par->codec_id == AV_CODEC_ID_MP3) {
                flags |= FLV_SAMPLERATE_44100HZ;
                break;
            } else {
                goto error;
            }
156
        case 44100:
157
            flags |= FLV_SAMPLERATE_44100HZ;
158
            break;
159
        case 22050:
160
            flags |= FLV_SAMPLERATE_22050HZ;
161
            break;
162
        case 11025:
163
            flags |= FLV_SAMPLERATE_11025HZ;
164
            break;
165 166 167
        case 16000: // nellymoser only
        case  8000: // nellymoser only
        case  5512: // not MP3
168
            if (par->codec_id != AV_CODEC_ID_MP3) {
Michael Niedermayer's avatar
Michael Niedermayer committed
169 170
                flags |= FLV_SAMPLERATE_SPECIAL;
                break;
171
            }
172
        default:
173
error:
174
            av_log(s, AV_LOG_ERROR,
175
                   "FLV does not support sample rate %d, "
176
                   "choose from (44100, 22050, 11025)\n", par->sample_rate);
177
            return AVERROR(EINVAL);
178
        }
179
    }
180

181
    if (par->channels > 1)
182
        flags |= FLV_STEREO;
183

184
    switch (par->codec_id) {
185
    case AV_CODEC_ID_MP3:
186
        flags |= FLV_CODECID_MP3    | FLV_SAMPLESSIZE_16BIT;
187
        break;
188
    case AV_CODEC_ID_PCM_U8:
189
        flags |= FLV_CODECID_PCM    | FLV_SAMPLESSIZE_8BIT;
190
        break;
191
    case AV_CODEC_ID_PCM_S16BE:
192
        flags |= FLV_CODECID_PCM    | FLV_SAMPLESSIZE_16BIT;
193
        break;
194
    case AV_CODEC_ID_PCM_S16LE:
195
        flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT;
196
        break;
197
    case AV_CODEC_ID_ADPCM_SWF:
198
        flags |= FLV_CODECID_ADPCM  | FLV_SAMPLESSIZE_16BIT;
199
        break;
200
    case AV_CODEC_ID_NELLYMOSER:
201
        if (par->sample_rate == 8000)
202
            flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO  | FLV_SAMPLESSIZE_16BIT;
203
        else if (par->sample_rate == 16000)
204
            flags |= FLV_CODECID_NELLYMOSER_16KHZ_MONO | FLV_SAMPLESSIZE_16BIT;
205 206
        else
            flags |= FLV_CODECID_NELLYMOSER            | FLV_SAMPLESSIZE_16BIT;
207
        break;
208
    case AV_CODEC_ID_PCM_MULAW:
209 210
        flags = FLV_CODECID_PCM_MULAW | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT;
        break;
211
    case AV_CODEC_ID_PCM_ALAW:
212
        flags = FLV_CODECID_PCM_ALAW  | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT;
213
        break;
214
    case 0:
215
        flags |= par->codec_tag << 4;
216 217
        break;
    default:
218
        av_log(s, AV_LOG_ERROR, "Audio codec '%s' not compatible with FLV\n",
219
               avcodec_get_name(par->codec_id));
220
        return AVERROR(EINVAL);
221
    }
222

223 224 225
    return flags;
}

226
static void put_amf_string(AVIOContext *pb, const char *str)
227 228
{
    size_t len = strlen(str);
229 230
    avio_wb16(pb, len);
    avio_write(pb, str, len);
231 232
}

233 234
static void put_avc_eos_tag(AVIOContext *pb, unsigned ts)
{
235
    avio_w8(pb, FLV_TAG_TYPE_VIDEO);
236 237 238 239 240 241 242 243
    avio_wb24(pb, 5);               /* Tag Data Size */
    avio_wb24(pb, ts);              /* lower 24 bits of timestamp in ms */
    avio_w8(pb, (ts >> 24) & 0x7F); /* MSB of ts in ms */
    avio_wb24(pb, 0);               /* StreamId = 0 */
    avio_w8(pb, 23);                /* ub[4] FrameType = 1, ub[4] CodecId = 7 */
    avio_w8(pb, 2);                 /* AVC end of sequence */
    avio_wb24(pb, 0);               /* Always 0 for AVC EOS. */
    avio_wb32(pb, 16);              /* Size of FLV tag */
244 245
}

246
static void put_amf_double(AVIOContext *pb, double d)
247
{
248
    avio_w8(pb, AMF_DATA_TYPE_NUMBER);
249
    avio_wb64(pb, av_double2int(d));
250 251
}

252 253 254 255 256 257 258 259 260 261 262
static void put_amf_byte(AVIOContext *pb, unsigned char abyte)
{
    avio_w8(pb, abyte);
}

static void put_amf_dword_array(AVIOContext *pb, uint32_t dw)
{
    avio_w8(pb, AMF_DATA_TYPE_ARRAY);
    avio_wb32(pb, dw);
}

263 264
static void put_amf_bool(AVIOContext *pb, int b)
{
265 266
    avio_w8(pb, AMF_DATA_TYPE_BOOL);
    avio_w8(pb, !!b);
267 268
}

269
static void write_metadata(AVFormatContext *s, unsigned int ts)
270
{
271
    AVIOContext *pb = s->pb;
272
    FLVContext *flv = s->priv_data;
273
    int write_duration_filesize = !(flv->flags & FLV_NO_DURATION_FILESIZE);
274
    int metadata_count = 0;
275
    int64_t metadata_count_pos;
276
    AVDictionaryEntry *tag = NULL;
277

278
    /* write meta_tag */
279 280
    avio_w8(pb, FLV_TAG_TYPE_META);            // tag type META
    flv->metadata_size_pos = avio_tell(pb);
281
    avio_wb24(pb, 0);           // size of data part (sum of all parts below)
282
    avio_wb24(pb, ts);          // timestamp
283
    avio_wb32(pb, 0);           // reserved
284 285 286 287

    /* now data of data_size size */

    /* first event name as a string */
288
    avio_w8(pb, AMF_DATA_TYPE_STRING);
289 290 291
    put_amf_string(pb, "onMetaData"); // 12 bytes

    /* mixed array (hash) with size and string/type/data tuples */
292
    avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
293
    metadata_count_pos = avio_tell(pb);
294 295
    metadata_count = 4 * !!flv->video_par +
                     5 * !!flv->audio_par +
296
                     1 * !!flv->data_par;
297
    if (write_duration_filesize) {
298 299
        metadata_count += 2; // +2 for duration and file size
    }
300
    avio_wb32(pb, metadata_count);
301

302
    if (write_duration_filesize) {
303 304 305 306 307
        put_amf_string(pb, "duration");
        flv->duration_offset = avio_tell(pb);
        // fill in the guessed duration, it'll be corrected later if incorrect
        put_amf_double(pb, s->duration / AV_TIME_BASE);
    }
308

309
    if (flv->video_par) {
310
        put_amf_string(pb, "width");
311
        put_amf_double(pb, flv->video_par->width);
312 313

        put_amf_string(pb, "height");
314
        put_amf_double(pb, flv->video_par->height);
315 316

        put_amf_string(pb, "videodatarate");
317
        put_amf_double(pb, flv->video_par->bit_rate / 1024.0);
318

319
        if (flv->framerate != 0.0) {
320
            put_amf_string(pb, "framerate");
321
            put_amf_double(pb, flv->framerate);
322
            metadata_count++;
323
        }
324 325

        put_amf_string(pb, "videocodecid");
326
        put_amf_double(pb, flv->video_par->codec_tag);
327 328
    }

329
    if (flv->audio_par) {
330
        put_amf_string(pb, "audiodatarate");
331
        put_amf_double(pb, flv->audio_par->bit_rate / 1024.0);
332

333
        put_amf_string(pb, "audiosamplerate");
334
        put_amf_double(pb, flv->audio_par->sample_rate);
335 336

        put_amf_string(pb, "audiosamplesize");
337
        put_amf_double(pb, flv->audio_par->codec_id == AV_CODEC_ID_PCM_U8 ? 8 : 16);
338 339

        put_amf_string(pb, "stereo");
340
        put_amf_bool(pb, flv->audio_par->channels == 2);
341 342

        put_amf_string(pb, "audiocodecid");
343
        put_amf_double(pb, flv->audio_par->codec_tag);
344 345
    }

346
    if (flv->data_par) {
347 348 349 350
        put_amf_string(pb, "datastream");
        put_amf_double(pb, 0.0);
    }

351
    ff_standardize_creation_time(s);
352
    while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
353 354 355 356 357 358 359 360 361 362 363 364
        if(   !strcmp(tag->key, "width")
            ||!strcmp(tag->key, "height")
            ||!strcmp(tag->key, "videodatarate")
            ||!strcmp(tag->key, "framerate")
            ||!strcmp(tag->key, "videocodecid")
            ||!strcmp(tag->key, "audiodatarate")
            ||!strcmp(tag->key, "audiosamplerate")
            ||!strcmp(tag->key, "audiosamplesize")
            ||!strcmp(tag->key, "stereo")
            ||!strcmp(tag->key, "audiocodecid")
            ||!strcmp(tag->key, "duration")
            ||!strcmp(tag->key, "onMetaData")
365 366 367 368 369 370 371 372
            ||!strcmp(tag->key, "datasize")
            ||!strcmp(tag->key, "lasttimestamp")
            ||!strcmp(tag->key, "totalframes")
            ||!strcmp(tag->key, "hasAudio")
            ||!strcmp(tag->key, "hasVideo")
            ||!strcmp(tag->key, "hasCuePoints")
            ||!strcmp(tag->key, "hasMetadata")
            ||!strcmp(tag->key, "hasKeyframes")
373
        ){
374
            av_log(s, AV_LOG_DEBUG, "Ignoring metadata for %s\n", tag->key);
375 376
            continue;
        }
Tomás Touceda's avatar
Tomás Touceda committed
377
        put_amf_string(pb, tag->key);
378
        avio_w8(pb, AMF_DATA_TYPE_STRING);
Tomás Touceda's avatar
Tomás Touceda committed
379
        put_amf_string(pb, tag->value);
380
        metadata_count++;
Tomás Touceda's avatar
Tomás Touceda committed
381 382
    }

383
    if (write_duration_filesize) {
384 385 386 387
        put_amf_string(pb, "filesize");
        flv->filesize_offset = avio_tell(pb);
        put_amf_double(pb, 0); // delayed write
    }
388

389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
    if (flv->flags & FLV_ADD_KEYFRAME_INDEX) {
        flv->acurframeindex = 0;
        flv->keyframe_index_size = 0;

        put_amf_string(pb, "hasVideo");
        put_amf_bool(pb, !!flv->video_par);
        metadata_count++;

        put_amf_string(pb, "hasKeyframes");
        put_amf_bool(pb, 1);
        metadata_count++;

        put_amf_string(pb, "hasAudio");
        put_amf_bool(pb, !!flv->audio_par);
        metadata_count++;

        put_amf_string(pb, "hasMetadata");
        put_amf_bool(pb, 1);
        metadata_count++;

        put_amf_string(pb, "canSeekToEnd");
        put_amf_bool(pb, 1);
        metadata_count++;

        put_amf_string(pb, "datasize");
        flv->datasize_offset = avio_tell(pb);
        flv->datasize = 0;
        put_amf_double(pb, flv->datasize);
        metadata_count++;

        put_amf_string(pb, "videosize");
        flv->videosize_offset = avio_tell(pb);
        flv->videosize = 0;
        put_amf_double(pb, flv->videosize);
        metadata_count++;

        put_amf_string(pb, "audiosize");
        flv->audiosize_offset = avio_tell(pb);
        flv->audiosize = 0;
        put_amf_double(pb, flv->audiosize);
        metadata_count++;

        put_amf_string(pb, "lasttimestamp");
        flv->lasttimestamp_offset = avio_tell(pb);
        flv->lasttimestamp = 0;
        put_amf_double(pb, 0);
        metadata_count++;

        put_amf_string(pb, "lastkeyframetimestamp");
        flv->lastkeyframetimestamp_offset = avio_tell(pb);
        flv->lastkeyframetimestamp = 0;
        put_amf_double(pb, 0);
        metadata_count++;

        put_amf_string(pb, "lastkeyframelocation");
        flv->lastkeyframelocation_offset = avio_tell(pb);
        flv->lastkeyframelocation = 0;
        put_amf_double(pb, 0);
        metadata_count++;

        put_amf_string(pb, "keyframes");
        put_amf_byte(pb, AMF_DATA_TYPE_OBJECT);
        metadata_count++;

        flv->keyframes_info_offset = avio_tell(pb);
    }

456
    put_amf_string(pb, "");
457
    avio_w8(pb, AMF_END_OF_OBJECT);
458 459

    /* write total size of tag */
460
    flv->metadata_totalsize = avio_tell(pb) - flv->metadata_size_pos - 10;
461 462 463 464

    avio_seek(pb, metadata_count_pos, SEEK_SET);
    avio_wb32(pb, metadata_count);

465 466 467 468 469
    avio_seek(pb, flv->metadata_size_pos, SEEK_SET);
    avio_wb24(pb, flv->metadata_totalsize);
    avio_skip(pb, flv->metadata_totalsize + 10 - 3);
    flv->metadata_totalsize_pos = avio_tell(pb);
    avio_wb32(pb, flv->metadata_totalsize + 11);
470 471
}

472 473 474 475 476 477 478 479 480 481 482
static int unsupported_codec(AVFormatContext *s,
                             const char* type, int codec_id)
{
    const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id);
    av_log(s, AV_LOG_ERROR,
           "%s codec %s not compatible with flv\n",
            type,
            desc ? desc->name : "unknown");
    return AVERROR(ENOSYS);
}

483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par) {
    int64_t data_size;
    AVIOContext *pb = s->pb;
    FLVContext *flv = s->priv_data;

    if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
            || par->codec_id == AV_CODEC_ID_MPEG4) {
        int64_t pos;
        avio_w8(pb,
                par->codec_type == AVMEDIA_TYPE_VIDEO ?
                        FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
        avio_wb24(pb, 0); // size patched later
        avio_wb24(pb, 0); // ts
        avio_w8(pb, 0);   // ts ext
        avio_wb24(pb, 0); // streamid
        pos = avio_tell(pb);
        if (par->codec_id == AV_CODEC_ID_AAC) {
            avio_w8(pb, get_audio_flags(s, par));
            avio_w8(pb, 0); // AAC sequence header

503
            if (!par->extradata_size && (flv->flags & FLV_AAC_SEQ_HEADER_DETECT)) {
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
                PutBitContext pbc;
                int samplerate_index;
                int channels = flv->audio_par->channels
                        - (flv->audio_par->channels == 8 ? 1 : 0);
                uint8_t data[2];

                for (samplerate_index = 0; samplerate_index < 16;
                        samplerate_index++)
                    if (flv->audio_par->sample_rate
                            == mpeg4audio_sample_rates[samplerate_index])
                        break;

                init_put_bits(&pbc, data, sizeof(data));
                put_bits(&pbc, 5, flv->audio_par->profile + 1); //profile
                put_bits(&pbc, 4, samplerate_index); //sample rate index
                put_bits(&pbc, 4, channels);
                put_bits(&pbc, 1, 0); //frame length - 1024 samples
                put_bits(&pbc, 1, 0); //does not depend on core coder
                put_bits(&pbc, 1, 0); //is not extension
                flush_put_bits(&pbc);

                avio_w8(pb, data[0]);
                avio_w8(pb, data[1]);

                av_log(s, AV_LOG_WARNING, "AAC sequence header: %02x %02x.\n",
                        data[0], data[1]);
            }
            avio_write(pb, par->extradata, par->extradata_size);
        } else {
            avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
            avio_w8(pb, 0); // AVC sequence header
            avio_wb24(pb, 0); // composition time
            ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
        }
        data_size = avio_tell(pb) - pos;
        avio_seek(pb, -data_size - 10, SEEK_CUR);
        avio_wb24(pb, data_size);
        avio_skip(pb, data_size + 10 - 3);
        avio_wb32(pb, data_size + 11); // previous tag size
    }
}

546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
static int flv_append_keyframe_info(AVFormatContext *s, FLVContext *flv, double ts, int64_t pos)
{
    FLVFileposition *position = av_malloc(sizeof(FLVFileposition));

    if (!position) {
        av_log(s, AV_LOG_WARNING, "no mem for add keyframe index!\n");
        return AVERROR(ENOMEM);
    }

    position->keyframe_timestamp = ts;
    position->keyframe_position = pos;

    if (!flv->filepositions_count) {
        flv->filepositions = position;
        flv->head_filepositions = flv->filepositions;
        position->next = NULL;
    } else {
        flv->filepositions->next = position;
        position->next = NULL;
        flv->filepositions = flv->filepositions->next;
    }

    flv->filepositions_count++;

    return 0;
}

static int shift_data(AVFormatContext *s)
{
    int ret = 0;
    int n = 0;
    int64_t metadata_size = 0;
    FLVContext *flv = s->priv_data;
    int64_t pos, pos_end = avio_tell(s->pb);
    uint8_t *buf, *read_buf[2];
    int read_buf_id = 0;
    int read_size[2];
    AVIOContext *read_pb;

    metadata_size = flv->filepositions_count * 9 * 2 + 10; /* filepositions and times value */
    metadata_size += 2 + 13; /* filepositions String */
    metadata_size += 2 + 5; /* times String */
    metadata_size += 3; /* Object end */

    flv->keyframe_index_size = metadata_size;

    if (metadata_size < 0)
        return metadata_size;

    buf = av_malloc_array(metadata_size, 2);
    if (!buf) {
        return AVERROR(ENOMEM);
    }
    read_buf[0] = buf;
    read_buf[1] = buf + metadata_size;

    avio_seek(s->pb, flv->metadata_size_pos, SEEK_SET);
    avio_wb24(s->pb, flv->metadata_totalsize + metadata_size);

    avio_seek(s->pb, flv->metadata_totalsize_pos, SEEK_SET);
    avio_wb32(s->pb, flv->metadata_totalsize + 11 + metadata_size);
    avio_seek(s->pb, pos_end, SEEK_SET);

    /* Shift the data: the AVIO context of the output can only be used for
     * writing, so we re-open the same output, but for reading. It also avoids
     * a read/seek/write/seek back and forth. */
    avio_flush(s->pb);
    ret = s->io_open(s, &read_pb, s->filename, AVIO_FLAG_READ, NULL);
    if (ret < 0) {
        av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
               "the second pass (add_keyframe_index)\n", s->filename);
        goto end;
    }

    /* mark the end of the shift to up to the last data we wrote, and get ready
     * for writing */
    pos_end = avio_tell(s->pb);
    avio_seek(s->pb, flv->keyframes_info_offset + metadata_size, SEEK_SET);

    /* start reading at where the keyframe index information will be placed */
    avio_seek(read_pb, flv->keyframes_info_offset, SEEK_SET);
    pos = avio_tell(read_pb);

    /* shift data by chunk of at most keyframe *filepositions* and *times* size */
    read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], metadata_size);  \
    read_buf_id ^= 1;
    do {

        read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], metadata_size);  \
        read_buf_id ^= 1;
        n = read_size[read_buf_id];
        if (n < 0)
            break;
        avio_write(s->pb, read_buf[read_buf_id], n);
        pos += n;
    } while (pos <= pos_end);

    ff_format_io_close(s, &read_pb);

end:
    av_free(buf);
    return ret;
}


651 652 653 654 655 656 657
static int flv_write_header(AVFormatContext *s)
{
    int i;
    AVIOContext *pb = s->pb;
    FLVContext *flv = s->priv_data;

    for (i = 0; i < s->nb_streams; i++) {
658
        AVCodecParameters *par = s->streams[i]->codecpar;
659
        FLVStreamContext *sc;
660
        switch (par->codec_type) {
661 662 663 664 665
        case AVMEDIA_TYPE_VIDEO:
            if (s->streams[i]->avg_frame_rate.den &&
                s->streams[i]->avg_frame_rate.num) {
                flv->framerate = av_q2d(s->streams[i]->avg_frame_rate);
            }
666
            if (flv->video_par) {
667 668 669 670
                av_log(s, AV_LOG_ERROR,
                       "at most one video stream is supported in flv\n");
                return AVERROR(EINVAL);
            }
671 672 673
            flv->video_par = par;
            if (!ff_codec_get_tag(flv_video_codec_ids, par->codec_id))
                return unsupported_codec(s, "Video", par->codec_id);
674

675 676
            if (par->codec_id == AV_CODEC_ID_MPEG4 ||
                par->codec_id == AV_CODEC_ID_H263) {
677 678
                int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
                av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
679
                       "Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
680 681 682 683 684 685

                if (error) {
                    av_log(s, AV_LOG_ERROR,
                           "use vstrict=-1 / -strict -1 to use it anyway.\n");
                    return AVERROR(EINVAL);
                }
686
            } else if (par->codec_id == AV_CODEC_ID_VP6) {
687 688
                av_log(s, AV_LOG_WARNING,
                       "Muxing VP6 in flv will produce flipped video on playback.\n");
689 690 691
            }
            break;
        case AVMEDIA_TYPE_AUDIO:
692
            if (flv->audio_par) {
693 694 695 696
                av_log(s, AV_LOG_ERROR,
                       "at most one audio stream is supported in flv\n");
                return AVERROR(EINVAL);
            }
697 698 699
            flv->audio_par = par;
            if (get_audio_flags(s, par) < 0)
                return unsupported_codec(s, "Audio", par->codec_id);
700
            if (par->codec_id == AV_CODEC_ID_PCM_S16BE)
701 702
                av_log(s, AV_LOG_WARNING,
                       "16-bit big-endian audio in flv is valid but most likely unplayable (hardware dependent); use s16le\n");
703 704
            break;
        case AVMEDIA_TYPE_DATA:
705
            if (par->codec_id != AV_CODEC_ID_TEXT && par->codec_id != AV_CODEC_ID_NONE)
706 707
                return unsupported_codec(s, "Data", par->codec_id);
            flv->data_par = par;
708
            break;
709
        case AVMEDIA_TYPE_SUBTITLE:
710
            if (par->codec_id != AV_CODEC_ID_TEXT) {
711
                av_log(s, AV_LOG_ERROR, "Subtitle codec '%s' for stream %d is not compatible with FLV\n",
712
                       avcodec_get_name(par->codec_id), i);
713 714
                return AVERROR_INVALIDDATA;
            }
715
            flv->data_par = par;
716
            break;
717
        default:
718
            av_log(s, AV_LOG_ERROR, "Codec type '%s' for stream %d is not compatible with FLV\n",
719
                   av_get_media_type_string(par->codec_type), i);
720
            return AVERROR(EINVAL);
721 722 723 724 725 726 727 728 729 730 731 732 733 734
        }
        avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */

        sc = av_mallocz(sizeof(FLVStreamContext));
        if (!sc)
            return AVERROR(ENOMEM);
        s->streams[i]->priv_data = sc;
        sc->last_ts = -1;
    }

    flv->delay = AV_NOPTS_VALUE;

    avio_write(pb, "FLV", 3);
    avio_w8(pb, 1);
735 736
    avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!flv->audio_par +
                FLV_HEADER_FLAG_HASVIDEO * !!flv->video_par);
737 738 739 740
    avio_wb32(pb, 9);
    avio_wb32(pb, 0);

    for (i = 0; i < s->nb_streams; i++)
741
        if (s->streams[i]->codecpar->codec_tag == 5) {
742 743 744 745 746 747 748 749
            avio_w8(pb, 8);     // message type
            avio_wb24(pb, 0);   // include flags
            avio_wb24(pb, 0);   // time stamp
            avio_wb32(pb, 0);   // reserved
            avio_wb32(pb, 11);  // size
            flv->reserved = 5;
        }

750 751 752 753 754
    if (flv->flags & FLV_NO_METADATA) {
        pb->seekable = 0;
    } else {
        write_metadata(s, 0);
    }
755

756
    for (i = 0; i < s->nb_streams; i++) {
757
        flv_write_codec_header(s, s->streams[i]->codecpar);
758 759
    }

760
    flv->datastart_offset = avio_tell(pb);
761 762 763 764 765
    return 0;
}

static int flv_write_trailer(AVFormatContext *s)
{
766
    int64_t file_size;
767
    AVIOContext *pb = s->pb;
768
    FLVContext *flv = s->priv_data;
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786
    int build_keyframes_idx = flv->flags & FLV_ADD_KEYFRAME_INDEX;
    int i, res;
    int64_t cur_pos = avio_tell(s->pb);

    if (build_keyframes_idx) {
        FLVFileposition *newflv_posinfo, *p;

        avio_seek(pb, flv->videosize_offset, SEEK_SET);
        put_amf_double(pb, flv->videosize);

        avio_seek(pb, flv->audiosize_offset, SEEK_SET);
        put_amf_double(pb, flv->audiosize);

        avio_seek(pb, flv->lasttimestamp_offset, SEEK_SET);
        put_amf_double(pb, flv->lasttimestamp);

        avio_seek(pb, flv->lastkeyframetimestamp_offset, SEEK_SET);
        put_amf_double(pb, flv->lastkeyframetimestamp);
787

788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
        avio_seek(pb, flv->lastkeyframelocation_offset, SEEK_SET);
        put_amf_double(pb, flv->lastkeyframelocation + flv->keyframe_index_size);
        avio_seek(pb, cur_pos, SEEK_SET);

        res = shift_data(s);
        if (res < 0) {
             goto end;
        }
        avio_seek(pb, flv->keyframes_info_offset, SEEK_SET);
        put_amf_string(pb, "filepositions");
        put_amf_dword_array(pb, flv->filepositions_count);
        for (newflv_posinfo = flv->head_filepositions; newflv_posinfo; newflv_posinfo = newflv_posinfo->next) {
            put_amf_double(pb, newflv_posinfo->keyframe_position + flv->keyframe_index_size);
        }

        put_amf_string(pb, "times");
        put_amf_dword_array(pb, flv->filepositions_count);
        for (newflv_posinfo = flv->head_filepositions; newflv_posinfo; newflv_posinfo = newflv_posinfo->next) {
            put_amf_double(pb, newflv_posinfo->keyframe_timestamp);
        }

        newflv_posinfo = flv->head_filepositions;
        while (newflv_posinfo) {
            p = newflv_posinfo->next;
            if (p) {
                newflv_posinfo->next = p->next;
                av_free(p);
                p = NULL;
            } else {
                av_free(newflv_posinfo);
                newflv_posinfo = NULL;
            }
        }

        put_amf_string(pb, "");
        avio_w8(pb, AMF_END_OF_OBJECT);

        avio_seek(pb, cur_pos + flv->keyframe_index_size, SEEK_SET);
    }

end:
829 830 831 832 833 834 835 836 837 838 839
    if (flv->flags & FLV_NO_SEQUENCE_END) {
        av_log(s, AV_LOG_DEBUG, "FLV no sequence end mode open\n");
    } else {
        /* Add EOS tag */
        for (i = 0; i < s->nb_streams; i++) {
            AVCodecParameters *par = s->streams[i]->codecpar;
            FLVStreamContext *sc = s->streams[i]->priv_data;
            if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
                    (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4))
                put_avc_eos_tag(pb, sc->last_ts);
        }
840
    }
841

842
    file_size = avio_tell(pb);
843

844 845 846 847 848
    if (build_keyframes_idx) {
        flv->datasize = file_size - flv->datastart_offset;
        avio_seek(pb, flv->datasize_offset, SEEK_SET);
        put_amf_double(pb, flv->datasize);
    }
849
    if (!(flv->flags & FLV_NO_DURATION_FILESIZE)) {
850 851 852 853 854 855 856 857 858 859 860 861
        /* update information */
        if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0) {
            av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n");
        } else {
            put_amf_double(pb, flv->duration / (double)1000);
        }
        if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0) {
            av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n");
        } else {
            put_amf_double(pb, file_size);
        }
    }
862
    avio_seek(pb, file_size, SEEK_SET);
863 864 865
    return 0;
}

866
static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
867
{
868
    AVIOContext *pb      = s->pb;
869
    AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
870
    FLVContext *flv      = s->priv_data;
871
    FLVStreamContext *sc = s->streams[pkt->stream_index]->priv_data;
872
    unsigned ts;
873 874
    int size = pkt->size;
    uint8_t *data = NULL;
875
    int flags = -1, flags_size, ret;
876
    int64_t cur_offset = avio_tell(pb);
877

878
    if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
879
        par->codec_id == AV_CODEC_ID_VP6  || par->codec_id == AV_CODEC_ID_AAC)
880
        flags_size = 2;
881
    else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4)
882
        flags_size = 5;
883
    else
884
        flags_size = 1;
885

886 887 888 889 890 891 892
    if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
            || par->codec_id == AV_CODEC_ID_MPEG4) {
        int side_size = 0;
        uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
        if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
            av_free(par->extradata);
            par->extradata = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
893 894 895 896
            if (!par->extradata) {
                par->extradata_size = 0;
                return AVERROR(ENOMEM);
            }
897 898 899 900 901 902
            memcpy(par->extradata, side, side_size);
            par->extradata_size = side_size;
            flv_write_codec_header(s, par);
        }
    }

903 904 905 906 907 908 909 910 911
    if (flv->delay == AV_NOPTS_VALUE)
        flv->delay = -pkt->dts;

    if (pkt->dts < -flv->delay) {
        av_log(s, AV_LOG_WARNING,
               "Packets are not in the proper order with respect to DTS\n");
        return AVERROR(EINVAL);
    }

912
    ts = pkt->dts;
913 914 915 916 917 918

    if (s->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
        write_metadata(s, ts);
        s->event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
    }

919 920 921
    avio_write_marker(pb, av_rescale(ts, AV_TIME_BASE, 1000),
                      pkt->flags & AV_PKT_FLAG_KEY && (flv->video_par ? par->codec_type == AVMEDIA_TYPE_VIDEO : 1) ? AVIO_DATA_MARKER_SYNC_POINT : AVIO_DATA_MARKER_BOUNDARY_POINT);

922
    switch (par->codec_type) {
923
    case AVMEDIA_TYPE_VIDEO:
924
        avio_w8(pb, FLV_TAG_TYPE_VIDEO);
925

926
        flags = ff_codec_get_tag(flv_video_codec_ids, par->codec_id);
927

928
        flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER;
929 930
        break;
    case AVMEDIA_TYPE_AUDIO:
931
        flags = get_audio_flags(s, par);
932

933
        av_assert0(size);
Michael Niedermayer's avatar
Michael Niedermayer committed
934

935
        avio_w8(pb, FLV_TAG_TYPE_AUDIO);
936
        break;
937
    case AVMEDIA_TYPE_SUBTITLE:
938
    case AVMEDIA_TYPE_DATA:
939
        avio_w8(pb, FLV_TAG_TYPE_META);
940 941 942
        break;
    default:
        return AVERROR(EINVAL);
Michael Niedermayer's avatar
Michael Niedermayer committed
943
    }
944

945
    if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
946
        /* check if extradata looks like mp4 formatted */
947
        if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
948 949
            if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0)
                return ret;
950
    } else if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
951
               (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
952
        if (!s->streams[pkt->stream_index]->nb_frames) {
953
        av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
954
               "use the audio bitstream filter 'aac_adtstoasc' to fix it "
955
               "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
956
        return AVERROR_INVALIDDATA;
957 958
        }
        av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
959
    }
960

961
    /* check Speex packet duration */
962
    if (par->codec_id == AV_CODEC_ID_SPEEX && ts - sc->last_ts > 160)
963 964 965 966
        av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than "
                                  "8 frames per packet. Adobe Flash "
                                  "Player cannot handle this!\n");

967 968
    if (sc->last_ts < ts)
        sc->last_ts = ts;
969

970 971 972 973 974 975
    if (size + flags_size >= 1<<24) {
        av_log(s, AV_LOG_ERROR, "Too large packet with size %u >= %u\n",
               size + flags_size, 1<<24);
        return AVERROR(EINVAL);
    }

976
    avio_wb24(pb, size + flags_size);
977
    avio_wb24(pb, ts & 0xFFFFFF);
978 979
    avio_w8(pb, (ts >> 24) & 0x7F); // timestamps are 32 bits _signed_
    avio_wb24(pb, flv->reserved);
980

981 982
    if (par->codec_type == AVMEDIA_TYPE_DATA ||
        par->codec_type == AVMEDIA_TYPE_SUBTITLE ) {
983
        int data_size;
984
        int64_t metadata_size_pos = avio_tell(pb);
985
        if (par->codec_id == AV_CODEC_ID_TEXT) {
986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002
            // legacy FFmpeg magic?
            avio_w8(pb, AMF_DATA_TYPE_STRING);
            put_amf_string(pb, "onTextData");
            avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
            avio_wb32(pb, 2);
            put_amf_string(pb, "type");
            avio_w8(pb, AMF_DATA_TYPE_STRING);
            put_amf_string(pb, "Text");
            put_amf_string(pb, "text");
            avio_w8(pb, AMF_DATA_TYPE_STRING);
            put_amf_string(pb, pkt->data);
            put_amf_string(pb, "");
            avio_w8(pb, AMF_END_OF_OBJECT);
        } else {
            // just pass the metadata through
            avio_write(pb, data ? data : pkt->data, size);
        }
1003 1004 1005 1006 1007 1008 1009
        /* write total size of tag */
        data_size = avio_tell(pb) - metadata_size_pos;
        avio_seek(pb, metadata_size_pos - 10, SEEK_SET);
        avio_wb24(pb, data_size);
        avio_seek(pb, data_size + 10 - 3, SEEK_CUR);
        avio_wb32(pb, data_size + 11);
    } else {
1010
        av_assert1(flags>=0);
1011
        avio_w8(pb,flags);
1012
        if (par->codec_id == AV_CODEC_ID_VP6)
1013
            avio_w8(pb,0);
1014 1015 1016
        if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A) {
            if (par->extradata_size)
                avio_w8(pb, par->extradata[0]);
1017
            else
1018 1019 1020
                avio_w8(pb, ((FFALIGN(par->width,  16) - par->width) << 4) |
                             (FFALIGN(par->height, 16) - par->height));
        } else if (par->codec_id == AV_CODEC_ID_AAC)
1021
            avio_w8(pb, 1); // AAC raw
1022
        else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
1023 1024 1025
            avio_w8(pb, 1); // AVC NALU
            avio_wb24(pb, pkt->pts - pkt->dts);
        }
1026

1027
        avio_write(pb, data ? data : pkt->data, size);
1028

1029 1030 1031
        avio_wb32(pb, size + flags_size + 11); // previous tag size
        flv->duration = FFMAX(flv->duration,
                              pkt->pts + flv->delay + pkt->duration);
1032
    }
1033

1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
    if (flv->flags & FLV_ADD_KEYFRAME_INDEX) {
        switch (par->codec_type) {
            case AVMEDIA_TYPE_VIDEO:
                flv->videosize += (avio_tell(pb) - cur_offset);
                flv->lasttimestamp = flv->acurframeindex / flv->framerate;
                if (pkt->flags & AV_PKT_FLAG_KEY) {
                    double ts = flv->acurframeindex / flv->framerate;
                    int64_t pos = cur_offset;

                    flv->lastkeyframetimestamp = flv->acurframeindex / flv->framerate;
                    flv->lastkeyframelocation = pos;
                    flv_append_keyframe_info(s, flv, ts, pos);
                }
                flv->acurframeindex++;
                break;

            case AVMEDIA_TYPE_AUDIO:
                flv->audiosize += (avio_tell(pb) - cur_offset);
                break;

            default:
                av_log(s, AV_LOG_WARNING, "par->codec_type is type = [%d]\n", par->codec_type);
                break;
        }
    }

1060 1061
    av_free(data);

1062
    return pb->error;
1063 1064
}

1065 1066
static const AVOption options[] = {
    { "flvflags", "FLV muxer flags", offsetof(FLVContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" },
1067
    { "aac_seq_header_detect", "Put AAC sequence header based on stream data", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_AAC_SEQ_HEADER_DETECT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" },
1068
    { "no_sequence_end", "disable sequence end for FLV", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_NO_SEQUENCE_END}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" },
1069
    { "no_metadata", "disable metadata for FLV", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_NO_METADATA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" },
1070
    { "no_duration_filesize", "disable duration and filesize zero value metadata for FLV", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_NO_DURATION_FILESIZE}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" },
1071
    { "add_keyframe_index", "Add keyframe index metadata", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_ADD_KEYFRAME_INDEX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" },
1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
    { NULL },
};

static const AVClass flv_muxer_class = {
    .class_name = "flv muxer",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

1082
AVOutputFormat ff_flv_muxer = {
1083
    .name           = "flv",
1084
    .long_name      = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),
1085 1086 1087
    .mime_type      = "video/x-flv",
    .extensions     = "flv",
    .priv_data_size = sizeof(FLVContext),
1088 1089
    .audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF,
    .video_codec    = AV_CODEC_ID_FLV1,
1090 1091 1092
    .write_header   = flv_write_header,
    .write_packet   = flv_write_packet,
    .write_trailer  = flv_write_trailer,
1093 1094 1095
    .codec_tag      = (const AVCodecTag* const []) {
                          flv_video_codec_ids, flv_audio_codec_ids, 0
                      },
1096 1097
    .flags          = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
                      AVFMT_TS_NONSTRICT,
1098
    .priv_class     = &flv_muxer_class,
1099
};