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
22 #include "samplefmt.h"
28 typedef struct SampleFmtInfo
{
32 enum AVSampleFormat altform
; ///< planar<->packed alternative form
35 /** this table gives more information about formats */
36 static const SampleFmtInfo sample_fmt_info
[AV_SAMPLE_FMT_NB
] = {
37 [AV_SAMPLE_FMT_U8
] = { .name
= "u8", .bits
= 8, .planar
= 0, .altform
= AV_SAMPLE_FMT_U8P
},
38 [AV_SAMPLE_FMT_S16
] = { .name
= "s16", .bits
= 16, .planar
= 0, .altform
= AV_SAMPLE_FMT_S16P
},
39 [AV_SAMPLE_FMT_S32
] = { .name
= "s32", .bits
= 32, .planar
= 0, .altform
= AV_SAMPLE_FMT_S32P
},
40 [AV_SAMPLE_FMT_S64
] = { .name
= "s64", .bits
= 64, .planar
= 0, .altform
= AV_SAMPLE_FMT_S64P
},
41 [AV_SAMPLE_FMT_FLT
] = { .name
= "flt", .bits
= 32, .planar
= 0, .altform
= AV_SAMPLE_FMT_FLTP
},
42 [AV_SAMPLE_FMT_DBL
] = { .name
= "dbl", .bits
= 64, .planar
= 0, .altform
= AV_SAMPLE_FMT_DBLP
},
43 [AV_SAMPLE_FMT_U8P
] = { .name
= "u8p", .bits
= 8, .planar
= 1, .altform
= AV_SAMPLE_FMT_U8
},
44 [AV_SAMPLE_FMT_S16P
] = { .name
= "s16p", .bits
= 16, .planar
= 1, .altform
= AV_SAMPLE_FMT_S16
},
45 [AV_SAMPLE_FMT_S32P
] = { .name
= "s32p", .bits
= 32, .planar
= 1, .altform
= AV_SAMPLE_FMT_S32
},
46 [AV_SAMPLE_FMT_S64P
] = { .name
= "s64p", .bits
= 64, .planar
= 1, .altform
= AV_SAMPLE_FMT_S64
},
47 [AV_SAMPLE_FMT_FLTP
] = { .name
= "fltp", .bits
= 32, .planar
= 1, .altform
= AV_SAMPLE_FMT_FLT
},
48 [AV_SAMPLE_FMT_DBLP
] = { .name
= "dblp", .bits
= 64, .planar
= 1, .altform
= AV_SAMPLE_FMT_DBL
},
51 const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt
)
53 if (sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
)
55 return sample_fmt_info
[sample_fmt
].name
;
58 enum AVSampleFormat
av_get_sample_fmt(const char *name
)
62 for (i
= 0; i
< AV_SAMPLE_FMT_NB
; i
++)
63 if (!strcmp(sample_fmt_info
[i
].name
, name
))
65 return AV_SAMPLE_FMT_NONE
;
68 enum AVSampleFormat
av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt
, int planar
)
70 if (sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
)
71 return AV_SAMPLE_FMT_NONE
;
72 if (sample_fmt_info
[sample_fmt
].planar
== planar
)
74 return sample_fmt_info
[sample_fmt
].altform
;
77 enum AVSampleFormat
av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt
)
79 if (sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
)
80 return AV_SAMPLE_FMT_NONE
;
81 if (sample_fmt_info
[sample_fmt
].planar
)
82 return sample_fmt_info
[sample_fmt
].altform
;
86 enum AVSampleFormat
av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt
)
88 if (sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
)
89 return AV_SAMPLE_FMT_NONE
;
90 if (sample_fmt_info
[sample_fmt
].planar
)
92 return sample_fmt_info
[sample_fmt
].altform
;
95 char *av_get_sample_fmt_string (char *buf
, int buf_size
, enum AVSampleFormat sample_fmt
)
99 snprintf(buf
, buf_size
, "name " " depth");
100 else if (sample_fmt
< AV_SAMPLE_FMT_NB
) {
101 SampleFmtInfo info
= sample_fmt_info
[sample_fmt
];
102 snprintf (buf
, buf_size
, "%-6s" " %2d ", info
.name
, info
.bits
);
108 int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt
)
110 return sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
?
111 0 : sample_fmt_info
[sample_fmt
].bits
>> 3;
114 int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt
)
116 if (sample_fmt
< 0 || sample_fmt
>= AV_SAMPLE_FMT_NB
)
118 return sample_fmt_info
[sample_fmt
].planar
;
121 int av_samples_get_buffer_size(int *linesize
, int nb_channels
, int nb_samples
,
122 enum AVSampleFormat sample_fmt
, int align
)
125 int sample_size
= av_get_bytes_per_sample(sample_fmt
);
126 int planar
= av_sample_fmt_is_planar(sample_fmt
);
128 /* validate parameter ranges */
129 if (!sample_size
|| nb_samples
<= 0 || nb_channels
<= 0)
130 return AVERROR(EINVAL
);
132 /* auto-select alignment if not specified */
134 if (nb_samples
> INT_MAX
- 31)
135 return AVERROR(EINVAL
);
137 nb_samples
= FFALIGN(nb_samples
, 32);
140 /* check for integer overflow */
141 if (nb_channels
> INT_MAX
/ align
||
142 (int64_t)nb_channels
* nb_samples
> (INT_MAX
- (align
* nb_channels
)) / sample_size
)
143 return AVERROR(EINVAL
);
145 line_size
= planar
? FFALIGN(nb_samples
* sample_size
, align
) :
146 FFALIGN(nb_samples
* sample_size
* nb_channels
, align
);
148 *linesize
= line_size
;
150 return planar
? line_size
* nb_channels
: line_size
;
153 int av_samples_fill_arrays(uint8_t **audio_data
, int *linesize
,
154 const uint8_t *buf
, int nb_channels
, int nb_samples
,
155 enum AVSampleFormat sample_fmt
, int align
)
157 int ch
, planar
, buf_size
, line_size
;
159 planar
= av_sample_fmt_is_planar(sample_fmt
);
160 buf_size
= av_samples_get_buffer_size(&line_size
, nb_channels
, nb_samples
,
166 *linesize
= line_size
;
168 memset(audio_data
, 0, planar
169 ? sizeof(*audio_data
) * nb_channels
170 : sizeof(*audio_data
));
175 audio_data
[0] = (uint8_t *)buf
;
176 for (ch
= 1; planar
&& ch
< nb_channels
; ch
++)
177 audio_data
[ch
] = audio_data
[ch
-1] + line_size
;
182 int av_samples_alloc(uint8_t **audio_data
, int *linesize
, int nb_channels
,
183 int nb_samples
, enum AVSampleFormat sample_fmt
, int align
)
186 int size
= av_samples_get_buffer_size(NULL
, nb_channels
, nb_samples
,
191 buf
= av_malloc(size
);
193 return AVERROR(ENOMEM
);
195 size
= av_samples_fill_arrays(audio_data
, linesize
, buf
, nb_channels
,
196 nb_samples
, sample_fmt
, align
);
202 av_samples_set_silence(audio_data
, 0, nb_samples
, nb_channels
, sample_fmt
);
207 int av_samples_alloc_array_and_samples(uint8_t ***audio_data
, int *linesize
, int nb_channels
,
208 int nb_samples
, enum AVSampleFormat sample_fmt
, int align
)
210 int ret
, nb_planes
= av_sample_fmt_is_planar(sample_fmt
) ? nb_channels
: 1;
212 *audio_data
= av_calloc(nb_planes
, sizeof(**audio_data
));
214 return AVERROR(ENOMEM
);
215 ret
= av_samples_alloc(*audio_data
, linesize
, nb_channels
,
216 nb_samples
, sample_fmt
, align
);
218 av_freep(audio_data
);
222 int av_samples_copy(uint8_t * const *dst
, uint8_t * const *src
, int dst_offset
,
223 int src_offset
, int nb_samples
, int nb_channels
,
224 enum AVSampleFormat sample_fmt
)
226 int planar
= av_sample_fmt_is_planar(sample_fmt
);
227 int planes
= planar
? nb_channels
: 1;
228 int block_align
= av_get_bytes_per_sample(sample_fmt
) * (planar
? 1 : nb_channels
);
229 int data_size
= nb_samples
* block_align
;
232 dst_offset
*= block_align
;
233 src_offset
*= block_align
;
235 if((dst
[0] < src
[0] ? src
[0] - dst
[0] : dst
[0] - src
[0]) >= data_size
) {
236 for (i
= 0; i
< planes
; i
++)
237 memcpy(dst
[i
] + dst_offset
, src
[i
] + src_offset
, data_size
);
239 for (i
= 0; i
< planes
; i
++)
240 memmove(dst
[i
] + dst_offset
, src
[i
] + src_offset
, data_size
);
246 int av_samples_set_silence(uint8_t * const *audio_data
, int offset
, int nb_samples
,
247 int nb_channels
, enum AVSampleFormat sample_fmt
)
249 int planar
= av_sample_fmt_is_planar(sample_fmt
);
250 int planes
= planar
? nb_channels
: 1;
251 int block_align
= av_get_bytes_per_sample(sample_fmt
) * (planar
? 1 : nb_channels
);
252 int data_size
= nb_samples
* block_align
;
253 int fill_char
= (sample_fmt
== AV_SAMPLE_FMT_U8
||
254 sample_fmt
== AV_SAMPLE_FMT_U8P
) ? 0x80 : 0x00;
257 offset
*= block_align
;
259 for (i
= 0; i
< planes
; i
++)
260 memset(audio_data
[i
] + offset
, fill_char
, data_size
);