LCOV - code coverage report
Current view: top level - libavformat - lxfdec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 3 150 2.0 %
Date: 2017-12-12 11:08:38 Functions: 1 6 16.7 %

          Line data    Source code
       1             : /*
       2             :  * LXF demuxer
       3             :  * Copyright (c) 2010 Tomas Härdin
       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 <inttypes.h>
      23             : 
      24             : #include "libavutil/intreadwrite.h"
      25             : #include "libavcodec/bytestream.h"
      26             : #include "avformat.h"
      27             : #include "internal.h"
      28             : 
      29             : #define LXF_MAX_PACKET_HEADER_SIZE 256
      30             : #define LXF_HEADER_DATA_SIZE    120
      31             : #define LXF_IDENT               "LEITCH\0"
      32             : #define LXF_IDENT_LENGTH        8
      33             : #define LXF_SAMPLERATE          48000
      34             : 
      35             : static const AVCodecTag lxf_tags[] = {
      36             :     { AV_CODEC_ID_MJPEG,       0 },
      37             :     { AV_CODEC_ID_MPEG1VIDEO,  1 },
      38             :     { AV_CODEC_ID_MPEG2VIDEO,  2 },    //MpMl, 4:2:0
      39             :     { AV_CODEC_ID_MPEG2VIDEO,  3 },    //MpPl, 4:2:2
      40             :     { AV_CODEC_ID_DVVIDEO,     4 },    //DV25
      41             :     { AV_CODEC_ID_DVVIDEO,     5 },    //DVCPRO
      42             :     { AV_CODEC_ID_DVVIDEO,     6 },    //DVCPRO50
      43             :     { AV_CODEC_ID_RAWVIDEO,    7 },    //AV_PIX_FMT_ARGB, where alpha is used for chroma keying
      44             :     { AV_CODEC_ID_RAWVIDEO,    8 },    //16-bit chroma key
      45             :     { AV_CODEC_ID_MPEG2VIDEO,  9 },    //4:2:2 CBP ("Constrained Bytes per Gop")
      46             :     { AV_CODEC_ID_NONE,        0 },
      47             : };
      48             : 
      49             : typedef struct LXFDemuxContext {
      50             :     int channels;                       ///< number of audio channels. zero means no audio
      51             :     int frame_number;                   ///< current video frame
      52             :     uint32_t video_format, packet_type, extended_size;
      53             : } LXFDemuxContext;
      54             : 
      55        6130 : static int lxf_probe(AVProbeData *p)
      56             : {
      57        6130 :     if (!memcmp(p->buf, LXF_IDENT, LXF_IDENT_LENGTH))
      58           0 :         return AVPROBE_SCORE_MAX;
      59             : 
      60        6130 :     return 0;
      61             : }
      62             : 
      63             : /**
      64             :  * Verify the checksum of an LXF packet header
      65             :  *
      66             :  * @param[in] header the packet header to check
      67             :  * @return zero if the checksum is OK, non-zero otherwise
      68             :  */
      69           0 : static int check_checksum(const uint8_t *header, int size)
      70             : {
      71             :     int x;
      72           0 :     uint32_t sum = 0;
      73             : 
      74           0 :     for (x = 0; x < size; x += 4)
      75           0 :         sum += AV_RL32(&header[x]);
      76             : 
      77           0 :     return sum;
      78             : }
      79             : 
      80             : /**
      81             :  * Read input until we find the next ident. If found, copy it to the header buffer
      82             :  *
      83             :  * @param[out] header where to copy the ident to
      84             :  * @return 0 if an ident was found, < 0 on I/O error
      85             :  */
      86           0 : static int lxf_sync(AVFormatContext *s, uint8_t *header)
      87             : {
      88             :     uint8_t buf[LXF_IDENT_LENGTH];
      89             :     int ret;
      90             : 
      91           0 :     if ((ret = avio_read(s->pb, buf, LXF_IDENT_LENGTH)) != LXF_IDENT_LENGTH)
      92           0 :         return ret < 0 ? ret : AVERROR_EOF;
      93             : 
      94           0 :     while (memcmp(buf, LXF_IDENT, LXF_IDENT_LENGTH)) {
      95           0 :         if (avio_feof(s->pb))
      96           0 :             return AVERROR_EOF;
      97             : 
      98           0 :         memmove(buf, &buf[1], LXF_IDENT_LENGTH-1);
      99           0 :         buf[LXF_IDENT_LENGTH-1] = avio_r8(s->pb);
     100             :     }
     101             : 
     102           0 :     memcpy(header, LXF_IDENT, LXF_IDENT_LENGTH);
     103             : 
     104           0 :     return 0;
     105             : }
     106             : 
     107             : /**
     108             :  * Read and checksum the next packet header
     109             :  *
     110             :  * @return the size of the payload following the header or < 0 on failure
     111             :  */
     112           0 : static int get_packet_header(AVFormatContext *s)
     113             : {
     114           0 :     LXFDemuxContext *lxf = s->priv_data;
     115           0 :     AVIOContext   *pb  = s->pb;
     116             :     int track_size, samples, ret;
     117             :     uint32_t version, audio_format, header_size, channels, tmp;
     118             :     AVStream *st;
     119             :     uint8_t header[LXF_MAX_PACKET_HEADER_SIZE];
     120           0 :     const uint8_t *p = header + LXF_IDENT_LENGTH;
     121             : 
     122             :     //find and read the ident
     123           0 :     if ((ret = lxf_sync(s, header)) < 0)
     124           0 :         return ret;
     125             : 
     126           0 :     ret = avio_read(pb, header + LXF_IDENT_LENGTH, 8);
     127           0 :     if (ret != 8)
     128           0 :         return ret < 0 ? ret : AVERROR_EOF;
     129             : 
     130           0 :     version     = bytestream_get_le32(&p);
     131           0 :     header_size = bytestream_get_le32(&p);
     132           0 :     if (version > 1)
     133           0 :         avpriv_request_sample(s, "Format version %"PRIu32, version);
     134             : 
     135           0 :     if (header_size < (version ? 72 : 60) ||
     136           0 :         header_size > LXF_MAX_PACKET_HEADER_SIZE ||
     137           0 :         (header_size & 3)) {
     138           0 :         av_log(s, AV_LOG_ERROR, "Invalid header size 0x%"PRIx32"\n", header_size);
     139           0 :         return AVERROR_INVALIDDATA;
     140             :     }
     141             : 
     142             :     //read the rest of the packet header
     143           0 :     if ((ret = avio_read(pb, header + (p - header),
     144           0 :                           header_size - (p - header))) !=
     145           0 :                           header_size - (p - header))
     146           0 :         return ret < 0 ? ret : AVERROR_EOF;
     147             : 
     148           0 :     if (check_checksum(header, header_size))
     149           0 :         av_log(s, AV_LOG_ERROR, "checksum error\n");
     150             : 
     151           0 :     lxf->packet_type = bytestream_get_le32(&p);
     152           0 :     p += version ? 20 : 12;
     153             : 
     154           0 :     lxf->extended_size = 0;
     155           0 :     switch (lxf->packet_type) {
     156           0 :     case 0:
     157             :         //video
     158           0 :         lxf->video_format = bytestream_get_le32(&p);
     159           0 :         ret               = bytestream_get_le32(&p);
     160             :         //skip VBI data and metadata
     161           0 :         avio_skip(pb, (int64_t)(uint32_t)AV_RL32(p + 4) +
     162           0 :                       (int64_t)(uint32_t)AV_RL32(p + 12));
     163           0 :         break;
     164           0 :     case 1:
     165             :         //audio
     166           0 :         if (s->nb_streams < 2) {
     167           0 :             av_log(s, AV_LOG_INFO, "got audio packet, but no audio stream present\n");
     168           0 :             break;
     169             :         }
     170             : 
     171           0 :         if (version == 0)
     172           0 :             p += 8;
     173           0 :         audio_format = bytestream_get_le32(&p);
     174           0 :         channels     = bytestream_get_le32(&p);
     175           0 :         track_size   = bytestream_get_le32(&p);
     176             : 
     177           0 :         st = s->streams[1];
     178             : 
     179             :         //set codec based on specified audio bitdepth
     180             :         //we only support tightly packed 16-, 20-, 24- and 32-bit PCM at the moment
     181           0 :         st->codecpar->bits_per_coded_sample = (audio_format >> 6) & 0x3F;
     182             : 
     183           0 :         if (st->codecpar->bits_per_coded_sample != (audio_format & 0x3F)) {
     184           0 :             avpriv_report_missing_feature(s, "Not tightly packed PCM");
     185           0 :             return AVERROR_PATCHWELCOME;
     186             :         }
     187             : 
     188           0 :         switch (st->codecpar->bits_per_coded_sample) {
     189           0 :         case 16: st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE_PLANAR; break;
     190           0 :         case 20: st->codecpar->codec_id = AV_CODEC_ID_PCM_LXF;   break;
     191           0 :         case 24: st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE_PLANAR; break;
     192           0 :         case 32: st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE_PLANAR; break;
     193           0 :         default:
     194           0 :             avpriv_report_missing_feature(s, "PCM not 16-, 20-, 24- or 32-bits");
     195           0 :             return AVERROR_PATCHWELCOME;
     196             :         }
     197             : 
     198           0 :         samples = track_size * 8 / st->codecpar->bits_per_coded_sample;
     199             : 
     200             :         //use audio packet size to determine video standard
     201             :         //for NTSC we have one 8008-sample audio frame per five video frames
     202           0 :         if (samples == LXF_SAMPLERATE * 5005 / 30000) {
     203           0 :             avpriv_set_pts_info(s->streams[0], 64, 1001, 30000);
     204             :         } else {
     205             :             //assume PAL, but warn if we don't have 1920 samples
     206           0 :             if (samples != LXF_SAMPLERATE / 25)
     207           0 :                 av_log(s, AV_LOG_WARNING,
     208             :                        "video doesn't seem to be PAL or NTSC. guessing PAL\n");
     209             : 
     210           0 :             avpriv_set_pts_info(s->streams[0], 64, 1, 25);
     211             :         }
     212             : 
     213             :         //TODO: warning if track mask != (1 << channels) - 1?
     214           0 :         ret = av_popcount(channels) * track_size;
     215             : 
     216           0 :         break;
     217           0 :     default:
     218           0 :         tmp = bytestream_get_le32(&p);
     219           0 :         ret = bytestream_get_le32(&p);
     220           0 :         if (tmp == 1)
     221           0 :             lxf->extended_size = bytestream_get_le32(&p);
     222           0 :         break;
     223             :     }
     224             : 
     225           0 :     return ret;
     226             : }
     227             : 
     228           0 : static int lxf_read_header(AVFormatContext *s)
     229             : {
     230           0 :     LXFDemuxContext *lxf = s->priv_data;
     231           0 :     AVIOContext   *pb  = s->pb;
     232             :     uint8_t header_data[LXF_HEADER_DATA_SIZE];
     233             :     int ret;
     234             :     AVStream *st;
     235             :     uint32_t video_params, disk_params;
     236             :     uint16_t record_date, expiration_date;
     237             : 
     238           0 :     if ((ret = get_packet_header(s)) < 0)
     239           0 :         return ret;
     240             : 
     241           0 :     if (ret != LXF_HEADER_DATA_SIZE) {
     242           0 :         av_log(s, AV_LOG_ERROR, "expected %d B size header, got %d\n",
     243             :                LXF_HEADER_DATA_SIZE, ret);
     244           0 :         return AVERROR_INVALIDDATA;
     245             :     }
     246             : 
     247           0 :     if ((ret = avio_read(pb, header_data, LXF_HEADER_DATA_SIZE)) != LXF_HEADER_DATA_SIZE)
     248           0 :         return ret < 0 ? ret : AVERROR_EOF;
     249             : 
     250           0 :     if (!(st = avformat_new_stream(s, NULL)))
     251           0 :         return AVERROR(ENOMEM);
     252             : 
     253           0 :     st->duration          = AV_RL32(&header_data[32]);
     254           0 :     video_params          = AV_RL32(&header_data[40]);
     255           0 :     record_date           = AV_RL16(&header_data[56]);
     256           0 :     expiration_date       = AV_RL16(&header_data[58]);
     257           0 :     disk_params           = AV_RL32(&header_data[116]);
     258             : 
     259           0 :     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     260           0 :     st->codecpar->bit_rate   = 1000000 * ((video_params >> 14) & 0xFF);
     261           0 :     st->codecpar->codec_tag  = video_params & 0xF;
     262           0 :     st->codecpar->codec_id   = ff_codec_get_id(lxf_tags, st->codecpar->codec_tag);
     263           0 :     st->need_parsing         = AVSTREAM_PARSE_HEADERS;
     264             : 
     265           0 :     av_log(s, AV_LOG_DEBUG, "record: %x = %i-%02i-%02i\n",
     266           0 :            record_date, 1900 + (record_date & 0x7F), (record_date >> 7) & 0xF,
     267             :            (record_date >> 11) & 0x1F);
     268             : 
     269           0 :     av_log(s, AV_LOG_DEBUG, "expire: %x = %i-%02i-%02i\n",
     270           0 :            expiration_date, 1900 + (expiration_date & 0x7F), (expiration_date >> 7) & 0xF,
     271             :            (expiration_date >> 11) & 0x1F);
     272             : 
     273           0 :     if ((video_params >> 22) & 1)
     274           0 :         av_log(s, AV_LOG_WARNING, "VBI data not yet supported\n");
     275             : 
     276           0 :     if ((lxf->channels = 1 << (disk_params >> 4 & 3) + 1)) {
     277           0 :         if (!(st = avformat_new_stream(s, NULL)))
     278           0 :             return AVERROR(ENOMEM);
     279             : 
     280           0 :         st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
     281           0 :         st->codecpar->sample_rate = LXF_SAMPLERATE;
     282           0 :         st->codecpar->channels    = lxf->channels;
     283             : 
     284           0 :         avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
     285             :     }
     286             : 
     287           0 :     avio_skip(s->pb, lxf->extended_size);
     288             : 
     289           0 :     return 0;
     290             : }
     291             : 
     292           0 : static int lxf_read_packet(AVFormatContext *s, AVPacket *pkt)
     293             : {
     294           0 :     LXFDemuxContext *lxf = s->priv_data;
     295           0 :     AVIOContext   *pb  = s->pb;
     296             :     uint32_t stream;
     297             :     int ret, ret2;
     298             : 
     299           0 :     if ((ret = get_packet_header(s)) < 0)
     300           0 :         return ret;
     301             : 
     302           0 :     stream = lxf->packet_type;
     303             : 
     304           0 :     if (stream > 1) {
     305           0 :         av_log(s, AV_LOG_WARNING,
     306             :                "got packet with illegal stream index %"PRIu32"\n", stream);
     307           0 :         return FFERROR_REDO;
     308             :     }
     309             : 
     310           0 :     if (stream == 1 && s->nb_streams < 2) {
     311           0 :         av_log(s, AV_LOG_ERROR, "got audio packet without having an audio stream\n");
     312           0 :         return AVERROR_INVALIDDATA;
     313             :     }
     314             : 
     315           0 :     if ((ret2 = av_new_packet(pkt, ret)) < 0)
     316           0 :         return ret2;
     317             : 
     318           0 :     if ((ret2 = avio_read(pb, pkt->data, ret)) != ret) {
     319           0 :         av_packet_unref(pkt);
     320           0 :         return ret2 < 0 ? ret2 : AVERROR_EOF;
     321             :     }
     322             : 
     323           0 :     pkt->stream_index = stream;
     324             : 
     325           0 :     if (!stream) {
     326             :         //picture type (0 = closed I, 1 = open I, 2 = P, 3 = B)
     327           0 :         if (((lxf->video_format >> 22) & 0x3) < 2)
     328           0 :             pkt->flags |= AV_PKT_FLAG_KEY;
     329             : 
     330           0 :         pkt->dts = lxf->frame_number++;
     331             :     }
     332             : 
     333           0 :     return ret;
     334             : }
     335             : 
     336             : AVInputFormat ff_lxf_demuxer = {
     337             :     .name           = "lxf",
     338             :     .long_name      = NULL_IF_CONFIG_SMALL("VR native stream (LXF)"),
     339             :     .priv_data_size = sizeof(LXFDemuxContext),
     340             :     .read_probe     = lxf_probe,
     341             :     .read_header    = lxf_read_header,
     342             :     .read_packet    = lxf_read_packet,
     343             :     .codec_tag      = (const AVCodecTag* const []){lxf_tags, 0},
     344             : };

Generated by: LCOV version 1.13