LCOV - code coverage report
Current view: top level - libavformat - oggparsespeex.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 68 0.0 %
Date: 2017-12-10 21:22:29 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /*
       2             :       Copyright (C) 2008  Reimar Döffinger
       3             : 
       4             :       Permission is hereby granted, free of charge, to any person
       5             :       obtaining a copy of this software and associated documentation
       6             :       files (the "Software"), to deal in the Software without
       7             :       restriction, including without limitation the rights to use, copy,
       8             :       modify, merge, publish, distribute, sublicense, and/or sell copies
       9             :       of the Software, and to permit persons to whom the Software is
      10             :       furnished to do so, subject to the following conditions:
      11             : 
      12             :       The above copyright notice and this permission notice shall be
      13             :       included in all copies or substantial portions of the Software.
      14             : 
      15             :       THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      16             :       EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      17             :       MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      18             :       NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      19             :       HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
      20             :       WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      21             :       OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      22             :       DEALINGS IN THE SOFTWARE.
      23             : **/
      24             : 
      25             : #include <stdlib.h>
      26             : 
      27             : #include "libavutil/bswap.h"
      28             : #include "libavutil/avstring.h"
      29             : #include "libavutil/channel_layout.h"
      30             : 
      31             : #include "libavcodec/bytestream.h"
      32             : 
      33             : #include "avformat.h"
      34             : #include "internal.h"
      35             : #include "oggdec.h"
      36             : 
      37             : struct speex_params {
      38             :     int packet_size;
      39             :     int final_packet_duration;
      40             :     int seq;
      41             : };
      42             : 
      43           0 : static int speex_header(AVFormatContext *s, int idx) {
      44           0 :     struct ogg *ogg = s->priv_data;
      45           0 :     struct ogg_stream *os = ogg->streams + idx;
      46           0 :     struct speex_params *spxp = os->private;
      47           0 :     AVStream *st = s->streams[idx];
      48           0 :     uint8_t *p = os->buf + os->pstart;
      49             : 
      50           0 :     if (!spxp) {
      51           0 :         spxp = av_mallocz(sizeof(*spxp));
      52           0 :         if (!spxp)
      53           0 :             return AVERROR(ENOMEM);
      54           0 :         os->private = spxp;
      55             :     }
      56             : 
      57           0 :     if (spxp->seq > 1)
      58           0 :         return 0;
      59             : 
      60           0 :     if (spxp->seq == 0) {
      61             :         int frames_per_packet;
      62           0 :         st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
      63           0 :         st->codecpar->codec_id = AV_CODEC_ID_SPEEX;
      64             : 
      65           0 :         if (os->psize < 68) {
      66           0 :             av_log(s, AV_LOG_ERROR, "speex packet too small\n");
      67           0 :             return AVERROR_INVALIDDATA;
      68             :         }
      69             : 
      70           0 :         st->codecpar->sample_rate = AV_RL32(p + 36);
      71           0 :         if (st->codecpar->sample_rate <= 0) {
      72           0 :             av_log(s, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
      73           0 :             return AVERROR_INVALIDDATA;
      74             :         }
      75           0 :         st->codecpar->channels = AV_RL32(p + 48);
      76           0 :         if (st->codecpar->channels < 1 || st->codecpar->channels > 2) {
      77           0 :             av_log(s, AV_LOG_ERROR, "invalid channel count. Speex must be mono or stereo.\n");
      78           0 :             return AVERROR_INVALIDDATA;
      79             :         }
      80           0 :         st->codecpar->channel_layout = st->codecpar->channels == 1 ? AV_CH_LAYOUT_MONO :
      81             :                                                                      AV_CH_LAYOUT_STEREO;
      82             : 
      83           0 :         spxp->packet_size  = AV_RL32(p + 56);
      84           0 :         frames_per_packet  = AV_RL32(p + 64);
      85           0 :         if (spxp->packet_size < 0 ||
      86           0 :             frames_per_packet < 0 ||
      87           0 :             spxp->packet_size * (int64_t)frames_per_packet > INT32_MAX / 256) {
      88           0 :             av_log(s, AV_LOG_ERROR, "invalid packet_size, frames_per_packet %d %d\n", spxp->packet_size, frames_per_packet);
      89           0 :             spxp->packet_size = 0;
      90           0 :             return AVERROR_INVALIDDATA;
      91             :         }
      92           0 :         if (frames_per_packet)
      93           0 :             spxp->packet_size *= frames_per_packet;
      94             : 
      95           0 :         if (ff_alloc_extradata(st->codecpar, os->psize) < 0)
      96           0 :             return AVERROR(ENOMEM);
      97           0 :         memcpy(st->codecpar->extradata, p, st->codecpar->extradata_size);
      98             : 
      99           0 :         avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
     100             :     } else
     101           0 :         ff_vorbis_stream_comment(s, st, p, os->psize);
     102             : 
     103           0 :     spxp->seq++;
     104           0 :     return 1;
     105             : }
     106             : 
     107           0 : static int ogg_page_packets(struct ogg_stream *os)
     108             : {
     109             :     int i;
     110           0 :     int packets = 0;
     111           0 :     for (i = 0; i < os->nsegs; i++)
     112           0 :         if (os->segments[i] < 255)
     113           0 :             packets++;
     114           0 :     return packets;
     115             : }
     116             : 
     117           0 : static int speex_packet(AVFormatContext *s, int idx)
     118             : {
     119           0 :     struct ogg *ogg = s->priv_data;
     120           0 :     struct ogg_stream *os = ogg->streams + idx;
     121           0 :     struct speex_params *spxp = os->private;
     122           0 :     int packet_size = spxp->packet_size;
     123             : 
     124           0 :     if (os->flags & OGG_FLAG_EOS && os->lastpts != AV_NOPTS_VALUE &&
     125           0 :         os->granule > 0) {
     126             :         /* first packet of final page. we have to calculate the final packet
     127             :            duration here because it is the only place we know the next-to-last
     128             :            granule position. */
     129           0 :         spxp->final_packet_duration = os->granule - os->lastpts -
     130           0 :                                       packet_size * (ogg_page_packets(os) - 1);
     131             :     }
     132             : 
     133           0 :     if (!os->lastpts && os->granule > 0)
     134             :         /* first packet */
     135           0 :         os->lastpts = os->lastdts = os->granule - packet_size *
     136           0 :                                     ogg_page_packets(os);
     137           0 :     if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs &&
     138           0 :         spxp->final_packet_duration)
     139             :         /* final packet */
     140           0 :         os->pduration = spxp->final_packet_duration;
     141             :     else
     142           0 :         os->pduration = packet_size;
     143             : 
     144           0 :     return 0;
     145             : }
     146             : 
     147             : const struct ogg_codec ff_speex_codec = {
     148             :     .magic = "Speex   ",
     149             :     .magicsize = 8,
     150             :     .header = speex_header,
     151             :     .packet = speex_packet,
     152             :     .nb_header = 2,
     153             : };

Generated by: LCOV version 1.13