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
path: root/source
diff options
context:
space:
mode:
authorSebastian Parborg <darkdefende@gmail.com>2021-07-06 20:48:06 +0300
committerSebastian Parborg <darkdefende@gmail.com>2021-08-16 16:10:58 +0300
commitded68fb10275c9f9a66e7019171b83cab0e9485d (patch)
tree8a7d8ad343433070b79f6bceec92871c564da1ec /source
parent6df81ddb84c60876ac3ebd87d1d134109f34eabd (diff)
VSE: Fix audaspace not reading ffmpeg files with start offset correctly
The duration and start time for audio strips were not correctly read in audaspace. Some video files have a "lead in" section of audio that plays before the video starts playing back. Before this patch, we would play this lead in audio at the same time as the video started and thus the audio would not be in sync anymore. Now the lead in audio is cut off and the duration should be correctly calculated with this in mind. If the audio starts after the video, the audio strip is shifted to account for this, but it will also lead to cut off audio which might not be wanted. However we don't have a simple way to solve this at this point. Differential Revision: http://developer.blender.org/D11917
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_sound.h9
-rw-r--r--source/blender/blenkernel/intern/sound.c12
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c16
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c10
-rw-r--r--source/blender/imbuf/IMB_imbuf.h5
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h1
-rw-r--r--source/blender/imbuf/intern/anim_movie.c27
-rw-r--r--source/blender/makesdna/DNA_sound_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c5
-rw-r--r--source/blender/sequencer/SEQ_add.h6
-rw-r--r--source/blender/sequencer/intern/sound.c7
-rw-r--r--source/blender/sequencer/intern/strip_add.c46
-rw-r--r--source/blender/sequencer/intern/strip_time.c4
13 files changed, 113 insertions, 36 deletions
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 57ce33a239f..4b257b3b8ab 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -97,6 +97,7 @@ typedef struct SoundInfo {
eSoundChannels channels;
} specs;
float length;
+ double start_offset;
} SoundInfo;
/* Get information about given sound. Returns truth on success., false if sound can not be loaded
@@ -139,8 +140,12 @@ void BKE_sound_remove_scene_sound(struct Scene *scene, void *handle);
void BKE_sound_mute_scene_sound(void *handle, char mute);
-void BKE_sound_move_scene_sound(
- struct Scene *scene, void *handle, int startframe, int endframe, int frameskip);
+void BKE_sound_move_scene_sound(struct Scene *scene,
+ void *handle,
+ int startframe,
+ int endframe,
+ int frameskip,
+ double audio_offset);
void BKE_sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence);
void BKE_sound_update_scene_sound(void *handle, struct bSound *sound);
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index fcb992e1535..9d287377545 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -709,7 +709,7 @@ void *BKE_sound_scene_add_scene_sound(
sequence->scene->sound_scene,
startframe / fps,
endframe / fps,
- frameskip / fps);
+ frameskip / fps + sequence->sound->offset_time);
}
return NULL;
}
@@ -737,7 +737,7 @@ void *BKE_sound_add_scene_sound(
sequence->sound->playback_handle,
startframe / fps,
endframe / fps,
- frameskip / fps);
+ frameskip / fps + sequence->sound->offset_time);
AUD_SequenceEntry_setMuted(handle, (sequence->flag & SEQ_MUTE) != 0);
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_VOLUME, CFRA, &sequence->volume, 0);
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_PITCH, CFRA, &sequence->pitch, 0);
@@ -765,11 +765,11 @@ void BKE_sound_mute_scene_sound(void *handle, char mute)
}
void BKE_sound_move_scene_sound(
- Scene *scene, void *handle, int startframe, int endframe, int frameskip)
+ Scene *scene, void *handle, int startframe, int endframe, int frameskip, double audio_offset)
{
sound_verify_evaluated_id(&scene->id);
const double fps = FPS;
- AUD_SequenceEntry_move(handle, startframe / fps, endframe / fps, frameskip / fps);
+ AUD_SequenceEntry_move(handle, startframe / fps, endframe / fps, frameskip / fps + audio_offset);
}
void BKE_sound_move_scene_sound_defaults(Scene *scene, Sequence *sequence)
@@ -780,7 +780,8 @@ void BKE_sound_move_scene_sound_defaults(Scene *scene, Sequence *sequence)
sequence->scene_sound,
sequence->startdisp,
sequence->enddisp,
- sequence->startofs + sequence->anim_startofs);
+ sequence->startofs + sequence->anim_startofs,
+ sequence->sound->offset_time);
}
}
@@ -1213,6 +1214,7 @@ static bool sound_info_from_playback_handle(void *playback_handle, SoundInfo *so
AUD_SoundInfo info = AUD_getInfo(playback_handle);
sound_info->specs.channels = (eSoundChannels)info.specs.channels;
sound_info->length = info.length;
+ sound_info->start_offset = info.start_offset;
return true;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 47495eaa57a..ff8cbdb1a59 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -643,15 +643,17 @@ static void sequencer_add_movie_multiple_strips(bContext *C,
BLI_strncpy(load_data->name, file_only, sizeof(load_data->name));
Sequence *seq_movie = NULL;
Sequence *seq_sound = NULL;
+ double video_start_offset;
+
load_data->channel++;
- seq_movie = SEQ_add_movie_strip(bmain, scene, ed->seqbasep, load_data);
+ seq_movie = SEQ_add_movie_strip(bmain, scene, ed->seqbasep, load_data, &video_start_offset);
load_data->channel--;
if (seq_movie == NULL) {
BKE_reportf(op->reports, RPT_ERROR, "File '%s' could not be loaded", load_data->path);
}
else {
if (RNA_boolean_get(op->ptr, "sound")) {
- seq_sound = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data);
+ seq_sound = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data, video_start_offset);
}
load_data->start_frame += seq_movie->enddisp - seq_movie->startdisp;
seq_load_apply_generic_options(C, op, seq_sound);
@@ -670,8 +672,10 @@ static bool sequencer_add_movie_single_strip(bContext *C, wmOperator *op, SeqLoa
Sequence *seq_movie = NULL;
Sequence *seq_sound = NULL;
+ double video_start_offset;
+
load_data->channel++;
- seq_movie = SEQ_add_movie_strip(bmain, scene, ed->seqbasep, load_data);
+ seq_movie = SEQ_add_movie_strip(bmain, scene, ed->seqbasep, load_data, &video_start_offset);
load_data->channel--;
if (seq_movie == NULL) {
@@ -679,7 +683,7 @@ static bool sequencer_add_movie_single_strip(bContext *C, wmOperator *op, SeqLoa
return false;
}
if (RNA_boolean_get(op->ptr, "sound")) {
- seq_sound = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data);
+ seq_sound = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data, video_start_offset);
}
seq_load_apply_generic_options(C, op, seq_sound);
seq_load_apply_generic_options(C, op, seq_movie);
@@ -822,7 +826,7 @@ static void sequencer_add_sound_multiple_strips(bContext *C,
RNA_string_get(&itemptr, "name", file_only);
BLI_join_dirfile(load_data->path, sizeof(load_data->path), dir_only, file_only);
BLI_strncpy(load_data->name, file_only, sizeof(load_data->name));
- Sequence *seq = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data);
+ Sequence *seq = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data, 0.0f);
if (seq == NULL) {
BKE_reportf(op->reports, RPT_ERROR, "File '%s' could not be loaded", load_data->path);
}
@@ -840,7 +844,7 @@ static bool sequencer_add_sound_single_strip(bContext *C, wmOperator *op, SeqLoa
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene, true);
- Sequence *seq = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data);
+ Sequence *seq = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data, 0.0f);
if (seq == NULL) {
BKE_reportf(op->reports, RPT_ERROR, "File '%s' could not be loaded", load_data->path);
return false;
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 0472e1264ce..e49a88c88d2 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -284,10 +284,12 @@ static void draw_seq_waveform_overlay(View2D *v2d,
return;
}
- startsample = floor((seq->startofs + seq->anim_startofs) / FPS *
- SOUND_WAVE_SAMPLES_PER_SECOND);
- endsample = ceil((seq->startofs + seq->anim_startofs + seq->enddisp - seq->startdisp) / FPS *
- SOUND_WAVE_SAMPLES_PER_SECOND);
+ startsample = (seq->startofs + seq->anim_startofs) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND;
+ startsample += seq->sound->offset_time * SOUND_WAVE_SAMPLES_PER_SECOND;
+
+ endsample = (seq->enddisp - seq->startdisp) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND;
+ endsample += startsample;
+
samplestep = (endsample - startsample) * stepsize / (x2 - x1);
length = min_ii(
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index d527aca184c..4ad7aa98484 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -367,6 +367,11 @@ void IMB_anim_index_rebuild_finish(struct IndexBuildContext *context, short stop
int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc);
/**
+ * Return the encoded start offset (in seconds) of the given \a anim.
+ */
+double IMD_anim_get_offset(struct anim *anim);
+
+/**
* Return the fps contained in movie files (function rval is false,
* and frs_sec and frs_sec_base untouched if none available!)
*/
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h
index cfeffcca0ea..c4e2ad9da7f 100644
--- a/source/blender/imbuf/intern/IMB_anim.h
+++ b/source/blender/imbuf/intern/IMB_anim.h
@@ -91,6 +91,7 @@ struct anim {
int duration_in_frames;
int frs_sec;
double frs_sec_base;
+ double start_offset;
int x, y;
/* for number */
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index fd96110b59e..2998c4781b6 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -425,6 +425,7 @@ static int startavi(struct anim *anim)
}
anim->duration_in_frames = anim->avi->header->TotalFrames;
+ anim->start_offset = 0.0f;
anim->params = NULL;
anim->x = anim->avi->header->Width;
@@ -597,6 +598,13 @@ static int startffmpeg(struct anim *anim)
return -1;
}
+ double video_start = 0;
+ double pts_time_base = av_q2d(video_stream->time_base);
+
+ if (video_stream->start_time != AV_NOPTS_VALUE) {
+ video_start = video_stream->start_time * pts_time_base;
+ }
+
frame_rate = av_guess_frame_rate(pFormatCtx, video_stream, NULL);
anim->duration_in_frames = 0;
@@ -620,20 +628,14 @@ static int startffmpeg(struct anim *anim)
* This is because the video stream duration can be shorter than the pFormatCtx->duration.
*/
if (anim->duration_in_frames == 0) {
- double pts_time_base = av_q2d(video_stream->time_base);
double stream_dur;
if (video_stream->duration != AV_NOPTS_VALUE) {
stream_dur = video_stream->duration * pts_time_base;
}
else {
- double video_start = 0;
double audio_start = 0;
- if (video_stream->start_time != AV_NOPTS_VALUE) {
- video_start = video_stream->start_time * pts_time_base;
- }
-
/* Find audio stream to guess the duration of the video.
* Sometimes the audio AND the video stream have a start offset.
* The difference between these is the offset we want to use to
@@ -662,6 +664,11 @@ static int startffmpeg(struct anim *anim)
anim->duration_in_frames = (int)(stream_dur * av_q2d(frame_rate) + 0.5f);
}
+ double ctx_start = 0;
+ if (pFormatCtx->start_time != AV_NOPTS_VALUE) {
+ ctx_start = (double)pFormatCtx->start_time / AV_TIME_BASE;
+ }
+
frs_num = frame_rate.num;
frs_den = frame_rate.den;
@@ -674,6 +681,9 @@ static int startffmpeg(struct anim *anim)
anim->frs_sec = frs_num;
anim->frs_sec_base = frs_den;
+ /* Save the relative start time for the video. IE the start time in relation to where playback
+ * starts. */
+ anim->start_offset = video_start - ctx_start;
anim->params = 0;
@@ -1672,6 +1682,11 @@ int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc)
return IMB_indexer_get_duration(idx);
}
+double IMD_anim_get_offset(struct anim *anim)
+{
+ return anim->start_offset;
+}
+
bool IMB_anim_get_fps(struct anim *anim, short *frs_sec, float *frs_sec_base, bool no_av_base)
{
double frs_sec_base_double;
diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h
index b2bb50c56a2..e6394f0a56a 100644
--- a/source/blender/makesdna/DNA_sound_types.h
+++ b/source/blender/makesdna/DNA_sound_types.h
@@ -67,6 +67,7 @@ typedef struct bSound {
/** Runtime only, always reset in readfile. */
short tags;
char _pad[4];
+ double offset_time;
/* Unused currently. */
// int type;
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 4895ab11618..264ccccd350 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -310,7 +310,8 @@ static Sequence *rna_Sequences_new_movie(ID *id,
SEQ_add_load_data_init(&load_data, name, file, frame_start, channel);
load_data.fit_method = fit_method;
load_data.allow_invalid_file = true;
- Sequence *seq = SEQ_add_movie_strip(bmain, scene, seqbase, &load_data);
+ double video_start_offset;
+ Sequence *seq = SEQ_add_movie_strip(bmain, scene, seqbase, &load_data, &video_start_offset);
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
@@ -359,7 +360,7 @@ static Sequence *rna_Sequences_new_sound(ID *id,
SeqLoadData load_data;
SEQ_add_load_data_init(&load_data, name, file, frame_start, channel);
load_data.allow_invalid_file = true;
- Sequence *seq = SEQ_add_sound_strip(bmain, scene, seqbase, &load_data);
+ Sequence *seq = SEQ_add_sound_strip(bmain, scene, seqbase, &load_data, 0.0f);
if (seq == NULL) {
BKE_report(reports, RPT_ERROR, "Sequences.new_sound: unable to open sound file");
diff --git a/source/blender/sequencer/SEQ_add.h b/source/blender/sequencer/SEQ_add.h
index 2941eb6f4c0..4025f1a4a04 100644
--- a/source/blender/sequencer/SEQ_add.h
+++ b/source/blender/sequencer/SEQ_add.h
@@ -79,14 +79,16 @@ struct Sequence *SEQ_add_image_strip(struct Main *bmain,
struct Sequence *SEQ_add_sound_strip(struct Main *bmain,
struct Scene *scene,
struct ListBase *seqbase,
- struct SeqLoadData *load_data);
+ struct SeqLoadData *load_data,
+ const double audio_offset);
struct Sequence *SEQ_add_meta_strip(struct Scene *scene,
struct ListBase *seqbase,
struct SeqLoadData *load_data);
struct Sequence *SEQ_add_movie_strip(struct Main *bmain,
struct Scene *scene,
struct ListBase *seqbase,
- struct SeqLoadData *load_data);
+ struct SeqLoadData *load_data,
+ double *r_video_start_offset);
struct Sequence *SEQ_add_scene_strip(struct Scene *scene,
struct ListBase *seqbase,
struct SeqLoadData *load_data);
diff --git a/source/blender/sequencer/intern/sound.c b/source/blender/sequencer/intern/sound.c
index 1054dbeeba6..c53aacddcfe 100644
--- a/source/blender/sequencer/intern/sound.c
+++ b/source/blender/sequencer/intern/sound.c
@@ -111,7 +111,12 @@ void SEQ_sound_update_bounds(Scene *scene, Sequence *seq)
/* We have to take into account start frame of the sequence's scene! */
int startofs = seq->startofs + seq->anim_startofs + seq->scene->r.sfra;
- BKE_sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, startofs);
+ BKE_sound_move_scene_sound(scene,
+ seq->scene_sound,
+ seq->startdisp,
+ seq->enddisp,
+ startofs,
+ seq->sound->offset_time);
}
}
else {
diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c
index dab5593be37..cc70cc38ebb 100644
--- a/source/blender/sequencer/intern/strip_add.c
+++ b/source/blender/sequencer/intern/strip_add.c
@@ -382,9 +382,14 @@ Sequence *SEQ_add_image_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL
* \return created strip
*/
-Sequence *SEQ_add_sound_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqLoadData *load_data)
+Sequence *SEQ_add_sound_strip(Main *bmain,
+ Scene *scene,
+ ListBase *seqbase,
+ SeqLoadData *load_data,
+ const double audio_offset)
{
bSound *sound = BKE_sound_new_file(bmain, load_data->path); /* Handles relative paths. */
+ sound->offset_time = audio_offset;
SoundInfo info;
bool sound_loaded = BKE_sound_info_get(bmain, sound, &info);
@@ -398,14 +403,36 @@ Sequence *SEQ_add_sound_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL
return NULL;
}
- Sequence *seq = SEQ_sequence_alloc(
- seqbase, load_data->start_frame, load_data->channel, SEQ_TYPE_SOUND_RAM);
+ /* If this sound it part of a video, then the sound might start after the video.
+ * In this case we need to then offset the start frame of the audio so it syncs up
+ * properly with the video.
+ */
+ int start_frame_offset = info.start_offset * FPS;
+ double start_frame_offset_remainer = (info.start_offset * FPS - start_frame_offset) / FPS;
+
+ if (start_frame_offset_remainer > FLT_EPSILON) {
+ /* We can't represent a fraction of a frame, so skip the first frame fraction of sound so we
+ * start on a "whole" frame.
+ */
+ start_frame_offset++;
+ }
+
+ sound->offset_time += start_frame_offset_remainer;
+
+ Sequence *seq = SEQ_sequence_alloc(seqbase,
+ load_data->start_frame + start_frame_offset,
+ load_data->channel,
+ SEQ_TYPE_SOUND_RAM);
seq->sound = sound;
seq->scene_sound = NULL;
- /* We add a very small negative offset here, because
- * ceil(132.0) == 133.0, not nice with videos, see T47135. */
- seq->len = MAX2(1, (int)ceil((double)info.length * FPS - 1e-4));
+ /* We round the frame duration as the audio sample lenghts usually does not
+ * line up with the video frames. Therefore we round this number to the
+ * nearsest frame as the audio track usually overshoots or undershoots the
+ * end frame ofthe video by a little bit.
+ * See T47135 for under shoot example.
+ */
+ seq->len = MAX2(1, round((info.length - sound->offset_time) * FPS));
Strip *strip = seq->strip;
/* We only need 1 element to store the filename. */
@@ -477,7 +504,11 @@ Sequence *SEQ_add_meta_strip(Scene *scene, ListBase *seqbase, SeqLoadData *load_
* \param load_data: SeqLoadData with information necessary to create strip
* \return created strip
*/
-Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqLoadData *load_data)
+Sequence *SEQ_add_movie_strip(Main *bmain,
+ Scene *scene,
+ ListBase *seqbase,
+ SeqLoadData *load_data,
+ double *r_video_start_offset)
{
char path[sizeof(load_data->path)];
BLI_strncpy(path, load_data->path, sizeof(path));
@@ -552,6 +583,7 @@ Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL
if (anim_arr[0] != NULL) {
seq->len = IMB_anim_get_duration(anim_arr[0], IMB_TC_RECORD_RUN);
+ *r_video_start_offset = IMD_anim_get_offset(anim_arr[0]);
IMB_anim_load_metadata(anim_arr[0]);
diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c
index 68128690773..b73ac631693 100644
--- a/source/blender/sequencer/intern/strip_time.c
+++ b/source/blender/sequencer/intern/strip_time.c
@@ -34,6 +34,7 @@
#include "BKE_scene.h"
#include "BKE_sound.h"
+#include "DNA_sound_types.h"
#include "IMB_imbuf.h"
#include "SEQ_iterator.h"
@@ -134,7 +135,8 @@ static void seq_update_sound_bounds_recursive_impl(Scene *scene,
seq->scene_sound,
seq->start + startofs,
seq->start + seq->len - endofs,
- startofs + seq->anim_startofs);
+ startofs + seq->anim_startofs,
+ seq->sound->offset_time);
}
}
}