18# include <AUD_Device.h>
19# include <AUD_Special.h>
32static bool request_float_audio_buffer(
int codec_id)
34 return ELEM(codec_id, AV_CODEC_ID_AAC, AV_CODEC_ID_AC3, AV_CODEC_ID_VORBIS);
39static int write_audio_frame(MovieWriter *context)
41 AVFrame *frame =
nullptr;
42 AVCodecContext *c =
context->audio_codec;
47 frame = av_frame_alloc();
48 frame->pts =
context->audio_time / av_q2d(c->time_base);
49 frame->nb_samples =
context->audio_input_samples;
50 frame->format = c->sample_fmt;
51# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
52 frame->channels = c->channels;
53 frame->channel_layout = c->channel_layout;
54 const int num_channels = c->channels;
56 av_channel_layout_copy(&frame->ch_layout, &c->ch_layout);
57 const int num_channels = c->ch_layout.nb_channels;
60 if (
context->audio_deinterleave) {
64 for (channel = 0; channel < num_channels; channel++) {
65 for (
i = 0;
i < frame->nb_samples;
i++) {
66 memcpy(
context->audio_deinterleave_buffer +
67 (
i + channel * frame->nb_samples) *
context->audio_sample_size,
69 (num_channels *
i + channel) *
context->audio_sample_size,
74 temp =
context->audio_deinterleave_buffer;
76 context->audio_input_buffer = temp;
79 avcodec_fill_audio_frame(frame,
83 context->audio_input_samples * num_channels *
89 char error_str[AV_ERROR_MAX_STRING_SIZE];
90 int ret = avcodec_send_frame(c, frame);
93 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
94 fprintf(stderr,
"Can't send audio frame: %s\n", error_str);
98 AVPacket *pkt = av_packet_alloc();
102 ret = avcodec_receive_packet(c, pkt);
103 if (
ret == AVERROR(EAGAIN) ||
ret == AVERROR_EOF) {
107 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
108 fprintf(stderr,
"Error encoding audio frame: %s\n", error_str);
112 pkt->stream_index =
context->audio_stream->index;
113 av_packet_rescale_ts(pkt, c->time_base,
context->audio_stream->time_base);
114# ifdef FFMPEG_USE_DURATION_WORKAROUND
118 pkt->flags |= AV_PKT_FLAG_KEY;
120 int write_ret = av_interleaved_write_frame(
context->outfile, pkt);
121 if (write_ret != 0) {
122 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
123 fprintf(stderr,
"Error writing audio packet: %s\n", error_str);
129 av_packet_free(&pkt);
130 av_frame_free(&frame);
136bool movie_audio_open(MovieWriter *context,
144# ifdef WITH_AUDASPACE
146 AVCodecContext *c =
context->audio_codec;
148 AUD_DeviceSpecs specs;
149# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
150 specs.channels = AUD_Channels(c->channels);
152 specs.channels = AUD_Channels(c->ch_layout.nb_channels);
155 switch (av_get_packed_sample_fmt(c->sample_fmt)) {
156 case AV_SAMPLE_FMT_U8:
157 specs.format = AUD_FORMAT_U8;
159 case AV_SAMPLE_FMT_S16:
160 specs.format = AUD_FORMAT_S16;
162 case AV_SAMPLE_FMT_S32:
163 specs.format = AUD_FORMAT_S32;
165 case AV_SAMPLE_FMT_FLT:
166 specs.format = AUD_FORMAT_FLOAT32;
168 case AV_SAMPLE_FMT_DBL:
169 specs.format = AUD_FORMAT_FLOAT64;
177 specs.rate = mixrate;
179 context->audio_mixdown_device = BKE_sound_mixdown(scene, specs, start_frame, volume);
188void movie_audio_close(MovieWriter *context,
bool is_autosplit)
190# ifdef WITH_AUDASPACE
192 if (
context->audio_mixdown_device) {
193 AUD_Device_free(
context->audio_mixdown_device);
194 context->audio_mixdown_device =
nullptr;
202AVStream *alloc_audio_stream(MovieWriter *context,
211 const AVCodec *codec;
215 st = avformat_new_stream(of,
nullptr);
221 codec = avcodec_find_encoder(codec_id);
223 fprintf(stderr,
"Couldn't find valid audio codec\n");
224 context->audio_codec =
nullptr;
228 context->audio_codec = avcodec_alloc_context3(codec);
229 AVCodecContext *c =
context->audio_codec;
231 c->thread_type = FF_THREAD_SLICE;
233 c->sample_rate = audio_mixrate;
234 c->bit_rate =
context->ffmpeg_audio_bitrate * 1000;
235 c->sample_fmt = AV_SAMPLE_FMT_S16;
237 int channel_layout_mask = 0;
238 switch (audio_channels) {
240 channel_layout_mask = AV_CH_LAYOUT_MONO;
243 channel_layout_mask = AV_CH_LAYOUT_STEREO;
246 channel_layout_mask = AV_CH_LAYOUT_QUAD;
249 channel_layout_mask = AV_CH_LAYOUT_5POINT1_BACK;
252 channel_layout_mask = AV_CH_LAYOUT_7POINT1;
257# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
258 c->channels = audio_channels;
259 c->channel_layout = channel_layout_mask;
261 av_channel_layout_from_mask(&c->ch_layout, channel_layout_mask);
264 if (request_float_audio_buffer(codec_id)) {
266 c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
267 c->sample_fmt = AV_SAMPLE_FMT_FLT;
277 const enum AVSampleFormat *p = sample_fmts;
278 for (; *p != -1; p++) {
279 if (*p == c->sample_fmt) {
285 c->sample_fmt = sample_fmts[0];
290 if (supported_samplerates) {
291 const int *p = supported_samplerates;
293 int best_dist = INT_MAX;
295 int dist =
abs(c->sample_rate - *p);
296 if (dist < best_dist) {
302 c->sample_rate = best;
305 if (of->oformat->flags & AVFMT_GLOBALHEADER) {
306 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
309 int ret = avcodec_open2(c, codec,
nullptr);
312 char error_str[AV_ERROR_MAX_STRING_SIZE];
313 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
314 fprintf(stderr,
"Couldn't initialize audio codec: %s\n", error_str);
316 avcodec_free_context(&c);
317 context->audio_codec =
nullptr;
323 c->time_base.num = 1;
324 c->time_base.den = c->sample_rate;
326 if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) {
330 context->audio_input_samples = 10000;
333 context->audio_input_samples = c->frame_size;
336 context->audio_deinterleave = av_sample_fmt_is_planar(c->sample_fmt);
338 context->audio_sample_size = av_get_bytes_per_sample(c->sample_fmt);
341 audio_channels *
context->audio_sample_size);
342 if (
context->audio_deinterleave) {
344 context->audio_input_samples * audio_channels *
context->audio_sample_size);
349 avcodec_parameters_from_context(st->codecpar, c);
354void write_audio_frames(MovieWriter *context,
double to_pts)
356# ifdef WITH_AUDASPACE
357 AVCodecContext *c =
context->audio_codec;
359 while (
context->audio_stream) {
360 if ((
context->audio_time_total >= to_pts) || !write_audio_frame(context)) {
363 context->audio_time_total += double(
context->audio_input_samples) / double(c->sample_rate);
364 context->audio_time += double(
context->audio_input_samples) / double(c->sample_rate);
void BKE_report(ReportList *reports, eReportType type, const char *message)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
int BLI_system_thread_count(void)
@ FFM_CHANNELS_SURROUND51
@ FFM_CHANNELS_SURROUND71
FFMPEG_INLINE enum AVSampleFormat * ffmpeg_get_sample_fmts(struct AVCodecContext *context, const AVCodec *codec)
FFMPEG_INLINE const int * ffmpeg_get_sample_rates(struct AVCodecContext *context, const AVCodec *codec)
FFMPEG_INLINE void my_guess_pkt_duration(AVFormatContext *s, AVStream *st, AVPacket *pkt)
static void error(const char *str)
int context(const bContext *C, const char *member, bContextDataResult *result)