LCOV - code coverage report
Current view: top level - src/libavformat - ffmdec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 224 569 39.4 %
Date: 2017-06-22 08:51:55 Functions: 10 12 83.3 %

          Line data    Source code
       1             : /*
       2             :  * FFM (ffserver live feed) demuxer
       3             :  * Copyright (c) 2001 Fabrice Bellard
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * 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             :  * 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             :  * 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 <stdint.h>
      23             : 
      24             : #include "libavutil/imgutils.h"
      25             : #include "libavutil/internal.h"
      26             : #include "libavutil/intreadwrite.h"
      27             : #include "libavutil/intfloat.h"
      28             : #include "libavutil/opt.h"
      29             : #include "libavutil/avassert.h"
      30             : #include "libavutil/avstring.h"
      31             : #include "libavutil/pixdesc.h"
      32             : #include "libavcodec/internal.h"
      33             : #include "avformat.h"
      34             : #include "internal.h"
      35             : #include "ffm.h"
      36             : #include "avio_internal.h"
      37             : 
      38         312 : static int ffm_is_avail_data(AVFormatContext *s, int size)
      39             : {
      40         312 :     FFMContext *ffm = s->priv_data;
      41             :     int64_t pos, avail_size;
      42             :     ptrdiff_t len;
      43             : 
      44         312 :     len = ffm->packet_end - ffm->packet_ptr;
      45         312 :     if (size <= len)
      46         214 :         return 1;
      47          98 :     pos = avio_tell(s->pb);
      48          98 :     if (!ffm->write_index) {
      49          98 :         if (pos == ffm->file_size)
      50           4 :             return AVERROR_EOF;
      51          94 :         avail_size = ffm->file_size - pos;
      52             :     } else {
      53           0 :     if (pos == ffm->write_index) {
      54             :         /* exactly at the end of stream */
      55           0 :         if (ffm->server_attached)
      56           0 :             return AVERROR(EAGAIN);
      57             :         else
      58           0 :             return AVERROR_INVALIDDATA;
      59           0 :     } else if (pos < ffm->write_index) {
      60           0 :         avail_size = ffm->write_index - pos;
      61             :     } else {
      62           0 :         avail_size = (ffm->file_size - pos) + (ffm->write_index - FFM_PACKET_SIZE);
      63             :     }
      64             :     }
      65          94 :     avail_size = (avail_size / ffm->packet_size) * (ffm->packet_size - FFM_HEADER_SIZE) + len;
      66          94 :     if (size <= avail_size)
      67          94 :         return 1;
      68           0 :     else if (ffm->server_attached)
      69           0 :         return AVERROR(EAGAIN);
      70             :     else
      71           0 :         return AVERROR_INVALIDDATA;
      72             : }
      73             : 
      74           0 : static int ffm_resync(AVFormatContext *s, uint32_t state)
      75             : {
      76           0 :     av_log(s, AV_LOG_ERROR, "resyncing\n");
      77           0 :     while (state != PACKET_ID) {
      78           0 :         if (avio_feof(s->pb)) {
      79           0 :             av_log(s, AV_LOG_ERROR, "cannot find FFM syncword\n");
      80           0 :             return -1;
      81             :         }
      82           0 :         state = (state << 8) | avio_r8(s->pb);
      83             :     }
      84           0 :     return 0;
      85             : }
      86             : 
      87             : /* first is true if we read the frame header */
      88         367 : static int ffm_read_data(AVFormatContext *s,
      89             :                          uint8_t *buf, int size, int header)
      90             : {
      91         367 :     FFMContext *ffm = s->priv_data;
      92         367 :     AVIOContext *pb = s->pb;
      93             :     int fill_size, size1, frame_offset;
      94             :     uint32_t id;
      95             :     ptrdiff_t len;
      96         367 :     int64_t last_pos = -1;
      97             : 
      98         367 :     size1 = size;
      99        1333 :     while (size > 0) {
     100         599 :     redo:
     101         859 :         len = ffm->packet_end - ffm->packet_ptr;
     102         859 :         if (len < 0)
     103           0 :             return -1;
     104         859 :         if (len > size)
     105         365 :             len = size;
     106         859 :         if (len == 0) {
     107         260 :             if (avio_tell(pb) == ffm->file_size) {
     108           0 :                 if (ffm->server_attached) {
     109           0 :                     avio_seek(pb, ffm->packet_size, SEEK_SET);
     110             :                 } else
     111           0 :                     return AVERROR_EOF;
     112             :             }
     113         260 :     retry_read:
     114         262 :             if (pb->buffer_size != ffm->packet_size) {
     115           2 :                 int64_t tell = avio_tell(pb);
     116           2 :                 int ret = ffio_set_buf_size(pb, ffm->packet_size);
     117           2 :                 if (ret < 0)
     118           0 :                     return ret;
     119           2 :                 avio_seek(pb, tell, SEEK_SET);
     120             :             }
     121         262 :             id = avio_rb16(pb); /* PACKET_ID */
     122         262 :             if (id != PACKET_ID) {
     123           0 :                 if (ffm_resync(s, id) < 0)
     124           0 :                     return -1;
     125           0 :                 last_pos = avio_tell(pb);
     126             :             }
     127         262 :             fill_size = avio_rb16(pb);
     128         262 :             ffm->dts = avio_rb64(pb);
     129         262 :             frame_offset = avio_rb16(pb);
     130         262 :             avio_read(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE);
     131         262 :             if (ffm->packet_size < FFM_HEADER_SIZE + fill_size || frame_offset < 0) {
     132           0 :                 return -1;
     133             :             }
     134         262 :             ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size);
     135             :             /* if first packet or resynchronization packet, we must
     136             :                handle it specifically */
     137         262 :             if (ffm->first_packet || (frame_offset & 0x8000)) {
     138          30 :                 if (!frame_offset) {
     139             :                     /* This packet has no frame headers in it */
     140           2 :                     if (avio_tell(pb) >= ffm->packet_size * 3LL) {
     141           2 :                         int64_t seekback = FFMIN(ffm->packet_size * 2LL, avio_tell(pb) - last_pos);
     142           2 :                         seekback = FFMAX(seekback, 0);
     143           2 :                         avio_seek(pb, -seekback, SEEK_CUR);
     144           2 :                         goto retry_read;
     145             :                     }
     146             :                     /* This is bad, we cannot find a valid frame header */
     147           0 :                     return 0;
     148             :                 }
     149          28 :                 ffm->first_packet = 0;
     150          28 :                 if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE) {
     151           0 :                     ffm->packet_end = ffm->packet_ptr;
     152           0 :                     return -1;
     153             :                 }
     154          28 :                 ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE;
     155          56 :                 if (!header)
     156           0 :                     break;
     157             :             } else {
     158         232 :                 ffm->packet_ptr = ffm->packet;
     159             :             }
     160         260 :             goto redo;
     161             :         }
     162         599 :         memcpy(buf, ffm->packet_ptr, len);
     163         599 :         buf += len;
     164         599 :         ffm->packet_ptr += len;
     165         599 :         size -= len;
     166         599 :         header = 0;
     167             :     }
     168         367 :     return size1 - size;
     169             : }
     170             : 
     171             : /* ensure that actual seeking happens between FFM_PACKET_SIZE
     172             :    and file_size - FFM_PACKET_SIZE */
     173         147 : static int64_t ffm_seek1(AVFormatContext *s, int64_t pos1)
     174             : {
     175         147 :     FFMContext *ffm = s->priv_data;
     176         147 :     AVIOContext *pb = s->pb;
     177             :     int64_t pos;
     178             : 
     179         147 :     pos = FFMIN(pos1, ffm->file_size - FFM_PACKET_SIZE);
     180         147 :     pos = FFMAX(pos, FFM_PACKET_SIZE);
     181             :     ff_dlog(s, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos);
     182         147 :     return avio_seek(pb, pos, SEEK_SET);
     183             : }
     184             : 
     185         121 : static int64_t get_dts(AVFormatContext *s, int64_t pos)
     186             : {
     187         121 :     AVIOContext *pb = s->pb;
     188             :     int64_t dts;
     189             : 
     190         121 :     ffm_seek1(s, pos);
     191         121 :     avio_skip(pb, 4);
     192         121 :     dts = avio_rb64(pb);
     193             :     ff_dlog(s, "dts=%0.6f\n", dts / 1000000.0);
     194         121 :     return dts;
     195             : }
     196             : 
     197           0 : static void adjust_write_index(AVFormatContext *s)
     198             : {
     199           0 :     FFMContext *ffm = s->priv_data;
     200           0 :     AVIOContext *pb = s->pb;
     201             :     int64_t pts;
     202             :     //int64_t orig_write_index = ffm->write_index;
     203             :     int64_t pos_min, pos_max;
     204             :     int64_t pts_start;
     205           0 :     int64_t ptr = avio_tell(pb);
     206             : 
     207             : 
     208           0 :     pos_min = 0;
     209           0 :     pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE;
     210             : 
     211           0 :     pts_start = get_dts(s, pos_min);
     212             : 
     213           0 :     pts = get_dts(s, pos_max);
     214             : 
     215           0 :     if (pts - 100000 > pts_start)
     216           0 :         goto end;
     217             : 
     218           0 :     ffm->write_index = FFM_PACKET_SIZE;
     219             : 
     220           0 :     pts_start = get_dts(s, pos_min);
     221             : 
     222           0 :     pts = get_dts(s, pos_max);
     223             : 
     224           0 :     if (pts - 100000 <= pts_start) {
     225           0 :         while (1) {
     226             :             int64_t newpos;
     227             :             int64_t newpts;
     228             : 
     229           0 :             newpos = ((pos_max + pos_min) / (2 * FFM_PACKET_SIZE)) * FFM_PACKET_SIZE;
     230             : 
     231           0 :             if (newpos == pos_min)
     232           0 :                 break;
     233             : 
     234           0 :             newpts = get_dts(s, newpos);
     235             : 
     236           0 :             if (newpts - 100000 <= pts) {
     237           0 :                 pos_max = newpos;
     238           0 :                 pts = newpts;
     239             :             } else {
     240           0 :                 pos_min = newpos;
     241             :             }
     242             :         }
     243           0 :         ffm->write_index += pos_max;
     244             :     }
     245             : 
     246           0 :  end:
     247           0 :     avio_seek(pb, ptr, SEEK_SET);
     248           0 : }
     249             : 
     250             : 
     251           4 : static int ffm_append_recommended_configuration(AVStream *st, char **conf)
     252             : {
     253             :     int ret;
     254             :     size_t newsize;
     255           4 :     av_assert0(conf && st);
     256           4 :     if (!*conf)
     257           0 :         return 0;
     258           4 :     if (!st->recommended_encoder_configuration) {
     259           4 :         st->recommended_encoder_configuration = *conf;
     260           4 :         *conf = 0;
     261           4 :         return 0;
     262             :     }
     263           0 :     newsize = strlen(*conf) + strlen(st->recommended_encoder_configuration) + 2;
     264           0 :     if ((ret = av_reallocp(&st->recommended_encoder_configuration, newsize)) < 0)
     265           0 :         return ret;
     266           0 :     av_strlcat(st->recommended_encoder_configuration, ",", newsize);
     267           0 :     av_strlcat(st->recommended_encoder_configuration, *conf, newsize);
     268           0 :     av_freep(conf);
     269           0 :     return 0;
     270             : }
     271             : 
     272             : #define VALIDATE_PARAMETER(parameter, name, check) {                              \
     273             :     if (check) {                                                                  \
     274             :         av_log(s, AV_LOG_ERROR, "Invalid " name " %d\n", codecpar->parameter);   \
     275             :         ret = AVERROR_INVALIDDATA;                                                \
     276             :         goto fail;                                                                \
     277             :     }                                                                             \
     278             : }
     279             : 
     280           2 : static int ffm2_read_header(AVFormatContext *s)
     281             : {
     282           2 :     FFMContext *ffm = s->priv_data;
     283           2 :     AVStream *st = NULL;
     284           2 :     AVIOContext *pb = s->pb;
     285           2 :     AVCodecContext *dummy_codec = NULL;
     286           2 :     AVCodecParameters *codecpar = NULL;
     287             :     const AVCodecDescriptor *codec_desc;
     288             :     int ret;
     289           2 :     int f_main = 0, f_cprv = -1, f_stvi = -1, f_stau = -1;
     290             :     AVCodec *enc;
     291             :     char *buffer;
     292             : 
     293           2 :     ffm->packet_size = avio_rb32(pb);
     294           2 :     if (ffm->packet_size != FFM_PACKET_SIZE) {
     295           0 :         av_log(s, AV_LOG_ERROR, "Invalid packet size %d, expected size was %d\n",
     296             :                ffm->packet_size, FFM_PACKET_SIZE);
     297           0 :         ret = AVERROR_INVALIDDATA;
     298           0 :         goto fail;
     299             :     }
     300             : 
     301           2 :     ffm->write_index = avio_rb64(pb);
     302             :     /* get also filesize */
     303           2 :     if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
     304           2 :         ffm->file_size = avio_size(pb);
     305             :         if (ffm->write_index && 0)
     306             :             adjust_write_index(s);
     307             :     } else {
     308           0 :         ffm->file_size = (UINT64_C(1) << 63) - 1;
     309             :     }
     310           2 :     dummy_codec = avcodec_alloc_context3(NULL);
     311             : 
     312          14 :     while(!avio_feof(pb)) {
     313          12 :         unsigned id = avio_rb32(pb);
     314          12 :         unsigned size = avio_rb32(pb);
     315          12 :         int64_t next = avio_tell(pb) + size;
     316             :         char rc_eq_buf[128];
     317             :         int flags;
     318             : 
     319          12 :         if(!id)
     320           2 :             break;
     321             : 
     322          10 :         switch(id) {
     323           2 :         case MKBETAG('M', 'A', 'I', 'N'):
     324           2 :             if (f_main++) {
     325           0 :                 ret = AVERROR(EINVAL);
     326           0 :                 goto fail;
     327             :             }
     328           2 :             avio_rb32(pb); /* nb_streams */
     329           2 :             avio_rb32(pb); /* total bitrate */
     330           2 :             break;
     331           4 :         case MKBETAG('C', 'O', 'M', 'M'):
     332           4 :             f_cprv = f_stvi = f_stau = 0;
     333           4 :             st = avformat_new_stream(s, NULL);
     334           4 :             if (!st) {
     335           0 :                 ret = AVERROR(ENOMEM);
     336           0 :                 goto fail;
     337             :             }
     338             : 
     339           4 :             avpriv_set_pts_info(st, 64, 1, 1000000);
     340             : 
     341           4 :             codecpar = st->codecpar;
     342             :             /* generic info */
     343           4 :             codecpar->codec_id = avio_rb32(pb);
     344           4 :             codec_desc = avcodec_descriptor_get(codecpar->codec_id);
     345           4 :             if (!codec_desc) {
     346           0 :                 av_log(s, AV_LOG_ERROR, "Invalid codec id: %d\n", codecpar->codec_id);
     347           0 :                 codecpar->codec_id = AV_CODEC_ID_NONE;
     348           0 :                 ret = AVERROR_INVALIDDATA;
     349           0 :                 goto fail;
     350             :             }
     351           4 :             codecpar->codec_type = avio_r8(pb);
     352           4 :             if (codecpar->codec_type != codec_desc->type) {
     353           0 :                 av_log(s, AV_LOG_ERROR, "Codec type mismatch: expected %d, found %d\n",
     354           0 :                        codec_desc->type, codecpar->codec_type);
     355           0 :                 codecpar->codec_id = AV_CODEC_ID_NONE;
     356           0 :                 codecpar->codec_type = AVMEDIA_TYPE_UNKNOWN;
     357           0 :                 ret = AVERROR_INVALIDDATA;
     358           0 :                 goto fail;
     359             :             }
     360           4 :             codecpar->bit_rate = avio_rb32(pb);
     361           4 :             if (codecpar->bit_rate < 0) {
     362           0 :                 av_log(s, AV_LOG_ERROR, "Invalid bit rate %"PRId64"\n", codecpar->bit_rate);
     363           0 :                 ret = AVERROR_INVALIDDATA;
     364           0 :                 goto fail;
     365             :             }
     366           4 :             flags = avio_rb32(pb);
     367             : #if FF_API_LAVF_AVCTX
     368             : FF_DISABLE_DEPRECATION_WARNINGS
     369           4 :             st->codec->flags = flags;
     370             : FF_ENABLE_DEPRECATION_WARNINGS
     371             : #endif
     372           4 :             avio_rb32(pb); // flags2
     373           4 :             avio_rb32(pb); // debug
     374           4 :             if (flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
     375           0 :                 int size = avio_rb32(pb);
     376           0 :                 if (size < 0 || size >= FF_MAX_EXTRADATA_SIZE) {
     377           0 :                     av_log(s, AV_LOG_ERROR, "Invalid extradata size %d\n", size);
     378           0 :                     ret = AVERROR_INVALIDDATA;
     379           0 :                     goto fail;
     380             :                 }
     381           0 :                 codecpar->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
     382           0 :                 if (!codecpar->extradata) {
     383           0 :                     ret = AVERROR(ENOMEM);
     384           0 :                     goto fail;
     385             :                 }
     386           0 :                 codecpar->extradata_size = size;
     387           0 :                 avio_read(pb, codecpar->extradata, size);
     388             :             }
     389           4 :             break;
     390           0 :         case MKBETAG('S', 'T', 'V', 'I'):
     391           0 :             if (f_stvi++ || codecpar->codec_type != AVMEDIA_TYPE_VIDEO) {
     392           0 :                 ret = AVERROR(EINVAL);
     393           0 :                 goto fail;
     394             :             }
     395           0 :             avio_rb32(pb); // time_base.num
     396           0 :             avio_rb32(pb); // time_base.den
     397           0 :             codecpar->width = avio_rb16(pb);
     398           0 :             codecpar->height = avio_rb16(pb);
     399           0 :             ret = av_image_check_size(codecpar->width, codecpar->height, 0, s);
     400           0 :             if (ret < 0)
     401           0 :                 goto fail;
     402           0 :             avio_rb16(pb); // gop_size
     403           0 :             codecpar->format = avio_rb32(pb);
     404           0 :             if (!av_pix_fmt_desc_get(codecpar->format)) {
     405           0 :                 av_log(s, AV_LOG_ERROR, "Invalid pix fmt id: %d\n", codecpar->format);
     406           0 :                 codecpar->format = AV_PIX_FMT_NONE;
     407           0 :                 ret = AVERROR_INVALIDDATA;
     408           0 :                 goto fail;
     409             :             }
     410           0 :             avio_r8(pb);   // qmin
     411           0 :             avio_r8(pb);   // qmax
     412           0 :             avio_r8(pb);   // max_qdiff
     413           0 :             avio_rb16(pb); // qcompress / 10000.0
     414           0 :             avio_rb16(pb); // qblur / 10000.0
     415           0 :             avio_rb32(pb); // bit_rate_tolerance
     416           0 :             avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf));
     417             : 
     418           0 :             avio_rb32(pb); // rc_max_rate
     419           0 :             avio_rb32(pb); // rc_min_rate
     420           0 :             avio_rb32(pb); // rc_buffer_size
     421           0 :             avio_rb64(pb); // i_quant_factor
     422           0 :             avio_rb64(pb); // b_quant_factor
     423           0 :             avio_rb64(pb); // i_quant_offset
     424           0 :             avio_rb64(pb); // b_quant_offset
     425           0 :             avio_rb32(pb); // dct_algo
     426           0 :             avio_rb32(pb); // strict_std_compliance
     427           0 :             avio_rb32(pb); // max_b_frames
     428           0 :             avio_rb32(pb); // mpeg_quant
     429           0 :             avio_rb32(pb); // intra_dc_precision
     430           0 :             avio_rb32(pb); // me_method
     431           0 :             avio_rb32(pb); // mb_decision
     432           0 :             avio_rb32(pb); // nsse_weight
     433           0 :             avio_rb32(pb); // frame_skip_cmp
     434           0 :             avio_rb64(pb); // rc_buffer_aggressivity
     435           0 :             codecpar->codec_tag = avio_rb32(pb);
     436           0 :             avio_r8(pb);   // thread_count
     437           0 :             avio_rb32(pb); // coder_type
     438           0 :             avio_rb32(pb); // me_cmp
     439           0 :             avio_rb32(pb); // me_subpel_quality
     440           0 :             avio_rb32(pb); // me_range
     441           0 :             avio_rb32(pb); // keyint_min
     442           0 :             avio_rb32(pb); // scenechange_threshold
     443           0 :             avio_rb32(pb); // b_frame_strategy
     444           0 :             avio_rb64(pb); // qcompress
     445           0 :             avio_rb64(pb); // qblur
     446           0 :             avio_rb32(pb); // max_qdiff
     447           0 :             avio_rb32(pb); // refs
     448           0 :             break;
     449           0 :         case MKBETAG('S', 'T', 'A', 'U'):
     450           0 :             if (f_stau++ || codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
     451           0 :                 ret = AVERROR(EINVAL);
     452           0 :                 goto fail;
     453             :             }
     454           0 :             codecpar->sample_rate = avio_rb32(pb);
     455           0 :             VALIDATE_PARAMETER(sample_rate, "sample rate",        codecpar->sample_rate < 0)
     456           0 :             codecpar->channels = avio_rl16(pb);
     457           0 :             VALIDATE_PARAMETER(channels,    "number of channels", codecpar->channels < 0)
     458           0 :             codecpar->frame_size = avio_rl16(pb);
     459           0 :             VALIDATE_PARAMETER(frame_size,  "frame size",         codecpar->frame_size < 0)
     460           0 :             break;
     461           0 :         case MKBETAG('C', 'P', 'R', 'V'):
     462           0 :             if (f_cprv++) {
     463           0 :                 ret = AVERROR(EINVAL);
     464           0 :                 goto fail;
     465             :             }
     466           0 :             enc = avcodec_find_encoder(codecpar->codec_id);
     467           0 :             if (enc && enc->priv_data_size && enc->priv_class) {
     468           0 :                 buffer = av_malloc(size + 1);
     469           0 :                 if (!buffer) {
     470           0 :                     ret = AVERROR(ENOMEM);
     471           0 :                     goto fail;
     472             :                 }
     473           0 :                 avio_get_str(pb, size, buffer, size + 1);
     474           0 :                 if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)
     475           0 :                     goto fail;
     476             :             }
     477           0 :             break;
     478           2 :         case MKBETAG('S', '2', 'V', 'I'):
     479           2 :             if (f_stvi++ || !size || codecpar->codec_type != AVMEDIA_TYPE_VIDEO) {
     480           0 :                 ret = AVERROR(EINVAL);
     481           0 :                 goto fail;
     482             :             }
     483           2 :             buffer = av_malloc(size);
     484           2 :             if (!buffer) {
     485           0 :                 ret = AVERROR(ENOMEM);
     486           0 :                 goto fail;
     487             :             }
     488           2 :             avio_get_str(pb, INT_MAX, buffer, size);
     489             :             // The lack of AVOptions support in AVCodecParameters makes this back and forth copying needed
     490           2 :             avcodec_parameters_to_context(dummy_codec, codecpar);
     491           2 :             av_set_options_string(dummy_codec, buffer, "=", ",");
     492           2 :             avcodec_parameters_from_context(codecpar, dummy_codec);
     493           2 :             if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)
     494           0 :                 goto fail;
     495           2 :             break;
     496           2 :         case MKBETAG('S', '2', 'A', 'U'):
     497           2 :             if (f_stau++ || !size || codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
     498           0 :                 ret = AVERROR(EINVAL);
     499           0 :                 goto fail;
     500             :             }
     501           2 :             buffer = av_malloc(size);
     502           2 :             if (!buffer) {
     503           0 :                 ret = AVERROR(ENOMEM);
     504           0 :                 goto fail;
     505             :             }
     506           2 :             avio_get_str(pb, INT_MAX, buffer, size);
     507             :             // The lack of AVOptions support in AVCodecParameters makes this back and forth copying needed
     508           2 :             avcodec_parameters_to_context(dummy_codec, codecpar);
     509           2 :             av_set_options_string(dummy_codec, buffer, "=", ",");
     510           2 :             avcodec_parameters_from_context(codecpar, dummy_codec);
     511           2 :             if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)
     512           0 :                 goto fail;
     513           2 :             break;
     514             :         }
     515          10 :         avio_seek(pb, next, SEEK_SET);
     516             :     }
     517             : 
     518             :     /* get until end of block reached */
     519        7602 :     while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached)
     520        7598 :         avio_r8(pb);
     521             : 
     522             :     /* init packet demux */
     523           2 :     ffm->packet_ptr = ffm->packet;
     524           2 :     ffm->packet_end = ffm->packet;
     525           2 :     ffm->frame_offset = 0;
     526           2 :     ffm->dts = 0;
     527           2 :     ffm->read_state = READ_HEADER;
     528           2 :     ffm->first_packet = 1;
     529           2 :     avcodec_free_context(&dummy_codec);
     530           2 :     return 0;
     531           0 :  fail:
     532           0 :     avcodec_free_context(&dummy_codec);
     533           0 :     return ret;
     534             : }
     535             : 
     536           2 : static int ffm_read_header(AVFormatContext *s)
     537             : {
     538           2 :     FFMContext *ffm = s->priv_data;
     539             :     AVStream *st;
     540           2 :     AVIOContext *pb = s->pb;
     541           2 :     AVCodecContext *dummy_codec = NULL;
     542             :     AVCodecParameters *codecpar;
     543             :     const AVCodecDescriptor *codec_desc;
     544             :     int i, nb_streams, ret;
     545             :     uint32_t tag;
     546             : 
     547             :     /* header */
     548           2 :     tag = avio_rl32(pb);
     549           2 :     if (tag == MKTAG('F', 'F', 'M', '2'))
     550           2 :         return ffm2_read_header(s);
     551           0 :     if (tag != MKTAG('F', 'F', 'M', '1')) {
     552           0 :         ret = AVERROR_INVALIDDATA;
     553           0 :         goto fail;
     554             :     }
     555           0 :     ffm->packet_size = avio_rb32(pb);
     556           0 :     if (ffm->packet_size != FFM_PACKET_SIZE) {
     557           0 :         ret = AVERROR_INVALIDDATA;
     558           0 :         goto fail;
     559             :     }
     560           0 :     ffm->write_index = avio_rb64(pb);
     561             :     /* get also filesize */
     562           0 :     if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
     563           0 :         ffm->file_size = avio_size(pb);
     564             :         if (ffm->write_index && 0)
     565             :             adjust_write_index(s);
     566             :     } else {
     567           0 :         ffm->file_size = (UINT64_C(1) << 63) - 1;
     568             :     }
     569           0 :     dummy_codec = avcodec_alloc_context3(NULL);
     570             : 
     571           0 :     nb_streams = avio_rb32(pb);
     572           0 :     avio_rb32(pb); /* total bitrate */
     573             :     /* read each stream */
     574           0 :     for(i=0;i<nb_streams;i++) {
     575             :         char rc_eq_buf[128];
     576             :         int flags;
     577             : 
     578           0 :         st = avformat_new_stream(s, NULL);
     579           0 :         if (!st) {
     580           0 :             ret = AVERROR(ENOMEM);
     581           0 :             goto fail;
     582             :         }
     583             : 
     584           0 :         avpriv_set_pts_info(st, 64, 1, 1000000);
     585             : 
     586           0 :         codecpar = st->codecpar;
     587             :         /* generic info */
     588           0 :         codecpar->codec_id = avio_rb32(pb);
     589           0 :         codec_desc = avcodec_descriptor_get(codecpar->codec_id);
     590           0 :         if (!codec_desc) {
     591           0 :             av_log(s, AV_LOG_ERROR, "Invalid codec id: %d\n", codecpar->codec_id);
     592           0 :             codecpar->codec_id = AV_CODEC_ID_NONE;
     593           0 :             ret = AVERROR_INVALIDDATA;
     594           0 :             goto fail;
     595             :         }
     596           0 :         codecpar->codec_type = avio_r8(pb); /* codec_type */
     597           0 :         if (codecpar->codec_type != codec_desc->type) {
     598           0 :             av_log(s, AV_LOG_ERROR, "Codec type mismatch: expected %d, found %d\n",
     599           0 :                    codec_desc->type, codecpar->codec_type);
     600           0 :             codecpar->codec_id = AV_CODEC_ID_NONE;
     601           0 :             codecpar->codec_type = AVMEDIA_TYPE_UNKNOWN;
     602           0 :             ret = AVERROR_INVALIDDATA;
     603           0 :             goto fail;
     604             :         }
     605           0 :         codecpar->bit_rate = avio_rb32(pb);
     606           0 :         if (codecpar->bit_rate < 0) {
     607           0 :             av_log(s, AV_LOG_WARNING, "Invalid bit rate %"PRId64"\n", codecpar->bit_rate);
     608           0 :             ret = AVERROR_INVALIDDATA;
     609           0 :             goto fail;
     610             :         }
     611           0 :         flags = avio_rb32(pb);
     612             : #if FF_API_LAVF_AVCTX
     613             : FF_DISABLE_DEPRECATION_WARNINGS
     614           0 :             st->codec->flags = flags;
     615             : FF_ENABLE_DEPRECATION_WARNINGS
     616             : #endif
     617           0 :         avio_rb32(pb); // flags2
     618           0 :         avio_rb32(pb); // debug
     619             :         /* specific info */
     620           0 :         switch(codecpar->codec_type) {
     621           0 :         case AVMEDIA_TYPE_VIDEO:
     622           0 :             avio_rb32(pb); // time_base.num
     623           0 :             avio_rb32(pb); // time_base.den
     624           0 :             codecpar->width = avio_rb16(pb);
     625           0 :             codecpar->height = avio_rb16(pb);
     626           0 :             if ((ret = av_image_check_size(codecpar->width, codecpar->height, 0, s)) < 0)
     627           0 :                 goto fail;
     628           0 :             avio_rb16(pb); // gop_size
     629           0 :             codecpar->format = avio_rb32(pb);
     630           0 :             if (!av_pix_fmt_desc_get(codecpar->format)) {
     631           0 :                 av_log(s, AV_LOG_ERROR, "Invalid pix fmt id: %d\n", codecpar->format);
     632           0 :                 codecpar->format = AV_PIX_FMT_NONE;
     633           0 :                 ret = AVERROR_INVALIDDATA;
     634           0 :                 goto fail;
     635             :             }
     636           0 :             avio_r8(pb);   // qmin
     637           0 :             avio_r8(pb);   // qmax
     638           0 :             avio_r8(pb);   // max_qdiff
     639           0 :             avio_rb16(pb); // qcompress / 10000.0
     640           0 :             avio_rb16(pb); // qblur / 10000.0
     641           0 :             avio_rb32(pb); // bit_rate_tolerance
     642           0 :             avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf));
     643             : 
     644           0 :             avio_rb32(pb); // rc_max_rate
     645           0 :             avio_rb32(pb); // rc_min_rate
     646           0 :             avio_rb32(pb); // rc_buffer_size
     647           0 :             avio_rb64(pb); // i_quant_factor
     648           0 :             avio_rb64(pb); // b_quant_factor
     649           0 :             avio_rb64(pb); // i_quant_offset
     650           0 :             avio_rb64(pb); // b_quant_offset
     651           0 :             avio_rb32(pb); // dct_algo
     652           0 :             avio_rb32(pb); // strict_std_compliance
     653           0 :             avio_rb32(pb); // max_b_frames
     654           0 :             avio_rb32(pb); // mpeg_quant
     655           0 :             avio_rb32(pb); // intra_dc_precision
     656           0 :             avio_rb32(pb); // me_method
     657           0 :             avio_rb32(pb); // mb_decision
     658           0 :             avio_rb32(pb); // nsse_weight
     659           0 :             avio_rb32(pb); // frame_skip_cmp
     660           0 :             avio_rb64(pb); // rc_buffer_aggressivity
     661           0 :             codecpar->codec_tag = avio_rb32(pb);
     662           0 :             avio_r8(pb);   // thread_count
     663           0 :             avio_rb32(pb); // coder_type
     664           0 :             avio_rb32(pb); // me_cmp
     665           0 :             avio_rb32(pb); // me_subpel_quality
     666           0 :             avio_rb32(pb); // me_range
     667           0 :             avio_rb32(pb); // keyint_min
     668           0 :             avio_rb32(pb); // scenechange_threshold
     669           0 :             avio_rb32(pb); // b_frame_strategy
     670           0 :             avio_rb64(pb); // qcompress
     671           0 :             avio_rb64(pb); // qblur
     672           0 :             avio_rb32(pb); // max_qdiff
     673           0 :             avio_rb32(pb); // refs
     674           0 :             break;
     675           0 :         case AVMEDIA_TYPE_AUDIO:
     676           0 :             codecpar->sample_rate = avio_rb32(pb);
     677           0 :             VALIDATE_PARAMETER(sample_rate, "sample rate",        codecpar->sample_rate < 0)
     678           0 :             codecpar->channels = avio_rl16(pb);
     679           0 :             VALIDATE_PARAMETER(channels,    "number of channels", codecpar->channels < 0)
     680           0 :             codecpar->frame_size = avio_rl16(pb);
     681           0 :             VALIDATE_PARAMETER(frame_size,  "frame size",         codecpar->frame_size < 0)
     682           0 :             break;
     683           0 :         default:
     684           0 :             ret = AVERROR_INVALIDDATA;
     685           0 :             goto fail;
     686             :         }
     687           0 :         if (flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
     688           0 :             int size = avio_rb32(pb);
     689           0 :             if (size < 0 || size >= FF_MAX_EXTRADATA_SIZE) {
     690           0 :                 av_log(s, AV_LOG_ERROR, "Invalid extradata size %d\n", size);
     691           0 :                 ret = AVERROR_INVALIDDATA;
     692           0 :                 goto fail;
     693             :             }
     694           0 :             codecpar->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
     695           0 :             if (!codecpar->extradata) {
     696           0 :                 ret = AVERROR(ENOMEM);
     697           0 :                 goto fail;
     698             :             }
     699           0 :             codecpar->extradata_size = size;
     700           0 :             avio_read(pb, codecpar->extradata, size);
     701             :         }
     702             :     }
     703             : 
     704             :     /* get until end of block reached */
     705           0 :     while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached)
     706           0 :         avio_r8(pb);
     707             : 
     708             :     /* init packet demux */
     709           0 :     ffm->packet_ptr = ffm->packet;
     710           0 :     ffm->packet_end = ffm->packet;
     711           0 :     ffm->frame_offset = 0;
     712           0 :     ffm->dts = 0;
     713           0 :     ffm->read_state = READ_HEADER;
     714           0 :     ffm->first_packet = 1;
     715           0 :     avcodec_free_context(&dummy_codec);
     716           0 :     return 0;
     717           0 :  fail:
     718           0 :     avcodec_free_context(&dummy_codec);
     719           0 :     return ret;
     720             : }
     721             : 
     722             : /* return < 0 if eof */
     723         158 : static int ffm_read_packet(AVFormatContext *s, AVPacket *pkt)
     724             : {
     725             :     int size;
     726         158 :     FFMContext *ffm = s->priv_data;
     727             :     int duration, ret;
     728             : 
     729         158 :     switch(ffm->read_state) {
     730         158 :     case READ_HEADER:
     731         158 :         if ((ret = ffm_is_avail_data(s, FRAME_HEADER_SIZE+4)) < 0)
     732           4 :             return ret;
     733             : 
     734             :         ff_dlog(s, "pos=%08"PRIx64" spos=%"PRIx64", write_index=%"PRIx64" size=%"PRIx64"\n",
     735             :                avio_tell(s->pb), s->pb->pos, ffm->write_index, ffm->file_size);
     736         154 :         if (ffm_read_data(s, ffm->header, FRAME_HEADER_SIZE, 1) !=
     737             :             FRAME_HEADER_SIZE)
     738           0 :             return -1;
     739         154 :         if (ffm->header[1] & FLAG_DTS)
     740          59 :             if (ffm_read_data(s, ffm->header+16, 4, 1) != 4)
     741           0 :                 return -1;
     742         154 :         ffm->read_state = READ_DATA;
     743             :         /* fall through */
     744         154 :     case READ_DATA:
     745         154 :         size = AV_RB24(ffm->header + 2);
     746         154 :         if ((ret = ffm_is_avail_data(s, size)) < 0)
     747           0 :             return ret;
     748             : 
     749         154 :         duration = AV_RB24(ffm->header + 5);
     750             : 
     751         154 :         if (av_new_packet(pkt, size) < 0) {
     752           0 :             return AVERROR(ENOMEM);
     753             :         }
     754         154 :         pkt->stream_index = ffm->header[0];
     755         154 :         if ((unsigned)pkt->stream_index >= s->nb_streams) {
     756           0 :             av_log(s, AV_LOG_ERROR, "invalid stream index %d\n", pkt->stream_index);
     757           0 :             av_packet_unref(pkt);
     758           0 :             ffm->read_state = READ_HEADER;
     759           0 :             return -1;
     760             :         }
     761         154 :         pkt->pos = avio_tell(s->pb);
     762         154 :         if (ffm->header[1] & FLAG_KEY_FRAME)
     763         109 :             pkt->flags |= AV_PKT_FLAG_KEY;
     764             : 
     765         154 :         ffm->read_state = READ_HEADER;
     766         154 :         if (ffm_read_data(s, pkt->data, size, 0) != size) {
     767             :             /* bad case: desynchronized packet. we cancel all the packet loading */
     768           0 :             av_packet_unref(pkt);
     769           0 :             return -1;
     770             :         }
     771         154 :         pkt->pts = AV_RB64(ffm->header+8);
     772         154 :         if (ffm->header[1] & FLAG_DTS)
     773          59 :             pkt->dts = pkt->pts - AV_RB32(ffm->header+16);
     774             :         else
     775          95 :             pkt->dts = pkt->pts;
     776         154 :         pkt->duration = duration;
     777         154 :         break;
     778             :     }
     779         154 :     return 0;
     780             : }
     781             : 
     782             : /* seek to a given time in the file. The file read pointer is
     783             :    positioned at or before pts. XXX: the following code is quite
     784             :    approximative */
     785          26 : static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, int flags)
     786             : {
     787          26 :     FFMContext *ffm = s->priv_data;
     788             :     int64_t pos_min, pos_max, pos;
     789             :     int64_t pts_min, pts_max, pts;
     790             :     double pos1;
     791             : 
     792             :     ff_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
     793             :     /* find the position using linear interpolation (better than
     794             :        dichotomy in typical cases) */
     795          26 :     if (ffm->write_index && ffm->write_index < ffm->file_size) {
     796           0 :         if (get_dts(s, FFM_PACKET_SIZE) < wanted_pts) {
     797           0 :             pos_min = FFM_PACKET_SIZE;
     798           0 :             pos_max = ffm->write_index - FFM_PACKET_SIZE;
     799             :         } else {
     800           0 :             pos_min = ffm->write_index;
     801           0 :             pos_max = ffm->file_size - FFM_PACKET_SIZE;
     802             :         }
     803             :     } else {
     804          26 :         pos_min = FFM_PACKET_SIZE;
     805          26 :         pos_max = ffm->file_size - FFM_PACKET_SIZE;
     806             :     }
     807          75 :     while (pos_min <= pos_max) {
     808          49 :         pts_min = get_dts(s, pos_min);
     809          49 :         pts_max = get_dts(s, pos_max);
     810          49 :         if (pts_min > wanted_pts || pts_max <= wanted_pts) {
     811          26 :             pos = pts_min > wanted_pts ? pos_min : pos_max;
     812          26 :             goto found;
     813             :         }
     814             :         /* linear interpolation */
     815          46 :         pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) /
     816          23 :             (double)(pts_max - pts_min);
     817          23 :         pos = (((int64_t)pos1) / FFM_PACKET_SIZE) * FFM_PACKET_SIZE;
     818          23 :         if (pos <= pos_min)
     819          17 :             pos = pos_min;
     820           6 :         else if (pos >= pos_max)
     821           0 :             pos = pos_max;
     822          23 :         pts = get_dts(s, pos);
     823             :         /* check if we are lucky */
     824          23 :         if (pts == wanted_pts) {
     825           0 :             goto found;
     826          23 :         } else if (pts > wanted_pts) {
     827           1 :             pos_max = pos - FFM_PACKET_SIZE;
     828             :         } else {
     829          22 :             pos_min = pos + FFM_PACKET_SIZE;
     830             :         }
     831             :     }
     832           0 :     pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;
     833             : 
     834          26 :  found:
     835          26 :     if (ffm_seek1(s, pos) < 0)
     836           0 :         return -1;
     837             : 
     838             :     /* reset read state */
     839          26 :     ffm->read_state = READ_HEADER;
     840          26 :     ffm->packet_ptr = ffm->packet;
     841          26 :     ffm->packet_end = ffm->packet;
     842          26 :     ffm->first_packet = 1;
     843             : 
     844          26 :     return 0;
     845             : }
     846             : 
     847        5965 : static int ffm_probe(AVProbeData *p)
     848             : {
     849        5965 :     if (
     850        6015 :         p->buf[0] == 'F' && p->buf[1] == 'F' && p->buf[2] == 'M' &&
     851           4 :         (p->buf[3] == '1' || p->buf[3] == '2'))
     852           2 :         return AVPROBE_SCORE_MAX + 1;
     853        5963 :     return 0;
     854             : }
     855             : 
     856             : static const AVOption options[] = {
     857             :     {"server_attached", NULL, offsetof(FFMContext, server_attached), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_EXPORT },
     858             :     {"ffm_write_index", NULL, offsetof(FFMContext, write_index), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_EXPORT },
     859             :     {"ffm_file_size", NULL, offsetof(FFMContext, file_size), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_EXPORT },
     860             :     { NULL },
     861             : };
     862             : 
     863             : static const AVClass ffm_class = {
     864             :     .class_name = "ffm demuxer",
     865             :     .item_name  = av_default_item_name,
     866             :     .option     = options,
     867             :     .version    = LIBAVUTIL_VERSION_INT,
     868             : };
     869             : AVInputFormat ff_ffm_demuxer = {
     870             :     .name           = "ffm",
     871             :     .long_name      = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed)"),
     872             :     .priv_data_size = sizeof(FFMContext),
     873             :     .read_probe     = ffm_probe,
     874             :     .read_header    = ffm_read_header,
     875             :     .read_packet    = ffm_read_packet,
     876             :     .read_seek      = ffm_seek,
     877             :     .priv_class     = &ffm_class,
     878             : };

Generated by: LCOV version 1.13