LCOV - code coverage report
Current view: top level - libavformat - smjpegenc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 64 71 90.1 %
Date: 2017-12-13 10:57:33 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SMJPEG muxer
       3             :  * Copyright (c) 2012 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 muxer for Loki SDL Motion JPEG files
      25             :  */
      26             : 
      27             : #include "avformat.h"
      28             : #include "internal.h"
      29             : #include "smjpeg.h"
      30             : 
      31             : typedef struct SMJPEGMuxContext {
      32             :     uint32_t duration;
      33             : } SMJPEGMuxContext;
      34             : 
      35           1 : static int smjpeg_write_header(AVFormatContext *s)
      36             : {
      37           1 :     AVDictionaryEntry *t = NULL;
      38           1 :     AVIOContext *pb = s->pb;
      39             :     int n, tag;
      40             : 
      41           1 :     if (s->nb_streams > 2) {
      42           0 :         av_log(s, AV_LOG_ERROR, "more than >2 streams are not supported\n");
      43           0 :         return AVERROR(EINVAL);
      44             :     }
      45           1 :     avio_write(pb, SMJPEG_MAGIC, 8);
      46           1 :     avio_wb32(pb, 0);
      47           1 :     avio_wb32(pb, 0);
      48             : 
      49           1 :     ff_standardize_creation_time(s);
      50           3 :     while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
      51           1 :         avio_wl32(pb, SMJPEG_TXT);
      52           1 :         avio_wb32(pb, strlen(t->key) + strlen(t->value) + 3);
      53           1 :         avio_write(pb, t->key, strlen(t->key));
      54           1 :         avio_write(pb, " = ", 3);
      55           1 :         avio_write(pb, t->value, strlen(t->value));
      56             :     }
      57             : 
      58           3 :     for (n = 0; n < s->nb_streams; n++) {
      59           2 :         AVStream *st = s->streams[n];
      60           2 :         AVCodecParameters *par = st->codecpar;
      61           2 :         if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
      62           1 :             tag = ff_codec_get_tag(ff_codec_smjpeg_audio_tags, par->codec_id);
      63           1 :             if (!tag) {
      64           0 :                 av_log(s, AV_LOG_ERROR, "unsupported audio codec\n");
      65           0 :                 return AVERROR(EINVAL);
      66             :             }
      67           1 :             avio_wl32(pb, SMJPEG_SND);
      68           1 :             avio_wb32(pb, 8);
      69           1 :             avio_wb16(pb, par->sample_rate);
      70           1 :             avio_w8(pb, par->bits_per_coded_sample);
      71           1 :             avio_w8(pb, par->channels);
      72           1 :             avio_wl32(pb, tag);
      73           1 :             avpriv_set_pts_info(st, 32, 1, 1000);
      74           1 :         } else if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
      75           1 :             tag = ff_codec_get_tag(ff_codec_smjpeg_video_tags, par->codec_id);
      76           1 :             if (!tag) {
      77           0 :                 av_log(s, AV_LOG_ERROR, "unsupported video codec\n");
      78           0 :                 return AVERROR(EINVAL);
      79             :             }
      80           1 :             avio_wl32(pb, SMJPEG_VID);
      81           1 :             avio_wb32(pb, 12);
      82           1 :             avio_wb32(pb, 0);
      83           1 :             avio_wb16(pb, par->width);
      84           1 :             avio_wb16(pb, par->height);
      85           1 :             avio_wl32(pb, tag);
      86           1 :             avpriv_set_pts_info(st, 32, 1, 1000);
      87             :         }
      88             :     }
      89             : 
      90           1 :     avio_wl32(pb, SMJPEG_HEND);
      91           1 :     avio_flush(pb);
      92             : 
      93           1 :     return 0;
      94             : }
      95             : 
      96          69 : static int smjpeg_write_packet(AVFormatContext *s, AVPacket *pkt)
      97             : {
      98          69 :     SMJPEGMuxContext *smc = s->priv_data;
      99          69 :     AVIOContext *pb = s->pb;
     100          69 :     AVStream *st = s->streams[pkt->stream_index];
     101          69 :     AVCodecParameters *par = st->codecpar;
     102             : 
     103          69 :     if (par->codec_type == AVMEDIA_TYPE_AUDIO)
     104          44 :         avio_wl32(pb, SMJPEG_SNDD);
     105          25 :     else if (par->codec_type == AVMEDIA_TYPE_VIDEO)
     106          25 :         avio_wl32(pb, SMJPEG_VIDD);
     107             :     else
     108           0 :         return 0;
     109             : 
     110          69 :     avio_wb32(pb, pkt->pts);
     111          69 :     avio_wb32(pb, pkt->size);
     112          69 :     avio_write(pb, pkt->data, pkt->size);
     113             : 
     114          69 :     smc->duration = FFMAX(smc->duration, pkt->pts + pkt->duration);
     115          69 :     return 0;
     116             : }
     117             : 
     118           1 : static int smjpeg_write_trailer(AVFormatContext *s)
     119             : {
     120           1 :     SMJPEGMuxContext *smc = s->priv_data;
     121           1 :     AVIOContext *pb = s->pb;
     122             :     int64_t currentpos;
     123             : 
     124           1 :     if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
     125           1 :         currentpos = avio_tell(pb);
     126           1 :         avio_seek(pb, 12, SEEK_SET);
     127           1 :         avio_wb32(pb, smc->duration);
     128           1 :         avio_seek(pb, currentpos, SEEK_SET);
     129             :     }
     130             : 
     131           1 :     avio_wl32(pb, SMJPEG_DONE);
     132             : 
     133           1 :     return 0;
     134             : }
     135             : 
     136             : AVOutputFormat ff_smjpeg_muxer = {
     137             :     .name           = "smjpeg",
     138             :     .long_name      = NULL_IF_CONFIG_SMALL("Loki SDL MJPEG"),
     139             :     .priv_data_size = sizeof(SMJPEGMuxContext),
     140             :     .audio_codec    = AV_CODEC_ID_PCM_S16LE,
     141             :     .video_codec    = AV_CODEC_ID_MJPEG,
     142             :     .write_header   = smjpeg_write_header,
     143             :     .write_packet   = smjpeg_write_packet,
     144             :     .write_trailer  = smjpeg_write_trailer,
     145             :     .flags          = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT,
     146             :     .codec_tag      = (const AVCodecTag *const []){ ff_codec_smjpeg_video_tags, ff_codec_smjpeg_audio_tags, 0 },
     147             : };

Generated by: LCOV version 1.13