diff options
-rw-r--r-- | intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp | 32 | ||||
-rw-r--r-- | intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h | 10 | ||||
-rw-r--r-- | source/blender/editors/sound/sound_ops.c | 18 |
3 files changed, 44 insertions, 16 deletions
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp index d8f0d837fec..859227a5006 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp @@ -187,14 +187,18 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs, m_frame = av_frame_alloc(); if (!m_frame) AUD_THROW(AUD_ERROR_FFMPEG, codec_error); + avcodec_get_frame_defaults(m_frame); m_frame->linesize[0] = m_input_size * samplesize; m_frame->format = m_codecCtx->sample_fmt; + m_frame->nb_samples = m_codecCtx->frame_size; # ifdef FFMPEG_HAVE_AVFRAME_SAMPLE_RATE m_frame->sample_rate = m_codecCtx->sample_rate; # endif # ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT m_frame->channel_layout = m_codecCtx->channel_layout; # endif + m_audio_sample_size = av_get_bytes_per_sample(m_codecCtx->sample_fmt); + m_frame_pts = 0; #endif try @@ -272,13 +276,20 @@ void AUD_FFMPEGWriter::encode(sample_t* data) #ifdef FFMPEG_HAVE_ENCODE_AUDIO2 int got_output, ret; + m_frame->pts = m_frame_pts / av_q2d(m_codecCtx->time_base); + m_frame_pts++; +#ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT + m_frame->channel_layout = m_codecCtx->channel_layout; +#endif + + avcodec_fill_audio_frame(m_frame, m_codecCtx->channels, m_codecCtx->sample_fmt, reinterpret_cast<uint8_t*>(data), + m_frame->nb_samples * av_get_bytes_per_sample(m_codecCtx->sample_fmt) * m_codecCtx->channels, 1); - m_frame->data[0] = reinterpret_cast<uint8_t*>(data); ret = avcodec_encode_audio2(m_codecCtx, &packet, m_frame, &got_output); - if (ret < 0) + if(ret < 0) AUD_THROW(AUD_ERROR_FFMPEG, codec_error); - if (!got_output) + if(!got_output) return; #else sample_t* outbuf = m_output_buffer.getBuffer(); @@ -290,10 +301,23 @@ void AUD_FFMPEGWriter::encode(sample_t* data) packet.data = reinterpret_cast<uint8_t*>(outbuf); #endif + if(packet.pts != AV_NOPTS_VALUE) + packet.pts = av_rescale_q(packet.pts, m_codecCtx->time_base, m_stream->time_base); + if(packet.dts != AV_NOPTS_VALUE) + packet.dts = av_rescale_q(packet.dts, m_codecCtx->time_base, m_stream->time_base); + if(packet.duration > 0) + packet.duration = av_rescale_q(packet.duration, m_codecCtx->time_base, m_stream->time_base); + packet.stream_index = m_stream->index; - if(av_interleaved_write_frame(m_formatCtx, &packet)) + packet.flags |= AV_PKT_FLAG_KEY; + + if(av_interleaved_write_frame(m_formatCtx, &packet)) { + av_free_packet(&packet); AUD_THROW(AUD_ERROR_FFMPEG, write_error); + } + + av_free_packet(&packet); } void AUD_FFMPEGWriter::write(unsigned int length, sample_t* buffer) diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h index 310f69258ea..743d885fca8 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h @@ -83,6 +83,16 @@ private: AVFrame *m_frame; /** + * PTS of next frame to write. + */ + int m_frame_pts; + + /** + * Number of bytes per sample. + */ + int m_audio_sample_size; + + /** * The input buffer for the format converted data before encoding. */ AUD_Buffer m_input_buffer; diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 168693db60b..1979379032f 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -476,12 +476,6 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op) {0, NULL, 0, NULL, NULL} }; - static EnumPropertyItem ac3_format_items[] = { - {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"}, - {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"}, - {0, NULL, 0, NULL, NULL} - }; - #ifdef WITH_SNDFILE static EnumPropertyItem flac_format_items[] = { {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"}, @@ -527,10 +521,9 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op) switch (container) { case AUD_CONTAINER_AC3: - RNA_def_property_clear_flag(prop_format, PROP_HIDDEN); - RNA_def_property_enum_items(prop_format, ac3_format_items); RNA_def_property_enum_items(prop_codec, all_codec_items); RNA_enum_set(op->ptr, "codec", AUD_CODEC_AC3); + RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32); break; case AUD_CONTAINER_FLAC: RNA_def_property_flag(prop_bitrate, PROP_HIDDEN); @@ -539,9 +532,8 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op) #ifdef WITH_SNDFILE RNA_def_property_clear_flag(prop_format, PROP_HIDDEN); RNA_def_property_enum_items(prop_format, flac_format_items); -#else - RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16); #endif + RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16); break; case AUD_CONTAINER_MATROSKA: RNA_def_property_clear_flag(prop_codec, PROP_HIDDEN); @@ -552,8 +544,7 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op) RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16); break; case AUD_CODEC_AC3: - RNA_def_property_enum_items(prop_format, ac3_format_items); - RNA_def_property_clear_flag(prop_format, PROP_HIDDEN); + RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32); break; case AUD_CODEC_FLAC: RNA_def_property_flag(prop_bitrate, PROP_HIDDEN); @@ -565,6 +556,7 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op) case AUD_CODEC_MP3: RNA_def_property_enum_items(prop_format, mp3_format_items); RNA_def_property_clear_flag(prop_format, PROP_HIDDEN); + RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16); break; case AUD_CODEC_PCM: RNA_def_property_flag(prop_bitrate, PROP_HIDDEN); @@ -589,11 +581,13 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op) RNA_def_property_enum_items(prop_format, mp3_format_items); RNA_def_property_enum_items(prop_codec, all_codec_items); RNA_enum_set(op->ptr, "codec", AUD_CODEC_MP3); + RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16); break; case AUD_CONTAINER_OGG: RNA_def_property_clear_flag(prop_codec, PROP_HIDDEN); RNA_def_property_enum_items(prop_codec, ogg_codec_items); RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16); + RNA_enum_set(op->ptr, "codec", AUD_CODEC_VORBIS); break; case AUD_CONTAINER_WAV: RNA_def_property_flag(prop_bitrate, PROP_HIDDEN); |