2 * This file is part of FFmpeg.
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.
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.
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
20 #include "samplefmt.h"
26 typedef struct SampleFmtInfo
{
30 enum AVSampleFormat altform
; ///< planar<->packed alternative form
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_FLT
] = { .name
= "flt", .bits
= 32, .planar
= 0, .altform
= AV_SAMPLE_FMT_FLTP
},
39 [AV_SAMPLE_FMT_DBL
] = { .name
= "dbl", .bits
= 64, .planar
= 0, .altform
= AV_SAMPLE_FMT_DBLP
},
40 [AV_SAMPLE_FMT_U8P
] = { .name
= "u8p", .bits
= 8, .planar
= 1, .altform
= AV_SAMPLE_FMT_U8
},
41 [AV_SAMPLE_FMT_S16P
] = { .name
= "s16p", .bits
= 16, .planar
= 1, .altform
= AV_SAMPLE_FMT_S16
},
42 [AV_SAMPLE_FMT_S32P
] = { .name
= "s32p", .bits
= 32, .planar
= 1, .altform
= AV_SAMPLE_FMT_S32
},
43 [AV_SAMPLE_FMT_FLTP
] = { .name
= "fltp", .bits
= 32, .planar
= 1, .altform
= AV_SAMPLE_FMT_FLT
},
44 [AV_SAMPLE_FMT_DBLP
] = { .name
= "dblp", .bits
= 64, .planar
= 1, .altform
= AV_SAMPLE_FMT_DBL
},
47 const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt
)
49 if (sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
)
51 return sample_fmt_info
[sample_fmt
].name
;
54 enum AVSampleFormat
av_get_sample_fmt(const char *name
)
58 for (i
= 0; i
< AV_SAMPLE_FMT_NB
; i
++)
59 if (!strcmp(sample_fmt_info
[i
].name
, name
))
61 return AV_SAMPLE_FMT_NONE
;
64 enum AVSampleFormat
av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt
, int planar
)
66 if (sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
)
67 return AV_SAMPLE_FMT_NONE
;
68 if (sample_fmt_info
[sample_fmt
].planar
== planar
)
70 return sample_fmt_info
[sample_fmt
].altform
;
73 enum AVSampleFormat
av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt
)
75 if (sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
)
76 return AV_SAMPLE_FMT_NONE
;
77 if (sample_fmt_info
[sample_fmt
].planar
)
78 return sample_fmt_info
[sample_fmt
].altform
;
82 enum AVSampleFormat
av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt
)
84 if (sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
)
85 return AV_SAMPLE_FMT_NONE
;
86 if (sample_fmt_info
[sample_fmt
].planar
)
88 return sample_fmt_info
[sample_fmt
].altform
;
91 char *av_get_sample_fmt_string (char *buf
, int buf_size
, enum AVSampleFormat sample_fmt
)
95 snprintf(buf
, buf_size
, "name " " depth");
96 else if (sample_fmt
< AV_SAMPLE_FMT_NB
) {
97 SampleFmtInfo info
= sample_fmt_info
[sample_fmt
];
98 snprintf (buf
, buf_size
, "%-6s" " %2d ", info
.name
, info
.bits
);
104 int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt
)
106 return sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
?
107 0 : sample_fmt_info
[sample_fmt
].bits
>> 3;
110 int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt
)
112 if (sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
)
114 return sample_fmt_info
[sample_fmt
].planar
;
117 int av_samples_get_buffer_size(int *linesize
, int nb_channels
, int nb_samples
,
118 enum AVSampleFormat sample_fmt
, int align
)
121 int sample_size
= av_get_bytes_per_sample(sample_fmt
);
122 int planar
= av_sample_fmt_is_planar(sample_fmt
);
124 /* validate parameter ranges */
125 if (!sample_size
|| nb_samples
<= 0 || nb_channels
<= 0)
126 return AVERROR(EINVAL
);
128 /* auto-select alignment if not specified */
130 if (nb_samples
> INT_MAX
- 31)
131 return AVERROR(EINVAL
);
133 nb_samples
= FFALIGN(nb_samples
, 32);
136 /* check for integer overflow */
137 if (nb_channels
> INT_MAX
/ align
||
138 (int64_t)nb_channels
* nb_samples
> (INT_MAX
- (align
* nb_channels
)) / sample_size
)
139 return AVERROR(EINVAL
);
141 line_size
= planar
? FFALIGN(nb_samples
* sample_size
, align
) :
142 FFALIGN(nb_samples
* sample_size
* nb_channels
, align
);
144 *linesize
= line_size
;
146 return planar
? line_size
* nb_channels
: line_size
;
149 int av_samples_fill_arrays(uint8_t **audio_data
, int *linesize
,
150 const uint8_t *buf
, int nb_channels
, int nb_samples
,
151 enum AVSampleFormat sample_fmt
, int align
)
153 int ch
, planar
, buf_size
, line_size
;
155 planar
= av_sample_fmt_is_planar(sample_fmt
);
156 buf_size
= av_samples_get_buffer_size(&line_size
, nb_channels
, nb_samples
,
161 audio_data
[0] = (uint8_t *)buf
;
162 for (ch
= 1; planar
&& ch
< nb_channels
; ch
++)
163 audio_data
[ch
] = audio_data
[ch
-1] + line_size
;
166 *linesize
= line_size
;
171 int av_samples_alloc(uint8_t **audio_data
, int *linesize
, int nb_channels
,
172 int nb_samples
, enum AVSampleFormat sample_fmt
, int align
)
175 int size
= av_samples_get_buffer_size(NULL
, nb_channels
, nb_samples
,
180 buf
= av_malloc(size
);
182 return AVERROR(ENOMEM
);
184 size
= av_samples_fill_arrays(audio_data
, linesize
, buf
, nb_channels
,
185 nb_samples
, sample_fmt
, align
);
191 av_samples_set_silence(audio_data
, 0, nb_samples
, nb_channels
, sample_fmt
);
196 int av_samples_alloc_array_and_samples(uint8_t ***audio_data
, int *linesize
, int nb_channels
,
197 int nb_samples
, enum AVSampleFormat sample_fmt
, int align
)
199 int ret
, nb_planes
= av_sample_fmt_is_planar(sample_fmt
) ? nb_channels
: 1;
201 *audio_data
= av_calloc(nb_planes
, sizeof(**audio_data
));
203 return AVERROR(ENOMEM
);
204 ret
= av_samples_alloc(*audio_data
, linesize
, nb_channels
,
205 nb_samples
, sample_fmt
, align
);
207 av_freep(audio_data
);
211 int av_samples_copy(uint8_t **dst
, uint8_t * const *src
, int dst_offset
,
212 int src_offset
, int nb_samples
, int nb_channels
,
213 enum AVSampleFormat sample_fmt
)
215 int planar
= av_sample_fmt_is_planar(sample_fmt
);
216 int planes
= planar
? nb_channels
: 1;
217 int block_align
= av_get_bytes_per_sample(sample_fmt
) * (planar
? 1 : nb_channels
);
218 int data_size
= nb_samples
* block_align
;
221 dst_offset
*= block_align
;
222 src_offset
*= block_align
;
224 if((dst
[0] < src
[0] ? src
[0] - dst
[0] : dst
[0] - src
[0]) >= data_size
) {
225 for (i
= 0; i
< planes
; i
++)
226 memcpy(dst
[i
] + dst_offset
, src
[i
] + src_offset
, data_size
);
228 for (i
= 0; i
< planes
; i
++)
229 memmove(dst
[i
] + dst_offset
, src
[i
] + src_offset
, data_size
);
235 int av_samples_set_silence(uint8_t **audio_data
, int offset
, int nb_samples
,
236 int nb_channels
, enum AVSampleFormat sample_fmt
)
238 int planar
= av_sample_fmt_is_planar(sample_fmt
);
239 int planes
= planar
? nb_channels
: 1;
240 int block_align
= av_get_bytes_per_sample(sample_fmt
) * (planar
? 1 : nb_channels
);
241 int data_size
= nb_samples
* block_align
;
242 int fill_char
= (sample_fmt
== AV_SAMPLE_FMT_U8
||
243 sample_fmt
== AV_SAMPLE_FMT_U8P
) ? 0x80 : 0x00;
246 offset
*= block_align
;
248 for (i
= 0; i
< planes
; i
++)
249 memset(audio_data
[i
] + offset
, fill_char
, data_size
);