• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/flvdec.c

Go to the documentation of this file.
00001 /*
00002  * FLV demuxer
00003  * Copyright (c) 2003 The FFmpeg Project
00004  *
00005  * This demuxer will generate a 1 byte extradata for VP6F content.
00006  * It is composed of:
00007  *  - upper 4bits: difference between encoded width and visible width
00008  *  - lower 4bits: difference between encoded height and visible height
00009  *
00010  * This file is part of FFmpeg.
00011  *
00012  * FFmpeg is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Lesser General Public
00014  * License as published by the Free Software Foundation; either
00015  * version 2.1 of the License, or (at your option) any later version.
00016  *
00017  * FFmpeg is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  * Lesser General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU Lesser General Public
00023  * License along with FFmpeg; if not, write to the Free Software
00024  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00025  */
00026 
00027 #include "libavcodec/mpeg4audio.h"
00028 #include "avformat.h"
00029 #include "flv.h"
00030 
00031 typedef struct {
00032     int wrong_dts; 
00033 } FLVContext;
00034 
00035 static int flv_probe(AVProbeData *p)
00036 {
00037     const uint8_t *d;
00038 
00039     d = p->buf;
00040     if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V' && d[3] < 5 && d[5]==0) {
00041         return AVPROBE_SCORE_MAX;
00042     }
00043     return 0;
00044 }
00045 
00046 static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, int flv_codecid) {
00047     AVCodecContext *acodec = astream->codec;
00048     switch(flv_codecid) {
00049         //no distinction between S16 and S8 PCM codec flags
00050         case FLV_CODECID_PCM:
00051             acodec->codec_id = acodec->bits_per_coded_sample == 8 ? CODEC_ID_PCM_S8 :
00052 #ifdef WORDS_BIGENDIAN
00053                                 CODEC_ID_PCM_S16BE;
00054 #else
00055                                 CODEC_ID_PCM_S16LE;
00056 #endif
00057             break;
00058         case FLV_CODECID_PCM_LE:
00059             acodec->codec_id = acodec->bits_per_coded_sample == 8 ? CODEC_ID_PCM_S8 : CODEC_ID_PCM_S16LE; break;
00060         case FLV_CODECID_AAC  : acodec->codec_id = CODEC_ID_AAC;                                    break;
00061         case FLV_CODECID_ADPCM: acodec->codec_id = CODEC_ID_ADPCM_SWF;                              break;
00062         case FLV_CODECID_SPEEX:
00063             acodec->codec_id = CODEC_ID_SPEEX;
00064             acodec->sample_rate = 16000;
00065             break;
00066         case FLV_CODECID_MP3  : acodec->codec_id = CODEC_ID_MP3      ; astream->need_parsing = AVSTREAM_PARSE_FULL; break;
00067         case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
00068             acodec->sample_rate = 8000; //in case metadata does not otherwise declare samplerate
00069         case FLV_CODECID_NELLYMOSER:
00070             acodec->codec_id = CODEC_ID_NELLYMOSER;
00071             break;
00072         default:
00073             av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
00074             acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
00075     }
00076 }
00077 
00078 static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) {
00079     AVCodecContext *vcodec = vstream->codec;
00080     switch(flv_codecid) {
00081         case FLV_CODECID_H263  : vcodec->codec_id = CODEC_ID_FLV1   ; break;
00082         case FLV_CODECID_SCREEN: vcodec->codec_id = CODEC_ID_FLASHSV; break;
00083         case FLV_CODECID_VP6   : vcodec->codec_id = CODEC_ID_VP6F   ;
00084         case FLV_CODECID_VP6A  :
00085             if(flv_codecid == FLV_CODECID_VP6A)
00086                 vcodec->codec_id = CODEC_ID_VP6A;
00087             if(vcodec->extradata_size != 1) {
00088                 vcodec->extradata_size = 1;
00089                 vcodec->extradata = av_malloc(1);
00090             }
00091             vcodec->extradata[0] = get_byte(s->pb);
00092             return 1; // 1 byte body size adjustment for flv_read_packet()
00093         case FLV_CODECID_H264:
00094             vcodec->codec_id = CODEC_ID_H264;
00095             return 3; // not 4, reading packet type will consume one byte
00096         default:
00097             av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
00098             vcodec->codec_tag = flv_codecid;
00099     }
00100 
00101     return 0;
00102 }
00103 
00104 static int amf_get_string(ByteIOContext *ioc, char *buffer, int buffsize) {
00105     int length = get_be16(ioc);
00106     if(length >= buffsize) {
00107         url_fskip(ioc, length);
00108         return -1;
00109     }
00110 
00111     get_buffer(ioc, buffer, length);
00112 
00113     buffer[length] = '\0';
00114 
00115     return length;
00116 }
00117 
00118 static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) {
00119     AVCodecContext *acodec, *vcodec;
00120     ByteIOContext *ioc;
00121     AMFDataType amf_type;
00122     char str_val[256];
00123     double num_val;
00124 
00125     num_val = 0;
00126     ioc = s->pb;
00127 
00128     amf_type = get_byte(ioc);
00129 
00130     switch(amf_type) {
00131         case AMF_DATA_TYPE_NUMBER:
00132             num_val = av_int2dbl(get_be64(ioc)); break;
00133         case AMF_DATA_TYPE_BOOL:
00134             num_val = get_byte(ioc); break;
00135         case AMF_DATA_TYPE_STRING:
00136             if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0)
00137                 return -1;
00138             break;
00139         case AMF_DATA_TYPE_OBJECT: {
00140             unsigned int keylen;
00141 
00142             while(url_ftell(ioc) < max_pos - 2 && (keylen = get_be16(ioc))) {
00143                 url_fskip(ioc, keylen); //skip key string
00144                 if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0)
00145                     return -1; //if we couldn't skip, bomb out.
00146             }
00147             if(get_byte(ioc) != AMF_END_OF_OBJECT)
00148                 return -1;
00149         }
00150             break;
00151         case AMF_DATA_TYPE_NULL:
00152         case AMF_DATA_TYPE_UNDEFINED:
00153         case AMF_DATA_TYPE_UNSUPPORTED:
00154             break; //these take up no additional space
00155         case AMF_DATA_TYPE_MIXEDARRAY:
00156             url_fskip(ioc, 4); //skip 32-bit max array index
00157             while(url_ftell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
00158                 //this is the only case in which we would want a nested parse to not skip over the object
00159                 if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)
00160                     return -1;
00161             }
00162             if(get_byte(ioc) != AMF_END_OF_OBJECT)
00163                 return -1;
00164             break;
00165         case AMF_DATA_TYPE_ARRAY: {
00166             unsigned int arraylen, i;
00167 
00168             arraylen = get_be32(ioc);
00169             for(i = 0; i < arraylen && url_ftell(ioc) < max_pos - 1; i++) {
00170                 if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0)
00171                     return -1; //if we couldn't skip, bomb out.
00172             }
00173         }
00174             break;
00175         case AMF_DATA_TYPE_DATE:
00176             url_fskip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16)
00177             break;
00178         default: //unsupported type, we couldn't skip
00179             return -1;
00180     }
00181 
00182     if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL
00183         acodec = astream ? astream->codec : NULL;
00184         vcodec = vstream ? vstream->codec : NULL;
00185 
00186         if(amf_type == AMF_DATA_TYPE_BOOL) {
00187             if(!strcmp(key, "stereo") && acodec) acodec->channels = num_val > 0 ? 2 : 1;
00188         } else if(amf_type == AMF_DATA_TYPE_NUMBER) {
00189             if(!strcmp(key, "duration")) s->duration = num_val * AV_TIME_BASE;
00190 //            else if(!strcmp(key, "width")  && vcodec && num_val > 0) vcodec->width  = num_val;
00191 //            else if(!strcmp(key, "height") && vcodec && num_val > 0) vcodec->height = num_val;
00192             else if(!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
00193                 vcodec->bit_rate = num_val * 1024.0;
00194             else if(!strcmp(key, "audiocodecid") && acodec && 0 <= (int)num_val)
00195                 flv_set_audio_codec(s, astream, (int)num_val << FLV_AUDIO_CODECID_OFFSET);
00196             else if(!strcmp(key, "videocodecid") && vcodec && 0 <= (int)num_val)
00197                 flv_set_video_codec(s, vstream, (int)num_val);
00198             else if(!strcmp(key, "audiosamplesize") && acodec && 0 < (int)num_val) {
00199                 acodec->bits_per_coded_sample = num_val;
00200                 //we may have to rewrite a previously read codecid because FLV only marks PCM endianness.
00201                 if(num_val == 8 && (acodec->codec_id == CODEC_ID_PCM_S16BE || acodec->codec_id == CODEC_ID_PCM_S16LE))
00202                     acodec->codec_id = CODEC_ID_PCM_S8;
00203             }
00204             else if(!strcmp(key, "audiosamplerate") && acodec && num_val >= 0) {
00205                 //some tools, like FLVTool2, write consistently approximate metadata sample rates
00206                 if (!acodec->sample_rate) {
00207                     switch((int)num_val) {
00208                         case 44000: acodec->sample_rate = 44100  ; break;
00209                         case 22000: acodec->sample_rate = 22050  ; break;
00210                         case 11000: acodec->sample_rate = 11025  ; break;
00211                         case 5000 : acodec->sample_rate = 5512   ; break;
00212                         default   : acodec->sample_rate = num_val;
00213                     }
00214                 }
00215             }
00216         }
00217     }
00218 
00219     return 0;
00220 }
00221 
00222 static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
00223     AMFDataType type;
00224     AVStream *stream, *astream, *vstream;
00225     ByteIOContext *ioc;
00226     int i, keylen;
00227     char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want.
00228 
00229     astream = NULL;
00230     vstream = NULL;
00231     keylen = 0;
00232     ioc = s->pb;
00233 
00234     //first object needs to be "onMetaData" string
00235     type = get_byte(ioc);
00236     if(type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer, sizeof(buffer)) < 0 || strcmp(buffer, "onMetaData"))
00237         return -1;
00238 
00239     //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called.
00240     for(i = 0; i < s->nb_streams; i++) {
00241         stream = s->streams[i];
00242         if     (stream->codec->codec_type == CODEC_TYPE_AUDIO) astream = stream;
00243         else if(stream->codec->codec_type == CODEC_TYPE_VIDEO) vstream = stream;
00244     }
00245 
00246     //parse the second object (we want a mixed array)
00247     if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
00248         return -1;
00249 
00250     return 0;
00251 }
00252 
00253 static AVStream *create_stream(AVFormatContext *s, int is_audio){
00254     AVStream *st = av_new_stream(s, is_audio);
00255     if (!st)
00256         return NULL;
00257     st->codec->codec_type = is_audio ? CODEC_TYPE_AUDIO : CODEC_TYPE_VIDEO;
00258     av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
00259     return st;
00260 }
00261 
00262 static int flv_read_header(AVFormatContext *s,
00263                            AVFormatParameters *ap)
00264 {
00265     int offset, flags;
00266 
00267     url_fskip(s->pb, 4);
00268     flags = get_byte(s->pb);
00269     /* old flvtool cleared this field */
00270     /* FIXME: better fix needed */
00271     if (!flags) {
00272         flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO;
00273         av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n");
00274     }
00275 
00276     if((flags & (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO))
00277              != (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO))
00278         s->ctx_flags |= AVFMTCTX_NOHEADER;
00279 
00280     if(flags & FLV_HEADER_FLAG_HASVIDEO){
00281         if(!create_stream(s, 0))
00282             return AVERROR(ENOMEM);
00283     }
00284     if(flags & FLV_HEADER_FLAG_HASAUDIO){
00285         if(!create_stream(s, 1))
00286             return AVERROR(ENOMEM);
00287     }
00288 
00289     offset = get_be32(s->pb);
00290     url_fseek(s->pb, offset, SEEK_SET);
00291 
00292     s->start_time = 0;
00293 
00294     return 0;
00295 }
00296 
00297 static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size)
00298 {
00299     av_free(st->codec->extradata);
00300     st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
00301     if (!st->codec->extradata)
00302         return AVERROR(ENOMEM);
00303     st->codec->extradata_size = size;
00304     get_buffer(s->pb, st->codec->extradata, st->codec->extradata_size);
00305     return 0;
00306 }
00307 
00308 static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
00309 {
00310     FLVContext *flv = s->priv_data;
00311     int ret, i, type, size, flags, is_audio;
00312     int64_t next, pos;
00313     int64_t dts, pts = AV_NOPTS_VALUE;
00314     AVStream *st = NULL;
00315 
00316  retry:
00317  for(;;){
00318     pos = url_ftell(s->pb);
00319     url_fskip(s->pb, 4); /* size of previous packet */
00320     type = get_byte(s->pb);
00321     size = get_be24(s->pb);
00322     dts = get_be24(s->pb);
00323     dts |= get_byte(s->pb) << 24;
00324 //    av_log(s, AV_LOG_DEBUG, "type:%d, size:%d, dts:%d\n", type, size, dts);
00325     if (url_feof(s->pb))
00326         return AVERROR_EOF;
00327     url_fskip(s->pb, 3); /* stream id, always 0 */
00328     flags = 0;
00329 
00330     if(size == 0)
00331         continue;
00332 
00333     next= size + url_ftell(s->pb);
00334 
00335     if (type == FLV_TAG_TYPE_AUDIO) {
00336         is_audio=1;
00337         flags = get_byte(s->pb);
00338         size--;
00339     } else if (type == FLV_TAG_TYPE_VIDEO) {
00340         is_audio=0;
00341         flags = get_byte(s->pb);
00342         size--;
00343         if ((flags & 0xf0) == 0x50) /* video info / command frame */
00344             goto skip;
00345     } else {
00346         if (type == FLV_TAG_TYPE_META && size > 13+1+4)
00347             flv_read_metabody(s, next);
00348         else /* skip packet */
00349             av_log(s, AV_LOG_ERROR, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
00350     skip:
00351         url_fseek(s->pb, next, SEEK_SET);
00352         continue;
00353     }
00354 
00355     /* skip empty data packets */
00356     if (!size)
00357         continue;
00358 
00359     /* now find stream */
00360     for(i=0;i<s->nb_streams;i++) {
00361         st = s->streams[i];
00362         if (st->id == is_audio)
00363             break;
00364     }
00365     if(i == s->nb_streams){
00366         av_log(s, AV_LOG_ERROR, "invalid stream\n");
00367         st= create_stream(s, is_audio);
00368         s->ctx_flags &= ~AVFMTCTX_NOHEADER;
00369     }
00370 //    av_log(s, AV_LOG_DEBUG, "%d %X %d \n", is_audio, flags, st->discard);
00371     if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||         is_audio))
00372        ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio))
00373        || st->discard >= AVDISCARD_ALL
00374        ){
00375         url_fseek(s->pb, next, SEEK_SET);
00376         continue;
00377     }
00378     if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)
00379         av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
00380     break;
00381  }
00382 
00383     // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps
00384     if(!url_is_streamed(s->pb) && s->duration==AV_NOPTS_VALUE){
00385         int size;
00386         const int64_t pos= url_ftell(s->pb);
00387         const int64_t fsize= url_fsize(s->pb);
00388         url_fseek(s->pb, fsize-4, SEEK_SET);
00389         size= get_be32(s->pb);
00390         url_fseek(s->pb, fsize-3-size, SEEK_SET);
00391         if(size == get_be24(s->pb) + 11){
00392             s->duration= get_be24(s->pb) * (int64_t)AV_TIME_BASE / 1000;
00393         }
00394         url_fseek(s->pb, pos, SEEK_SET);
00395     }
00396 
00397     if(is_audio){
00398         if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) {
00399             st->codec->channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
00400             st->codec->sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);
00401             st->codec->bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
00402         }
00403         if(!st->codec->codec_id){
00404             flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK);
00405         }
00406     }else{
00407         size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK);
00408     }
00409 
00410     if (st->codec->codec_id == CODEC_ID_AAC ||
00411         st->codec->codec_id == CODEC_ID_H264) {
00412         int type = get_byte(s->pb);
00413         size--;
00414         if (st->codec->codec_id == CODEC_ID_H264) {
00415             int32_t cts = (get_be24(s->pb)+0xff800000)^0xff800000; // sign extension
00416             pts = dts + cts;
00417             if (cts < 0) { // dts are wrong
00418                 flv->wrong_dts = 1;
00419                 av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n");
00420             }
00421             if (flv->wrong_dts)
00422                 dts = AV_NOPTS_VALUE;
00423         }
00424         if (type == 0) {
00425             if ((ret = flv_get_extradata(s, st, size)) < 0)
00426                 return ret;
00427             if (st->codec->codec_id == CODEC_ID_AAC) {
00428                 MPEG4AudioConfig cfg;
00429                 ff_mpeg4audio_get_config(&cfg, st->codec->extradata,
00430                                          st->codec->extradata_size);
00431                 if (cfg.chan_config > 7)
00432                     return -1;
00433                 st->codec->channels = ff_mpeg4audio_channels[cfg.chan_config];
00434                 st->codec->sample_rate = cfg.sample_rate;
00435                 dprintf(s, "mp4a config channels %d sample rate %d\n",
00436                         st->codec->channels, st->codec->sample_rate);
00437             }
00438 
00439             goto retry;
00440         }
00441     }
00442 
00443     ret= av_get_packet(s->pb, pkt, size);
00444     if (ret <= 0) {
00445         return AVERROR(EIO);
00446     }
00447     /* note: we need to modify the packet size here to handle the last
00448        packet */
00449     pkt->size = ret;
00450     pkt->dts = dts;
00451     pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
00452     pkt->stream_index = st->index;
00453 
00454     if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY))
00455         pkt->flags |= PKT_FLAG_KEY;
00456 
00457     return ret;
00458 }
00459 
00460 AVInputFormat flv_demuxer = {
00461     "flv",
00462     NULL_IF_CONFIG_SMALL("FLV format"),
00463     sizeof(FLVContext),
00464     flv_probe,
00465     flv_read_header,
00466     flv_read_packet,
00467     .extensions = "flv",
00468     .value = CODEC_ID_FLV1,
00469 };

Generated on Sat Feb 16 2013 09:23:14 for ffmpeg by  doxygen 1.7.1