LCOV - code coverage report
Current view: top level - libavutil - samplefmt.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 91 116 78.4 %
Date: 2017-10-18 21:45:51 Functions: 12 14 85.7 %

          Line data    Source code
       1             : /*
       2             :  * This file is part of FFmpeg.
       3             :  *
       4             :  * FFmpeg is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU Lesser General Public
       6             :  * License as published by the Free Software Foundation; either
       7             :  * version 2.1 of the License, or (at your option) any later version.
       8             :  *
       9             :  * FFmpeg is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :  * Lesser General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public
      15             :  * License along with FFmpeg; if not, write to the Free Software
      16             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      17             :  */
      18             : 
      19             : #include "common.h"
      20             : #include "samplefmt.h"
      21             : 
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <string.h>
      25             : 
      26             : typedef struct SampleFmtInfo {
      27             :     char name[8];
      28             :     int bits;
      29             :     int planar;
      30             :     enum AVSampleFormat altform; ///< planar<->packed alternative form
      31             : } SampleFmtInfo;
      32             : 
      33             : /** this table gives more information about formats */
      34             : static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB] = {
      35             :     [AV_SAMPLE_FMT_U8]   = { .name =   "u8", .bits =  8, .planar = 0, .altform = AV_SAMPLE_FMT_U8P  },
      36             :     [AV_SAMPLE_FMT_S16]  = { .name =  "s16", .bits = 16, .planar = 0, .altform = AV_SAMPLE_FMT_S16P },
      37             :     [AV_SAMPLE_FMT_S32]  = { .name =  "s32", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_S32P },
      38             :     [AV_SAMPLE_FMT_S64]  = { .name =  "s64", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_S64P },
      39             :     [AV_SAMPLE_FMT_FLT]  = { .name =  "flt", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_FLTP },
      40             :     [AV_SAMPLE_FMT_DBL]  = { .name =  "dbl", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_DBLP },
      41             :     [AV_SAMPLE_FMT_U8P]  = { .name =  "u8p", .bits =  8, .planar = 1, .altform = AV_SAMPLE_FMT_U8   },
      42             :     [AV_SAMPLE_FMT_S16P] = { .name = "s16p", .bits = 16, .planar = 1, .altform = AV_SAMPLE_FMT_S16  },
      43             :     [AV_SAMPLE_FMT_S32P] = { .name = "s32p", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_S32  },
      44             :     [AV_SAMPLE_FMT_S64P] = { .name = "s64p", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_S64  },
      45             :     [AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_FLT  },
      46             :     [AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_DBL  },
      47             : };
      48             : 
      49      119120 : const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
      50             : {
      51      119120 :     if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
      52        8218 :         return NULL;
      53      110902 :     return sample_fmt_info[sample_fmt].name;
      54             : }
      55             : 
      56        4178 : enum AVSampleFormat av_get_sample_fmt(const char *name)
      57             : {
      58             :     int i;
      59             : 
      60       19328 :     for (i = 0; i < AV_SAMPLE_FMT_NB; i++)
      61       19326 :         if (!strcmp(sample_fmt_info[i].name, name))
      62        4176 :             return i;
      63           2 :     return AV_SAMPLE_FMT_NONE;
      64             : }
      65             : 
      66           0 : enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar)
      67             : {
      68           0 :     if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
      69           0 :         return AV_SAMPLE_FMT_NONE;
      70           0 :     if (sample_fmt_info[sample_fmt].planar == planar)
      71           0 :         return sample_fmt;
      72           0 :     return sample_fmt_info[sample_fmt].altform;
      73             : }
      74             : 
      75        6576 : enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
      76             : {
      77        6576 :     if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
      78          42 :         return AV_SAMPLE_FMT_NONE;
      79        6534 :     if (sample_fmt_info[sample_fmt].planar)
      80        4302 :         return sample_fmt_info[sample_fmt].altform;
      81        2232 :     return sample_fmt;
      82             : }
      83             : 
      84        3261 : enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt)
      85             : {
      86        3261 :     if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
      87           0 :         return AV_SAMPLE_FMT_NONE;
      88        3261 :     if (sample_fmt_info[sample_fmt].planar)
      89        2267 :         return sample_fmt;
      90         994 :     return sample_fmt_info[sample_fmt].altform;
      91             : }
      92             : 
      93           0 : char *av_get_sample_fmt_string (char *buf, int buf_size, enum AVSampleFormat sample_fmt)
      94             : {
      95             :     /* print header */
      96           0 :     if (sample_fmt < 0)
      97           0 :         snprintf(buf, buf_size, "name  " " depth");
      98           0 :     else if (sample_fmt < AV_SAMPLE_FMT_NB) {
      99           0 :         SampleFmtInfo info = sample_fmt_info[sample_fmt];
     100           0 :         snprintf (buf, buf_size, "%-6s" "   %2d ", info.name, info.bits);
     101             :     }
     102             : 
     103           0 :     return buf;
     104             : }
     105             : 
     106      444782 : int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
     107             : {
     108      444687 :      return sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB ?
     109      889465 :         0 : sample_fmt_info[sample_fmt].bits >> 3;
     110             : }
     111             : 
     112      713805 : int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
     113             : {
     114      713805 :      if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
     115          74 :          return 0;
     116      713731 :      return sample_fmt_info[sample_fmt].planar;
     117             : }
     118             : 
     119       11320 : int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
     120             :                                enum AVSampleFormat sample_fmt, int align)
     121             : {
     122             :     int line_size;
     123       11320 :     int sample_size = av_get_bytes_per_sample(sample_fmt);
     124       11320 :     int planar      = av_sample_fmt_is_planar(sample_fmt);
     125             : 
     126             :     /* validate parameter ranges */
     127       11320 :     if (!sample_size || nb_samples <= 0 || nb_channels <= 0)
     128           0 :         return AVERROR(EINVAL);
     129             : 
     130             :     /* auto-select alignment if not specified */
     131       11320 :     if (!align) {
     132       11143 :         if (nb_samples > INT_MAX - 31)
     133           0 :             return AVERROR(EINVAL);
     134       11143 :         align = 1;
     135       11143 :         nb_samples = FFALIGN(nb_samples, 32);
     136             :     }
     137             : 
     138             :     /* check for integer overflow */
     139       22640 :     if (nb_channels > INT_MAX / align ||
     140       11320 :         (int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) / sample_size)
     141           0 :         return AVERROR(EINVAL);
     142             : 
     143       16118 :     line_size = planar ? FFALIGN(nb_samples * sample_size,               align) :
     144        4798 :                          FFALIGN(nb_samples * sample_size * nb_channels, align);
     145       11320 :     if (linesize)
     146       11211 :         *linesize = line_size;
     147             : 
     148       11320 :     return planar ? line_size * nb_channels : line_size;
     149             : }
     150             : 
     151         109 : int av_samples_fill_arrays(uint8_t **audio_data, int *linesize,
     152             :                            const uint8_t *buf, int nb_channels, int nb_samples,
     153             :                            enum AVSampleFormat sample_fmt, int align)
     154             : {
     155             :     int ch, planar, buf_size, line_size;
     156             : 
     157         109 :     planar   = av_sample_fmt_is_planar(sample_fmt);
     158         109 :     buf_size = av_samples_get_buffer_size(&line_size, nb_channels, nb_samples,
     159             :                                           sample_fmt, align);
     160         109 :     if (buf_size < 0)
     161           0 :         return buf_size;
     162             : 
     163         109 :     audio_data[0] = (uint8_t *)buf;
     164         234 :     for (ch = 1; planar && ch < nb_channels; ch++)
     165         125 :         audio_data[ch] = audio_data[ch-1] + line_size;
     166             : 
     167         109 :     if (linesize)
     168           0 :         *linesize = line_size;
     169             : 
     170         109 :     return buf_size;
     171             : }
     172             : 
     173           2 : int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
     174             :                      int nb_samples, enum AVSampleFormat sample_fmt, int align)
     175             : {
     176             :     uint8_t *buf;
     177           2 :     int size = av_samples_get_buffer_size(NULL, nb_channels, nb_samples,
     178             :                                           sample_fmt, align);
     179           2 :     if (size < 0)
     180           0 :         return size;
     181             : 
     182           2 :     buf = av_malloc(size);
     183           2 :     if (!buf)
     184           0 :         return AVERROR(ENOMEM);
     185             : 
     186           2 :     size = av_samples_fill_arrays(audio_data, linesize, buf, nb_channels,
     187             :                                   nb_samples, sample_fmt, align);
     188           2 :     if (size < 0) {
     189           0 :         av_free(buf);
     190           0 :         return size;
     191             :     }
     192             : 
     193           2 :     av_samples_set_silence(audio_data, 0, nb_samples, nb_channels, sample_fmt);
     194             : 
     195           2 :     return size;
     196             : }
     197             : 
     198           2 : int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels,
     199             :                                        int nb_samples, enum AVSampleFormat sample_fmt, int align)
     200             : {
     201           2 :     int ret, nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1;
     202             : 
     203           2 :     *audio_data = av_calloc(nb_planes, sizeof(**audio_data));
     204           2 :     if (!*audio_data)
     205           0 :         return AVERROR(ENOMEM);
     206           2 :     ret = av_samples_alloc(*audio_data, linesize, nb_channels,
     207             :                            nb_samples, sample_fmt, align);
     208           2 :     if (ret < 0)
     209           0 :         av_freep(audio_data);
     210           2 :     return ret;
     211             : }
     212             : 
     213       71066 : int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset,
     214             :                     int src_offset, int nb_samples, int nb_channels,
     215             :                     enum AVSampleFormat sample_fmt)
     216             : {
     217       71066 :     int planar      = av_sample_fmt_is_planar(sample_fmt);
     218       71066 :     int planes      = planar ? nb_channels : 1;
     219       71066 :     int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
     220       71066 :     int data_size   = nb_samples * block_align;
     221             :     int i;
     222             : 
     223       71066 :     dst_offset *= block_align;
     224       71066 :     src_offset *= block_align;
     225             : 
     226       71066 :     if((dst[0] < src[0] ? src[0] - dst[0] : dst[0] - src[0]) >= data_size) {
     227      178202 :         for (i = 0; i < planes; i++)
     228      107176 :             memcpy(dst[i] + dst_offset, src[i] + src_offset, data_size);
     229             :     } else {
     230         109 :         for (i = 0; i < planes; i++)
     231          69 :             memmove(dst[i] + dst_offset, src[i] + src_offset, data_size);
     232             :     }
     233             : 
     234       71066 :     return 0;
     235             : }
     236             : 
     237      289797 : int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples,
     238             :                            int nb_channels, enum AVSampleFormat sample_fmt)
     239             : {
     240      289797 :     int planar      = av_sample_fmt_is_planar(sample_fmt);
     241      289797 :     int planes      = planar ? nb_channels : 1;
     242      289797 :     int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
     243      289797 :     int data_size   = nb_samples * block_align;
     244      578873 :     int fill_char   = (sample_fmt == AV_SAMPLE_FMT_U8 ||
     245      290778 :                      sample_fmt == AV_SAMPLE_FMT_U8P) ? 0x80 : 0x00;
     246             :     int i;
     247             : 
     248      289797 :     offset *= block_align;
     249             : 
     250      628528 :     for (i = 0; i < planes; i++)
     251      338731 :         memset(audio_data[i] + offset, fill_char, data_size);
     252             : 
     253      289797 :     return 0;
     254             : }

Generated by: LCOV version 1.13