LCOV - code coverage report
Current view: top level - libavformat - smjpegdec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 92 111 82.9 %
Date: 2017-12-15 11:05:35 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SMJPEG demuxer
       3             :  * Copyright (c) 2011 Paul B Mahol
       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             : /**
      23             :  * @file
      24             :  * This is a demuxer for Loki SDL Motion JPEG files
      25             :  */
      26             : 
      27             : #include <inttypes.h>
      28             : 
      29             : #include "avformat.h"
      30             : #include "internal.h"
      31             : #include "riff.h"
      32             : #include "smjpeg.h"
      33             : 
      34             : typedef struct SMJPEGContext {
      35             :     int audio_stream_index;
      36             :     int video_stream_index;
      37             : } SMJPEGContext;
      38             : 
      39        6130 : static int smjpeg_probe(AVProbeData *p)
      40             : {
      41        6130 :     if (!memcmp(p->buf, SMJPEG_MAGIC, 8))
      42           5 :         return AVPROBE_SCORE_MAX;
      43        6125 :     return 0;
      44             : }
      45             : 
      46           5 : static int smjpeg_read_header(AVFormatContext *s)
      47             : {
      48           5 :     SMJPEGContext *sc = s->priv_data;
      49           5 :     AVStream *ast = NULL, *vst = NULL;
      50           5 :     AVIOContext *pb = s->pb;
      51             :     uint32_t version, htype, hlength, duration;
      52             :     char *comment;
      53             : 
      54           5 :     avio_skip(pb, 8); // magic
      55           5 :     version = avio_rb32(pb);
      56           5 :     if (version)
      57           0 :         avpriv_request_sample(s, "Unknown version %"PRIu32, version);
      58             : 
      59           5 :     duration = avio_rb32(pb); // in msec
      60             : 
      61           5 :     while (!avio_feof(pb)) {
      62          16 :         htype = avio_rl32(pb);
      63          16 :         switch (htype) {
      64           1 :         case SMJPEG_TXT:
      65           1 :             hlength = avio_rb32(pb);
      66           1 :             if (!hlength || hlength > 512)
      67           0 :                 return AVERROR_INVALIDDATA;
      68           1 :             comment = av_malloc(hlength + 1);
      69           1 :             if (!comment)
      70           0 :                 return AVERROR(ENOMEM);
      71           1 :             if (avio_read(pb, comment, hlength) != hlength) {
      72           0 :                 av_freep(&comment);
      73           0 :                 av_log(s, AV_LOG_ERROR, "error when reading comment\n");
      74           0 :                 return AVERROR_INVALIDDATA;
      75             :             }
      76           1 :             comment[hlength] = 0;
      77           1 :             av_dict_set(&s->metadata, "comment", comment,
      78             :                         AV_DICT_DONT_STRDUP_VAL);
      79           1 :             break;
      80           5 :         case SMJPEG_SND:
      81           5 :             if (ast) {
      82           0 :                 avpriv_request_sample(s, "Multiple audio streams");
      83           0 :                 return AVERROR_PATCHWELCOME;
      84             :             }
      85           5 :             hlength = avio_rb32(pb);
      86           5 :             if (hlength < 8)
      87           0 :                 return AVERROR_INVALIDDATA;
      88           5 :             ast = avformat_new_stream(s, 0);
      89           5 :             if (!ast)
      90           0 :                 return AVERROR(ENOMEM);
      91           5 :             ast->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
      92           5 :             ast->codecpar->sample_rate = avio_rb16(pb);
      93           5 :             ast->codecpar->bits_per_coded_sample = avio_r8(pb);
      94           5 :             ast->codecpar->channels    = avio_r8(pb);
      95           5 :             ast->codecpar->codec_tag   = avio_rl32(pb);
      96           5 :             ast->codecpar->codec_id    = ff_codec_get_id(ff_codec_smjpeg_audio_tags,
      97           5 :                                                          ast->codecpar->codec_tag);
      98           5 :             ast->duration           = duration;
      99           5 :             sc->audio_stream_index  = ast->index;
     100           5 :             avpriv_set_pts_info(ast, 32, 1, 1000);
     101           5 :             avio_skip(pb, hlength - 8);
     102           5 :             break;
     103           5 :         case SMJPEG_VID:
     104           5 :             if (vst) {
     105           0 :                 avpriv_request_sample(s, "Multiple video streams");
     106           0 :                 return AVERROR_INVALIDDATA;
     107             :             }
     108           5 :             hlength = avio_rb32(pb);
     109           5 :             if (hlength < 12)
     110           0 :                 return AVERROR_INVALIDDATA;
     111           5 :             vst = avformat_new_stream(s, 0);
     112           5 :             if (!vst)
     113           0 :                 return AVERROR(ENOMEM);
     114           5 :             vst->nb_frames            = avio_rb32(pb);
     115           5 :             vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     116           5 :             vst->codecpar->width      = avio_rb16(pb);
     117           5 :             vst->codecpar->height     = avio_rb16(pb);
     118           5 :             vst->codecpar->codec_tag  = avio_rl32(pb);
     119           5 :             vst->codecpar->codec_id   = ff_codec_get_id(ff_codec_smjpeg_video_tags,
     120           5 :                                                         vst->codecpar->codec_tag);
     121           5 :             vst->duration          = duration;
     122           5 :             sc->video_stream_index = vst->index;
     123           5 :             avpriv_set_pts_info(vst, 32, 1, 1000);
     124           5 :             avio_skip(pb, hlength - 12);
     125           5 :             break;
     126           5 :         case SMJPEG_HEND:
     127           5 :             return 0;
     128           0 :         default:
     129           0 :             av_log(s, AV_LOG_ERROR, "unknown header %"PRIx32"\n", htype);
     130           0 :             return AVERROR_INVALIDDATA;
     131             :         }
     132             :     }
     133             : 
     134           0 :     return AVERROR_EOF;
     135             : }
     136             : 
     137        1585 : static int smjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
     138             : {
     139        1585 :     SMJPEGContext *sc = s->priv_data;
     140             :     uint32_t dtype, size, timestamp;
     141             :     int64_t pos;
     142             :     int ret;
     143             : 
     144        1585 :     if (avio_feof(s->pb))
     145           0 :         return AVERROR_EOF;
     146        1585 :     pos   = avio_tell(s->pb);
     147        1585 :     dtype = avio_rl32(s->pb);
     148        1585 :     switch (dtype) {
     149        1295 :     case SMJPEG_SNDD:
     150        1295 :         timestamp = avio_rb32(s->pb);
     151        1295 :         size = avio_rb32(s->pb);
     152        1295 :         ret = av_get_packet(s->pb, pkt, size);
     153        1295 :         pkt->stream_index = sc->audio_stream_index;
     154        1295 :         pkt->pts = timestamp;
     155        1295 :         pkt->pos = pos;
     156        1295 :         break;
     157         285 :     case SMJPEG_VIDD:
     158         285 :         timestamp = avio_rb32(s->pb);
     159         285 :         size = avio_rb32(s->pb);
     160         285 :         ret = av_get_packet(s->pb, pkt, size);
     161         285 :         pkt->stream_index = sc->video_stream_index;
     162         285 :         pkt->pts = timestamp;
     163         285 :         pkt->pos = pos;
     164         285 :         break;
     165           4 :     case SMJPEG_DONE:
     166           4 :         ret = AVERROR_EOF;
     167           4 :         break;
     168           1 :     default:
     169           1 :         av_log(s, AV_LOG_ERROR, "unknown chunk %"PRIx32"\n", dtype);
     170           1 :         ret = AVERROR_INVALIDDATA;
     171           1 :         break;
     172             :     }
     173        1585 :     return ret;
     174             : }
     175             : 
     176             : AVInputFormat ff_smjpeg_demuxer = {
     177             :     .name           = "smjpeg",
     178             :     .long_name      = NULL_IF_CONFIG_SMALL("Loki SDL MJPEG"),
     179             :     .priv_data_size = sizeof(SMJPEGContext),
     180             :     .read_probe     = smjpeg_probe,
     181             :     .read_header    = smjpeg_read_header,
     182             :     .read_packet    = smjpeg_read_packet,
     183             :     .extensions     = "mjpg",
     184             :     .flags          = AVFMT_GENERIC_INDEX,
     185             : };

Generated by: LCOV version 1.13