LCOV - code coverage report
Current view: top level - src/libavformat - bmv.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 55 66 83.3 %
Date: 2017-04-23 07:57:23 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Discworld II BMV demuxer
       3             :  * Copyright (c) 2011 Konstantin Shishkov
       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 "libavutil/channel_layout.h"
      23             : #include "avformat.h"
      24             : #include "internal.h"
      25             : 
      26             : enum BMVFlags {
      27             :     BMV_NOP = 0,
      28             :     BMV_END,
      29             :     BMV_DELTA,
      30             :     BMV_INTRA,
      31             : 
      32             :     BMV_AUDIO   = 0x20,
      33             : };
      34             : 
      35             : typedef struct BMVContext {
      36             :     uint8_t *packet;
      37             :     int      size;
      38             :     int      get_next;
      39             :     int64_t  audio_pos;
      40             : } BMVContext;
      41             : 
      42           2 : static int bmv_read_header(AVFormatContext *s)
      43             : {
      44             :     AVStream *st, *ast;
      45           2 :     BMVContext *c = s->priv_data;
      46             : 
      47           2 :     st = avformat_new_stream(s, 0);
      48           2 :     if (!st)
      49           0 :         return AVERROR(ENOMEM);
      50           2 :     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
      51           2 :     st->codecpar->codec_id   = AV_CODEC_ID_BMV_VIDEO;
      52           2 :     st->codecpar->width      = 640;
      53           2 :     st->codecpar->height     = 429;
      54           2 :     st->codecpar->format     = AV_PIX_FMT_PAL8;
      55           2 :     avpriv_set_pts_info(st, 16, 1, 12);
      56           2 :     ast = avformat_new_stream(s, 0);
      57           2 :     if (!ast)
      58           0 :         return AVERROR(ENOMEM);
      59           2 :     ast->codecpar->codec_type      = AVMEDIA_TYPE_AUDIO;
      60           2 :     ast->codecpar->codec_id        = AV_CODEC_ID_BMV_AUDIO;
      61           2 :     ast->codecpar->channels        = 2;
      62           2 :     ast->codecpar->channel_layout  = AV_CH_LAYOUT_STEREO;
      63           2 :     ast->codecpar->sample_rate     = 22050;
      64           2 :     avpriv_set_pts_info(ast, 16, 1, 22050);
      65             : 
      66           2 :     c->get_next  = 1;
      67           2 :     c->audio_pos = 0;
      68           2 :     return 0;
      69             : }
      70             : 
      71          88 : static int bmv_read_packet(AVFormatContext *s, AVPacket *pkt)
      72             : {
      73          88 :     BMVContext *c = s->priv_data;
      74             :     int type, err;
      75             : 
      76         176 :     while (c->get_next) {
      77          46 :         if (s->pb->eof_reached)
      78           2 :             return AVERROR_EOF;
      79          44 :         type = avio_r8(s->pb);
      80          44 :         if (type == BMV_NOP)
      81           0 :             continue;
      82          44 :         if (type == BMV_END)
      83           0 :             return AVERROR_EOF;
      84          44 :         c->size = avio_rl24(s->pb);
      85          44 :         if (!c->size)
      86           0 :             return AVERROR_INVALIDDATA;
      87          44 :         if ((err = av_reallocp(&c->packet, c->size + 1)) < 0)
      88           0 :             return err;
      89          44 :         c->packet[0] = type;
      90          44 :         if (avio_read(s->pb, c->packet + 1, c->size) != c->size)
      91           2 :             return AVERROR(EIO);
      92          42 :         if (type & BMV_AUDIO) {
      93          42 :             int audio_size = c->packet[1] * 65 + 1;
      94          42 :             if (audio_size >= c->size) {
      95           0 :                 av_log(s, AV_LOG_ERROR, "Reported audio size %d is bigger than packet size (%d)\n",
      96             :                        audio_size, c->size);
      97           0 :                 return AVERROR_INVALIDDATA;
      98             :             }
      99          42 :             if (av_new_packet(pkt, audio_size) < 0)
     100           0 :                 return AVERROR(ENOMEM);
     101          42 :             memcpy(pkt->data, c->packet + 1, pkt->size);
     102          42 :             pkt->stream_index = 1;
     103          42 :             pkt->pts          = c->audio_pos;
     104          42 :             pkt->duration     = c->packet[1] * 32;
     105          42 :             c->audio_pos += pkt->duration;
     106          42 :             c->get_next   = 0;
     107          42 :             return pkt->size;
     108             :         } else
     109           0 :             break;
     110             :     }
     111          42 :     if (av_new_packet(pkt, c->size + 1) < 0)
     112           0 :         return AVERROR(ENOMEM);
     113          42 :     pkt->stream_index = 0;
     114          42 :     c->get_next = 1;
     115          42 :     memcpy(pkt->data, c->packet, pkt->size);
     116          42 :     return pkt->size;
     117             : }
     118             : 
     119           2 : static int bmv_read_close(AVFormatContext *s)
     120             : {
     121           2 :     BMVContext *c = s->priv_data;
     122             : 
     123           2 :     av_freep(&c->packet);
     124             : 
     125           2 :     return 0;
     126             : }
     127             : 
     128             : AVInputFormat ff_bmv_demuxer = {
     129             :     .name           = "bmv",
     130             :     .long_name      = NULL_IF_CONFIG_SMALL("Discworld II BMV"),
     131             :     .priv_data_size = sizeof(BMVContext),
     132             :     .read_header    = bmv_read_header,
     133             :     .read_packet    = bmv_read_packet,
     134             :     .read_close     = bmv_read_close,
     135             :     .extensions     = "bmv",
     136             : };

Generated by: LCOV version 1.13