Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Parborg <darkdefende@gmail.com>2021-07-05 15:16:02 +0300
committerJeroen Bakker <jeroen@blender.org>2021-08-25 16:43:01 +0300
commit85c08c9717b104e1b537476604b6a0fa8e58e477 (patch)
treec392bf56278b57e52cecc3a95072ebc6b0c84a27
parentf53cdbdd2781e7c07a0c8e5da2e88d245de88921 (diff)
VSE: Flush audio encode after finishing video export
We didn't flush audio after encoding finished which lead to audio packets being lost. In addition to this the audio timestamps were wrong because we incremented the current audio time before using it. Reviewed By: Richard Antalik Differential Revision: http://developer.blender.org/D11916
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 5ab9bdcbee6..2474c43c3e8 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -148,7 +148,6 @@ static int write_audio_frame(FFMpegContext *context)
AUD_Device_read(
context->audio_mixdown_device, context->audio_input_buffer, context->audio_input_samples);
- context->audio_time += (double)context->audio_input_samples / (double)c->sample_rate;
frame = av_frame_alloc();
frame->pts = context->audio_time / av_q2d(c->time_base);
@@ -183,7 +182,7 @@ static int write_audio_frame(FFMpegContext *context)
context->audio_input_samples * c->channels * context->audio_sample_size,
1);
- int success = 0;
+ int success = 1;
int ret = avcodec_send_frame(c, frame);
if (ret < 0) {
@@ -368,7 +367,7 @@ static int write_video_frame(FFMpegContext *context, int cfra, AVFrame *frame, R
return success;
}
-/* read and encode a frame of audio from the buffer */
+/* read and encode a frame of video from the buffer */
static AVFrame *generate_video_frame(FFMpegContext *context, const uint8_t *pixels)
{
AVCodecParameters *codec = context->video_stream->codecpar;
@@ -1220,9 +1219,8 @@ fail:
* parameter.
* </p>
*/
-static void flush_ffmpeg(FFMpegContext *context)
+static void flush_ffmpeg(AVCodecContext *c, AVStream *stream, AVFormatContext *outfile)
{
- AVCodecContext *c = context->video_codec;
AVPacket *packet = av_packet_alloc();
avcodec_send_frame(c, NULL);
@@ -1241,13 +1239,13 @@ static void flush_ffmpeg(FFMpegContext *context)
break;
}
- packet->stream_index = context->video_stream->index;
- av_packet_rescale_ts(packet, c->time_base, context->video_stream->time_base);
+ packet->stream_index = stream->index;
+ av_packet_rescale_ts(packet, c->time_base, stream->time_base);
# ifdef FFMPEG_USE_DURATION_WORKAROUND
- my_guess_pkt_duration(context->outfile, context->video_stream, packet);
+ my_guess_pkt_duration(context->outfile, stream, packet);
# endif
- int write_ret = av_interleaved_write_frame(context->outfile, packet);
+ int write_ret = av_interleaved_write_frame(outfile, packet);
if (write_ret != 0) {
fprintf(stderr, "Error writing delayed frame: %s\n", av_err2str(write_ret));
break;
@@ -1390,12 +1388,13 @@ static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit);
# ifdef WITH_AUDASPACE
static void write_audio_frames(FFMpegContext *context, double to_pts)
{
- int finished = 0;
+ AVCodecContext *c = context->audio_codec;
- while (context->audio_stream && !finished) {
- if ((context->audio_time >= to_pts) || (write_audio_frame(context))) {
- finished = 1;
+ while (context->audio_stream) {
+ if ((context->audio_time >= to_pts) || !write_audio_frame(context)) {
+ break;
}
+ context->audio_time += (double)context->audio_input_samples / (double)c->sample_rate;
}
}
# endif
@@ -1416,9 +1415,6 @@ int BKE_ffmpeg_append(void *context_v,
PRINT("Writing frame %i, render width=%d, render height=%d\n", frame, rectx, recty);
- /* why is this done before writing the video frame and again at end_ffmpeg? */
- // write_audio_frames(frame / (((double)rd->frs_sec) / rd->frs_sec_base));
-
if (context->video_stream) {
avframe = generate_video_frame(context, (unsigned char *)pixels);
success = (avframe && write_video_frame(context, frame - start_frame, avframe, reports));
@@ -1454,8 +1450,13 @@ static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit)
# endif
if (context->video_stream) {
- PRINT("Flushing delayed frames...\n");
- flush_ffmpeg(context);
+ PRINT("Flushing delayed video frames...\n");
+ flush_ffmpeg(context->video_codec, context->video_stream, context->outfile);
+ }
+
+ if (context->audio_stream) {
+ PRINT("Flushing delayed audio frames...\n");
+ flush_ffmpeg(context->audio_codec, context->audio_stream, context->outfile);
}
if (context->outfile) {