Statistics
| Branch: | Revision:

ffmpeg / libavformat / flvenc.c @ c04c3282

History | View | Annotate | Download (4.79 KB)

1 d4f5d74a Garrick Meeker
/*
2
 * FLV encoder.
3
 * Copyright (c) 2003 The FFmpeg Project.
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 d4f5d74a Garrick Meeker
 */
19
#include "avformat.h"
20
21 068f2a22 Michael Niedermayer
#undef NDEBUG
22
#include <assert.h>
23
24 d4f5d74a Garrick Meeker
typedef struct FLVContext {
25
    int hasAudio;
26
    int hasVideo;
27 11a8e425 Michael Niedermayer
    int reserved;
28 d4f5d74a Garrick Meeker
} FLVContext;
29
30 37cdf93d Michael Niedermayer
static int get_audio_flags(AVCodecContext *enc){
31 2f5132e7 Alex Beregszaszi
    int flags = (enc->bits_per_sample == 16) ? 0x2 : 0x0;
32 37cdf93d Michael Niedermayer
33
    switch (enc->sample_rate) {
34
        case    44100:
35
            flags |= 0x0C;
36
            break;
37
        case    22050:
38
            flags |= 0x08;
39
            break;
40
        case    11025:
41
            flags |= 0x04;
42
            break;
43
        case     8000: //nellymoser only
44
        case     5512: //not mp3
45
            flags |= 0x00;
46
            break;
47
        default:
48 a254c574 Michael Niedermayer
            av_log(enc, AV_LOG_ERROR, "flv doesnt support that sample rate, choose from (44100, 22050, 11025)\n");
49 37cdf93d Michael Niedermayer
            return -1;
50
    }
51
52
    if (enc->channels > 1) {
53
        flags |= 0x01;
54
    }
55 115329f1 Diego Biurrun
56 37cdf93d Michael Niedermayer
    switch(enc->codec_id){
57
    case CODEC_ID_MP3:
58 923bd441 Alex Beregszaszi
        flags |= 0x20 | 0x2;
59 37cdf93d Michael Niedermayer
        break;
60 923bd441 Alex Beregszaszi
    case CODEC_ID_PCM_S8:
61 bb270c08 Diego Biurrun
        break;
62 923bd441 Alex Beregszaszi
    case CODEC_ID_PCM_S16BE:
63 bb270c08 Diego Biurrun
        flags |= 0x60 | 0x2;
64
        break;
65 923bd441 Alex Beregszaszi
    case CODEC_ID_PCM_S16LE:
66 bb270c08 Diego Biurrun
        flags |= 0x2;
67
        break;
68 2fde8aae Alex Beregszaszi
    case CODEC_ID_ADPCM_SWF:
69 bb270c08 Diego Biurrun
        flags |= 0x10;
70
        break;
71 37cdf93d Michael Niedermayer
    case 0:
72
        flags |= enc->codec_tag<<4;
73
        break;
74
    default:
75 a254c574 Michael Niedermayer
        av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n");
76 37cdf93d Michael Niedermayer
        return -1;
77
    }
78 115329f1 Diego Biurrun
79 37cdf93d Michael Niedermayer
    return flags;
80
}
81
82 d4f5d74a Garrick Meeker
static int flv_write_header(AVFormatContext *s)
83
{
84
    ByteIOContext *pb = &s->pb;
85
    FLVContext *flv = s->priv_data;
86 11a8e425 Michael Niedermayer
    int i;
87 d4f5d74a Garrick Meeker
88
    flv->hasAudio = 0;
89
    flv->hasVideo = 0;
90
91
    put_tag(pb,"FLV");
92
    put_byte(pb,1);
93
    put_byte(pb,0); // delayed write
94
    put_be32(pb,9);
95
    put_be32(pb,0);
96 115329f1 Diego Biurrun
97 11a8e425 Michael Niedermayer
    for(i=0; i<s->nb_streams; i++){
98 01f4895c Michael Niedermayer
        AVCodecContext *enc = s->streams[i]->codec;
99 9ee91c2f Michael Niedermayer
        av_set_pts_info(s->streams[i], 24, 1, 1000); /* 24 bit pts in ms */
100 11a8e425 Michael Niedermayer
        if(enc->codec_tag == 5){
101
            put_byte(pb,8); // message type
102
            put_be24(pb,0); // include flags
103
            put_be24(pb,0); // time stamp
104
            put_be32(pb,0); // reserved
105
            put_be32(pb,11); // size
106
            flv->reserved=5;
107
        }
108 37cdf93d Michael Niedermayer
        if(enc->codec_type == CODEC_TYPE_AUDIO && get_audio_flags(enc)<0)
109
            return -1;
110 11a8e425 Michael Niedermayer
    }
111 d4f5d74a Garrick Meeker
112
    return 0;
113
}
114
115
static int flv_write_trailer(AVFormatContext *s)
116
{
117 14b32253 Michael Niedermayer
    int64_t file_size;
118
    int flags = 0;
119
120 d4f5d74a Garrick Meeker
    ByteIOContext *pb = &s->pb;
121
    FLVContext *flv = s->priv_data;
122
123 14b32253 Michael Niedermayer
    file_size = url_ftell(pb);
124 d4f5d74a Garrick Meeker
    flags |= flv->hasAudio ? 4 : 0;
125
    flags |= flv->hasVideo ? 1 : 0;
126
    url_fseek(pb, 4, SEEK_SET);
127
    put_byte(pb,flags);
128
    url_fseek(pb, file_size, SEEK_SET);
129
    return 0;
130
}
131
132 e928649b Michael Niedermayer
static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
133 d4f5d74a Garrick Meeker
{
134
    ByteIOContext *pb = &s->pb;
135 01f4895c Michael Niedermayer
    AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
136 d4f5d74a Garrick Meeker
    FLVContext *flv = s->priv_data;
137 e928649b Michael Niedermayer
    int size= pkt->size;
138 75293f05 Michael Niedermayer
    int flags;
139 d4f5d74a Garrick Meeker
140 068f2a22 Michael Niedermayer
//    av_log(s, AV_LOG_DEBUG, "type:%d pts: %lld size:%d\n", enc->codec_type, timestamp, size);
141 115329f1 Diego Biurrun
142 d4f5d74a Garrick Meeker
    if (enc->codec_type == CODEC_TYPE_VIDEO) {
143 75293f05 Michael Niedermayer
        put_byte(pb, 9);
144
        flags = 2; // choose h263
145
        flags |= pkt->flags & PKT_FLAG_KEY ? 0x10 : 0x20; // add keyframe indicator
146 d4f5d74a Garrick Meeker
        flv->hasVideo = 1;
147 75293f05 Michael Niedermayer
    } else {
148
        assert(enc->codec_type == CODEC_TYPE_AUDIO);
149 37cdf93d Michael Niedermayer
        flags = get_audio_flags(enc);
150 115329f1 Diego Biurrun
151 068f2a22 Michael Niedermayer
        assert(size);
152
153 75293f05 Michael Niedermayer
        put_byte(pb, 8);
154 068f2a22 Michael Niedermayer
155
        // We got audio! Make sure we set this to the global flags on closure
156
        flv->hasAudio = 1;
157 75293f05 Michael Niedermayer
    }
158
159
    put_be24(pb,size+1); // include flags
160
    put_be24(pb,pkt->pts);
161
    put_be32(pb,flv->reserved);
162
    put_byte(pb,flags);
163
    put_buffer(pb, pkt->data, size);
164 923bd441 Alex Beregszaszi
    put_be32(pb,size+1+11); // previous tag size
165 115329f1 Diego Biurrun
166 d4f5d74a Garrick Meeker
    put_flush_packet(pb);
167
    return 0;
168
}
169
170
static AVOutputFormat flv_oformat = {
171
    "flv",
172
    "flv format",
173 e817a73d Michael Niedermayer
    "video/x-flv",
174 d4f5d74a Garrick Meeker
    "flv",
175
    sizeof(FLVContext),
176
#ifdef CONFIG_MP3LAME
177 80783dc2 Fabrice Bellard
    CODEC_ID_MP3,
178 d4f5d74a Garrick Meeker
#else // CONFIG_MP3LAME
179
    CODEC_ID_NONE,
180
#endif // CONFIG_MP3LAME
181
    CODEC_ID_FLV1,
182
    flv_write_header,
183
    flv_write_packet,
184
    flv_write_trailer,
185
};
186
187
int flvenc_init(void)
188
{
189
    av_register_output_format(&flv_oformat);
190
    return 0;
191
}