LCOV - code coverage report
Current view: top level - libavcodec - s302m.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 53 106 50.0 %
Date: 2017-12-18 06:23:41 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SMPTE 302M decoder
       3             :  * Copyright (c) 2008 Laurent Aimar <fenrir@videolan.org>
       4             :  * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier@gmail.com>
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #include "libavutil/intreadwrite.h"
      24             : #include "libavutil/opt.h"
      25             : #include "libavutil/log.h"
      26             : #include "avcodec.h"
      27             : #include "internal.h"
      28             : #include "mathops.h"
      29             : 
      30             : #define AES3_HEADER_LEN 4
      31             : 
      32             : typedef struct S302Context {
      33             :     AVClass *class;
      34             :     int non_pcm_mode;
      35             : } S302Context;
      36             : 
      37         260 : static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
      38             :                                     int buf_size)
      39             : {
      40             :     uint32_t h;
      41             :     int frame_size, channels, bits;
      42             : 
      43         260 :     if (buf_size <= AES3_HEADER_LEN) {
      44           0 :         av_log(avctx, AV_LOG_ERROR, "frame is too short\n");
      45           0 :         return AVERROR_INVALIDDATA;
      46             :     }
      47             : 
      48             :     /*
      49             :      * AES3 header :
      50             :      * size:            16
      51             :      * number channels   2
      52             :      * channel_id        8
      53             :      * bits per samples  2
      54             :      * alignments        4
      55             :      */
      56             : 
      57         260 :     h = AV_RB32(buf);
      58         260 :     frame_size =  (h >> 16) & 0xffff;
      59         260 :     channels   = ((h >> 14) & 0x0003) * 2 +  2;
      60         260 :     bits       = ((h >>  4) & 0x0003) * 4 + 16;
      61             : 
      62         260 :     if (AES3_HEADER_LEN + frame_size != buf_size || bits > 24) {
      63           1 :         av_log(avctx, AV_LOG_ERROR, "frame has invalid header\n");
      64           1 :         return AVERROR_INVALIDDATA;
      65             :     }
      66             : 
      67             :     /* Set output properties */
      68         259 :     avctx->bits_per_raw_sample = bits;
      69         259 :     if (bits > 16)
      70           0 :         avctx->sample_fmt = AV_SAMPLE_FMT_S32;
      71             :     else
      72         259 :         avctx->sample_fmt = AV_SAMPLE_FMT_S16;
      73             : 
      74         259 :     avctx->channels    = channels;
      75         259 :     switch(channels) {
      76         259 :         case 2:
      77         259 :             avctx->channel_layout = AV_CH_LAYOUT_STEREO;
      78         259 :             break;
      79           0 :         case 4:
      80           0 :             avctx->channel_layout = AV_CH_LAYOUT_QUAD;
      81           0 :             break;
      82           0 :         case 6:
      83           0 :             avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
      84           0 :             break;
      85           0 :         case 8:
      86           0 :             avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX;
      87             :     }
      88             : 
      89         259 :     return frame_size;
      90             : }
      91             : 
      92         260 : static int s302m_decode_frame(AVCodecContext *avctx, void *data,
      93             :                               int *got_frame_ptr, AVPacket *avpkt)
      94             : {
      95         260 :     S302Context *s = avctx->priv_data;
      96         260 :     AVFrame *frame     = data;
      97         260 :     const uint8_t *buf = avpkt->data;
      98         260 :     int buf_size       = avpkt->size;
      99             :     int block_size, ret;
     100             :     int i;
     101         260 :     int non_pcm_data_type = -1;
     102             : 
     103         260 :     int frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
     104         260 :     if (frame_size < 0)
     105           1 :         return frame_size;
     106             : 
     107         259 :     buf_size -= AES3_HEADER_LEN;
     108         259 :     buf      += AES3_HEADER_LEN;
     109             : 
     110             :     /* get output buffer */
     111         259 :     block_size = (avctx->bits_per_raw_sample + 4) / 4;
     112         259 :     frame->nb_samples = 2 * (buf_size / block_size) / avctx->channels;
     113         259 :     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
     114           0 :         return ret;
     115             : 
     116         518 :     avctx->bit_rate = 48000 * avctx->channels * (avctx->bits_per_raw_sample + 4) +
     117         259 :                       32 * 48000 / frame->nb_samples;
     118         259 :     buf_size = (frame->nb_samples * avctx->channels / 2) * block_size;
     119             : 
     120         259 :     if (avctx->bits_per_raw_sample == 24) {
     121           0 :         uint32_t *o = (uint32_t *)frame->data[0];
     122           0 :         for (; buf_size > 6; buf_size -= 7) {
     123           0 :             *o++ = ((unsigned)ff_reverse[buf[2]]        << 24) |
     124           0 :                    (ff_reverse[buf[1]]        << 16) |
     125           0 :                    (ff_reverse[buf[0]]        <<  8);
     126           0 :             *o++ = ((unsigned)ff_reverse[buf[6] & 0xf0] << 28) |
     127           0 :                    (ff_reverse[buf[5]]        << 20) |
     128           0 :                    (ff_reverse[buf[4]]        << 12) |
     129           0 :                    (ff_reverse[buf[3] & 0x0f] <<  4);
     130           0 :             buf += 7;
     131             :         }
     132           0 :         o = (uint32_t *)frame->data[0];
     133           0 :         if (avctx->channels == 2)
     134           0 :             for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
     135           0 :                 if (o[i] || o[i+1] || o[i+2] || o[i+3])
     136             :                     break;
     137           0 :                 if (o[i+4] == 0x96F87200U && o[i+5] == 0xA54E1F00) {
     138           0 :                     non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
     139           0 :                     break;
     140             :                 }
     141             :             }
     142         259 :     } else if (avctx->bits_per_raw_sample == 20) {
     143           0 :         uint32_t *o = (uint32_t *)frame->data[0];
     144           0 :         for (; buf_size > 5; buf_size -= 6) {
     145           0 :             *o++ = ((unsigned)ff_reverse[buf[2] & 0xf0] << 28) |
     146           0 :                    (ff_reverse[buf[1]]        << 20) |
     147           0 :                    (ff_reverse[buf[0]]        << 12);
     148           0 :             *o++ = ((unsigned)ff_reverse[buf[5] & 0xf0] << 28) |
     149           0 :                    (ff_reverse[buf[4]]        << 20) |
     150           0 :                    (ff_reverse[buf[3]]        << 12);
     151           0 :             buf += 6;
     152             :         }
     153           0 :         o = (uint32_t *)frame->data[0];
     154           0 :         if (avctx->channels == 2)
     155           0 :             for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
     156           0 :                 if (o[i] || o[i+1] || o[i+2] || o[i+3])
     157             :                     break;
     158           0 :                 if (o[i+4] == 0x6F872000U && o[i+5] == 0x54E1F000) {
     159           0 :                     non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
     160           0 :                     break;
     161             :                 }
     162             :             }
     163             :     } else {
     164         259 :         uint16_t *o = (uint16_t *)frame->data[0];
     165      288896 :         for (; buf_size > 4; buf_size -= 5) {
     166      577274 :             *o++ = (ff_reverse[buf[1]]        <<  8) |
     167      288637 :                     ff_reverse[buf[0]];
     168     1154548 :             *o++ = (ff_reverse[buf[4] & 0xf0] << 12) |
     169      865911 :                    (ff_reverse[buf[3]]        <<  4) |
     170      288637 :                    (ff_reverse[buf[2]]        >>  4);
     171      288637 :             buf += 5;
     172             :         }
     173         259 :         o = (uint16_t *)frame->data[0];
     174         259 :         if (avctx->channels == 2)
     175         259 :             for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
     176         259 :                 if (o[i] || o[i+1] || o[i+2] || o[i+3])
     177             :                     break;
     178           0 :                 if (o[i+4] == 0xF872U && o[i+5] == 0x4E1F) {
     179           0 :                     non_pcm_data_type = (o[i+6] & 0x1F);
     180           0 :                     break;
     181             :                 }
     182             :             }
     183             :     }
     184             : 
     185         259 :     if (non_pcm_data_type != -1) {
     186           0 :         if (s->non_pcm_mode == 3) {
     187           0 :             av_log(avctx, AV_LOG_ERROR,
     188             :                    "S302 non PCM mode with data type %d not supported\n",
     189             :                    non_pcm_data_type);
     190           0 :             return AVERROR_PATCHWELCOME;
     191             :         }
     192           0 :         if (s->non_pcm_mode & 1) {
     193           0 :             return avpkt->size;
     194             :         }
     195             :     }
     196             : 
     197         259 :     avctx->sample_rate = 48000;
     198             : 
     199         259 :     *got_frame_ptr = 1;
     200             : 
     201         259 :     return avpkt->size;
     202             : }
     203             : 
     204             : #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_DECODING_PARAM
     205             : static const AVOption s302m_options[] = {
     206             :     {"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"},
     207             :     {"copy"        , "Pass NON-PCM through unchanged"     , 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 3, FLAGS, "non_pcm_mode"},
     208             :     {"drop"        , "Drop NON-PCM"                       , 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 3, FLAGS, "non_pcm_mode"},
     209             :     {"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 3, FLAGS, "non_pcm_mode"},
     210             :     {"decode_drop" , "Decode if possible else drop"       , 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"},
     211             :     {NULL}
     212             : };
     213             : 
     214             : static const AVClass s302m_class = {
     215             :     .class_name = "SMPTE 302M Decoder",
     216             :     .item_name  = av_default_item_name,
     217             :     .option     = s302m_options,
     218             :     .version    = LIBAVUTIL_VERSION_INT,
     219             : };
     220             : 
     221             : AVCodec ff_s302m_decoder = {
     222             :     .name           = "s302m",
     223             :     .long_name      = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
     224             :     .type           = AVMEDIA_TYPE_AUDIO,
     225             :     .id             = AV_CODEC_ID_S302M,
     226             :     .priv_data_size = sizeof(S302Context),
     227             :     .decode         = s302m_decode_frame,
     228             :     .capabilities   = AV_CODEC_CAP_DR1,
     229             :     .priv_class     = &s302m_class,
     230             : };

Generated by: LCOV version 1.13