Statistics
| Branch: | Revision:

ffmpeg / libavformat / flvdec.c @ f956e129

History | View | Annotate | Download (7.9 KB)

1 d4f5d74a Garrick Meeker
/*
2 7fbde343 Aurelien Jacobs
 * FLV demuxer
3 d4f5d74a Garrick Meeker
 * Copyright (c) 2003 The FFmpeg Project.
4
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 d4f5d74a Garrick Meeker
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 d4f5d74a Garrick Meeker
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 d4f5d74a Garrick Meeker
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 246f86a4 Aurelien Jacobs
 *
21
 *
22
 * This demuxer will generate a 1 byte extradata for VP6F content.
23
 * It is composed of:
24
 *  - upper 4bits: difference between encoded width and visible width
25
 *  - lower 4bits: difference between encoded height and visible height
26 d4f5d74a Garrick Meeker
 */
27
#include "avformat.h"
28
29
static int flv_probe(AVProbeData *p)
30
{
31
    const uint8_t *d;
32
33
    if (p->buf_size < 6)
34
        return 0;
35
    d = p->buf;
36
    if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V') {
37
        return 50;
38
    }
39
    return 0;
40
}
41
42
static int flv_read_header(AVFormatContext *s,
43
                           AVFormatParameters *ap)
44
{
45 dbdaebe2 Michael Niedermayer
    int offset, flags, size;
46 115329f1 Diego Biurrun
47 bb01a3f0 Michael Niedermayer
    s->ctx_flags |= AVFMTCTX_NOHEADER; //ok we have a header but theres no fps, codec type, sample_rate, ...
48 d4f5d74a Garrick Meeker
49
    url_fskip(&s->pb, 4);
50
    flags = get_byte(&s->pb);
51
52
    offset = get_be32(&s->pb);
53 dbdaebe2 Michael Niedermayer
54
    if(!url_is_streamed(&s->pb)){
55
        const int fsize= url_fsize(&s->pb);
56
        url_fseek(&s->pb, fsize-4, SEEK_SET);
57
        size= get_be32(&s->pb);
58
        url_fseek(&s->pb, fsize-3-size, SEEK_SET);
59
        if(size == get_be24(&s->pb) + 11){
60
            s->duration= get_be24(&s->pb) * (int64_t)AV_TIME_BASE / 1000;
61
        }
62
    }
63
64 d4f5d74a Garrick Meeker
    url_fseek(&s->pb, offset, SEEK_SET);
65
66 aeb20f7f Nazo
    s->start_time = 0;
67
68 d4f5d74a Garrick Meeker
    return 0;
69
}
70
71
static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
72
{
73 aeb20f7f Nazo
    int ret, i, type, size, pts, flags, is_audio, next, pos;
74 923bd441 Alex Beregszaszi
    AVStream *st = NULL;
75 115329f1 Diego Biurrun
76 068f2a22 Michael Niedermayer
 for(;;){
77 aeb20f7f Nazo
    pos = url_ftell(&s->pb);
78 d4f5d74a Garrick Meeker
    url_fskip(&s->pb, 4); /* size of previous packet */
79
    type = get_byte(&s->pb);
80
    size = get_be24(&s->pb);
81
    pts = get_be24(&s->pb);
82 92a26775 Michael Niedermayer
//    av_log(s, AV_LOG_DEBUG, "type:%d, size:%d, pts:%d\n", type, size, pts);
83 d4f5d74a Garrick Meeker
    if (url_feof(&s->pb))
84 0bd586c5 Mike Melanson
        return AVERROR_IO;
85 d4f5d74a Garrick Meeker
    url_fskip(&s->pb, 4); /* reserved */
86
    flags = 0;
87 115329f1 Diego Biurrun
88 068f2a22 Michael Niedermayer
    if(size == 0)
89
        continue;
90 115329f1 Diego Biurrun
91 dd9f5916 Michael Niedermayer
    next= size + url_ftell(&s->pb);
92
93 d4f5d74a Garrick Meeker
    if (type == 8) {
94 068f2a22 Michael Niedermayer
        is_audio=1;
95 d4f5d74a Garrick Meeker
        flags = get_byte(&s->pb);
96
    } else if (type == 9) {
97 068f2a22 Michael Niedermayer
        is_audio=0;
98 d4f5d74a Garrick Meeker
        flags = get_byte(&s->pb);
99 dd9f5916 Michael Niedermayer
    } else if (type == 18 && size > 13+1+4) {
100
        url_fskip(&s->pb, 13); //onMetaData blah
101
        if(get_byte(&s->pb) == 8){
102
            url_fskip(&s->pb, 4);
103
        }
104
        while(url_ftell(&s->pb) + 5 < next){
105
            char tmp[128];
106
            int type, len;
107
            double d= 0;
108 115329f1 Diego Biurrun
109 dd9f5916 Michael Niedermayer
            len= get_be16(&s->pb);
110
            if(len >= sizeof(tmp) || !len)
111
                break;
112
            get_buffer(&s->pb, tmp, len);
113
            tmp[len]=0;
114 115329f1 Diego Biurrun
115 dd9f5916 Michael Niedermayer
            type= get_byte(&s->pb);
116
            if(type==0){
117
                d= av_int2dbl(get_be64(&s->pb));
118
            }else if(type==2){
119
                len= get_be16(&s->pb);
120
                if(len >= sizeof(tmp))
121
                    break;
122
                url_fskip(&s->pb, len);
123
            }else if(type==8){
124
                //array
125
                break;
126
            }else if(type==11){
127
                d= av_int2dbl(get_be64(&s->pb));
128
                get_be16(&s->pb);
129
            }
130 115329f1 Diego Biurrun
131 dd9f5916 Michael Niedermayer
            if(!strcmp(tmp, "duration")){
132
                s->duration = d*AV_TIME_BASE;
133
            }else if(!strcmp(tmp, "videodatarate")){
134
            }else if(!strcmp(tmp, "audiodatarate")){
135
            }
136
        }
137
        url_fseek(&s->pb, next, SEEK_SET);
138
        continue;
139 d4f5d74a Garrick Meeker
    } else {
140
        /* skip packet */
141 bc874dae Michel Bardiaux
        av_log(s, AV_LOG_ERROR, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
142 dd9f5916 Michael Niedermayer
        url_fseek(&s->pb, next, SEEK_SET);
143 068f2a22 Michael Niedermayer
        continue;
144 d4f5d74a Garrick Meeker
    }
145
146
    /* now find stream */
147
    for(i=0;i<s->nb_streams;i++) {
148
        st = s->streams[i];
149 068f2a22 Michael Niedermayer
        if (st->id == is_audio)
150
            break;
151 d4f5d74a Garrick Meeker
    }
152 068f2a22 Michael Niedermayer
    if(i == s->nb_streams){
153
        st = av_new_stream(s, is_audio);
154
        if (!st)
155
            return AVERROR_NOMEM;
156 9ee91c2f Michael Niedermayer
157
        av_set_pts_info(st, 24, 1, 1000); /* 24 bit pts in ms */
158 01f4895c Michael Niedermayer
        st->codec->time_base= (AVRational){1,1000};
159 6ed08157 Michael Niedermayer
    }
160 f3356e9c Michael Niedermayer
//    av_log(NULL, AV_LOG_DEBUG, "%d %X %d \n", is_audio, flags, st->discard);
161
    if(  (st->discard >= AVDISCARD_NONKEY && !((flags >> 4)==1 ||  is_audio))
162
       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags >> 4)==3 && !is_audio))
163
       || st->discard >= AVDISCARD_ALL
164
       ){
165 dd9f5916 Michael Niedermayer
        url_fseek(&s->pb, next, SEEK_SET);
166 b9866ebc Michael Niedermayer
        continue;
167
    }
168 aeb20f7f Nazo
    if ((flags >> 4)==1)
169
        av_add_index_entry(st, pos, pts, size, 0, AVINDEX_KEYFRAME);
170 068f2a22 Michael Niedermayer
    break;
171
 }
172
173
    if(is_audio){
174 01f4895c Michael Niedermayer
        if(st->codec->sample_rate == 0){
175
            st->codec->codec_type = CODEC_TYPE_AUDIO;
176
            st->codec->channels = (flags&1)+1;
177 068f2a22 Michael Niedermayer
            if((flags >> 4) == 5)
178 01f4895c Michael Niedermayer
                st->codec->sample_rate= 8000;
179 068f2a22 Michael Niedermayer
            else
180 01f4895c Michael Niedermayer
                st->codec->sample_rate = (44100<<((flags>>2)&3))>>3;
181 068f2a22 Michael Niedermayer
            switch(flags >> 4){/* 0: uncompressed 1: ADPCM 2: mp3 5: Nellymoser 8kHz mono 6: Nellymoser*/
182 bb270c08 Diego Biurrun
            case 0: if (flags&2) st->codec->codec_id = CODEC_ID_PCM_S16BE;
183
                    else st->codec->codec_id = CODEC_ID_PCM_S8; break;
184
            case 1: st->codec->codec_id = CODEC_ID_ADPCM_SWF; break;
185 12b6992b Roberto Togni
            case 2: st->codec->codec_id = CODEC_ID_MP3; st->need_parsing = 1; break;
186 bb270c08 Diego Biurrun
            // this is not listed at FLV but at SWF, strange...
187
            case 3: if (flags&2) st->codec->codec_id = CODEC_ID_PCM_S16LE;
188
                    else st->codec->codec_id = CODEC_ID_PCM_S8; break;
189 068f2a22 Michael Niedermayer
            default:
190 bb270c08 Diego Biurrun
                    av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flags >> 4);
191 01f4895c Michael Niedermayer
                st->codec->codec_tag= (flags >> 4);
192 068f2a22 Michael Niedermayer
            }
193 bb270c08 Diego Biurrun
            st->codec->bits_per_sample = (flags & 2) ? 16 : 8;
194 068f2a22 Michael Niedermayer
        }
195
    }else{
196 01f4895c Michael Niedermayer
            st->codec->codec_type = CODEC_TYPE_VIDEO;
197 068f2a22 Michael Niedermayer
            switch(flags & 0xF){
198 01f4895c Michael Niedermayer
            case 2: st->codec->codec_id = CODEC_ID_FLV1; break;
199 0919e788 Benjamin Larsson
            case 3: st->codec->codec_id = CODEC_ID_FLASHSV; break;
200 5ce117c3 Aurelien Jacobs
            case 4:
201
                st->codec->codec_id = CODEC_ID_VP6F;
202 9e2424ce Aurelien Jacobs
                if (st->codec->extradata_size != 1) {
203
                    st->codec->extradata_size = 1;
204
                    st->codec->extradata = av_malloc(1);
205
                }
206
                /* width and height adjustment */
207
                st->codec->extradata[0] = get_byte(&s->pb);
208 5ce117c3 Aurelien Jacobs
                size--;
209
                break;
210 068f2a22 Michael Niedermayer
            default:
211 bb270c08 Diego Biurrun
                    av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flags & 0xf);
212 01f4895c Michael Niedermayer
                st->codec->codec_tag= flags & 0xF;
213 068f2a22 Michael Niedermayer
            }
214 bb01a3f0 Michael Niedermayer
    }
215
216 dd9f5916 Michael Niedermayer
    ret= av_get_packet(&s->pb, pkt, size - 1);
217 d4f5d74a Garrick Meeker
    if (ret <= 0) {
218 0bd586c5 Mike Melanson
        return AVERROR_IO;
219 d4f5d74a Garrick Meeker
    }
220
    /* note: we need to modify the packet size here to handle the last
221
       packet */
222
    pkt->size = ret;
223
    pkt->pts = pts;
224
    pkt->stream_index = st->index;
225 115329f1 Diego Biurrun
226 f3356e9c Michael Niedermayer
    if (is_audio || ((flags >> 4)==1))
227 bb270c08 Diego Biurrun
        pkt->flags |= PKT_FLAG_KEY;
228 115329f1 Diego Biurrun
229 d4f5d74a Garrick Meeker
    return ret;
230
}
231
232
static int flv_read_close(AVFormatContext *s)
233
{
234
    return 0;
235
}
236
237 aeb20f7f Nazo
static int flv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
238
{
239
    AVStream *st = s->streams[stream_index];
240
    int index = av_index_search_timestamp(st, timestamp, flags);
241
    if (index < 0)
242
        return -1;
243
    url_fseek(&s->pb, st->index_entries[index].pos, SEEK_SET);
244
245
    return 0;
246
}
247
248 d2a067d1 Måns Rullgård
AVInputFormat flv_demuxer = {
249 d4f5d74a Garrick Meeker
    "flv",
250
    "flv format",
251
    0,
252
    flv_probe,
253
    flv_read_header,
254
    flv_read_packet,
255
    flv_read_close,
256 aeb20f7f Nazo
    flv_read_seek,
257 d4f5d74a Garrick Meeker
    .extensions = "flv",
258
    .value = CODEC_ID_FLV1,
259
};