Statistics
| Branch: | Revision:

ffmpeg / libavformat / flvenc.c @ 2fde8aae

History | View | Annotate | Download (4.76 KB)

1
/*
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
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19
#include "avformat.h"
20

    
21
#undef NDEBUG
22
#include <assert.h>
23

    
24
typedef struct FLVContext {
25
    int hasAudio;
26
    int hasVideo;
27
    int reserved;
28
} FLVContext;
29

    
30
static int get_audio_flags(AVCodecContext *enc){
31
    int flags = (enc->bits_per_sample == 16) ? 0x2 : 0x0;
32

    
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
            av_log(enc, AV_LOG_ERROR, "flv doesnt support that sample rate, choose from (44100, 22050, 11025)\n");
49
            return -1;
50
    }
51

    
52
    if (enc->channels > 1) {
53
        flags |= 0x01;
54
    }
55
    
56
    switch(enc->codec_id){
57
    case CODEC_ID_MP3:
58
        flags |= 0x20 | 0x2;
59
        break;
60
    case CODEC_ID_PCM_S8:
61
        break;
62
    case CODEC_ID_PCM_S16BE:
63
        flags |= 0x60 | 0x2;
64
        break;
65
    case CODEC_ID_PCM_S16LE:
66
        flags |= 0x2;
67
        break;
68
    case CODEC_ID_ADPCM_SWF:
69
        flags |= 0x10;
70
        break;
71
    case 0:
72
        flags |= enc->codec_tag<<4;
73
        break;
74
    default:
75
        av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n");
76
        return -1;
77
    }
78
    
79
    return flags;
80
}
81

    
82
static int flv_write_header(AVFormatContext *s)
83
{
84
    ByteIOContext *pb = &s->pb;
85
    FLVContext *flv = s->priv_data;
86
    int i;
87

    
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
    
97
    for(i=0; i<s->nb_streams; i++){
98
        AVCodecContext *enc = s->streams[i]->codec;
99
        av_set_pts_info(s->streams[i], 24, 1, 1000); /* 24 bit pts in ms */
100
        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
        if(enc->codec_type == CODEC_TYPE_AUDIO && get_audio_flags(enc)<0)
109
            return -1;
110
    }
111

    
112
    return 0;
113
}
114

    
115
static int flv_write_trailer(AVFormatContext *s)
116
{
117
    int64_t file_size;
118
    int flags = 0;
119

    
120
    ByteIOContext *pb = &s->pb;
121
    FLVContext *flv = s->priv_data;
122

    
123
    file_size = url_ftell(pb);
124
    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
static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
133
{
134
    ByteIOContext *pb = &s->pb;
135
    AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
136
    FLVContext *flv = s->priv_data;
137
    int size= pkt->size;
138
    int flags;
139

    
140
//    av_log(s, AV_LOG_DEBUG, "type:%d pts: %lld size:%d\n", enc->codec_type, timestamp, size);
141
    
142
    if (enc->codec_type == CODEC_TYPE_VIDEO) {
143
        put_byte(pb, 9);
144
        flags = 2; // choose h263
145
        flags |= pkt->flags & PKT_FLAG_KEY ? 0x10 : 0x20; // add keyframe indicator
146
        flv->hasVideo = 1;
147
    } else {
148
        assert(enc->codec_type == CODEC_TYPE_AUDIO);
149
        flags = get_audio_flags(enc);
150
        
151
        assert(size);
152

    
153
        put_byte(pb, 8);
154

    
155
        // We got audio! Make sure we set this to the global flags on closure
156
        flv->hasAudio = 1;
157
    }
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
    put_be32(pb,size+1+11); // previous tag size
165
    
166
    put_flush_packet(pb);
167
    return 0;
168
}
169

    
170
static AVOutputFormat flv_oformat = {
171
    "flv",
172
    "flv format",
173
    "video/x-flv",
174
    "flv",
175
    sizeof(FLVContext),
176
#ifdef CONFIG_MP3LAME
177
    CODEC_ID_MP3,
178
#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
}