mirror of
https://github.com/mpv-player/mpv
synced 2025-01-02 21:12:23 +00:00
-delay for MEncoder, final step 6.
TODO: make it encode silence instead of cutting video as cutting video is unreliable with -ovc copy. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@15998 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
e805f50a76
commit
efee32de2b
@ -910,6 +910,13 @@ and skip reading from default locations.
|
||||
The file is assumed to be in Netscape format.
|
||||
.
|
||||
.TP
|
||||
.B \-delay <sec>
|
||||
audio delay in seconds (positive or negative float value)
|
||||
.I NOTE:
|
||||
When used with MEncoder, this is not guaranteed to work correctly
|
||||
with \-ovc copy.
|
||||
.
|
||||
.TP
|
||||
.B \-demuxer <number>
|
||||
Force demuxer type.
|
||||
Give the demuxer ID as defined in libmpdemux/\:demuxer.h.
|
||||
@ -1747,10 +1754,6 @@ Specify the VOBsub subtitle ID.
|
||||
Override audio driver/\:card buffer size detection.
|
||||
.
|
||||
.TP
|
||||
.B \-delay <sec>
|
||||
Audio delay in seconds (positive or negative float value).
|
||||
.
|
||||
.TP
|
||||
.B \-format <format> (also see the format audio filter)
|
||||
Select the sample format used for output from the audio filter
|
||||
layer to the sound card.
|
||||
|
@ -146,6 +146,9 @@
|
||||
{"format", &audio_output_format, CONF_TYPE_AFMT, 0, 0, 0, NULL},
|
||||
{"speed", &playback_speed, CONF_TYPE_FLOAT, CONF_RANGE, 0.01, 100.0, NULL},
|
||||
|
||||
// set a-v distance
|
||||
{"delay", &audio_delay, CONF_TYPE_FLOAT, CONF_RANGE, -100.0, 100.0, NULL},
|
||||
|
||||
#ifdef USE_LIBA52
|
||||
{"a52drc", &a52_drc_level, CONF_TYPE_FLOAT, CONF_RANGE, 0, 1, NULL},
|
||||
#endif
|
||||
|
@ -318,9 +318,6 @@ m_option_t mplayer_opts[]={
|
||||
|
||||
{"sstep", &step_sec, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL},
|
||||
|
||||
// set a-v distance, should be moved to -common and supported in MEncoder
|
||||
{"delay", &audio_delay, CONF_TYPE_FLOAT, CONF_RANGE, -100.0, 100.0, NULL},
|
||||
|
||||
{"framedrop", &frame_dropping, CONF_TYPE_FLAG, 0, 0, 1, NULL},
|
||||
{"hardframedrop", &frame_dropping, CONF_TYPE_FLAG, 0, 0, 2, NULL},
|
||||
{"noframedrop", &frame_dropping, CONF_TYPE_FLAG, 0, 1, 0, NULL},
|
||||
|
39
mencoder.c
39
mencoder.c
@ -147,6 +147,7 @@ static float c_total=0;
|
||||
|
||||
static float audio_preload=0.5;
|
||||
static float audio_delay_fix=0.0;
|
||||
static float audio_delay=0.0;
|
||||
static int audio_density=2;
|
||||
|
||||
float force_fps=0;
|
||||
@ -250,6 +251,8 @@ static float forward_audio(float pts, demux_stream_t *d_audio, muxer_stream_t* m
|
||||
\return 1 for success, 2 for EOF.
|
||||
*/
|
||||
static int slowseek(float end_pts, demux_stream_t *d_video, demux_stream_t *d_audio, muxer_stream_t* mux_a, s_frame_data * frame_data, int framecopy, int print_info);
|
||||
/// Deletes audio or video as told by -delay to sync
|
||||
static void fixdelay(demux_stream_t *d_video, demux_stream_t *d_audio, muxer_stream_t* mux_a, s_frame_data * frame_data, int framecopy);
|
||||
|
||||
#ifdef USE_EDL
|
||||
#include "edl.h"
|
||||
@ -1046,6 +1049,8 @@ if (edl_filename) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sh_audio && audio_delay != 0.) fixdelay(d_video, d_audio, mux_a, &frame_data, mux_v->codec==VCODEC_COPY);
|
||||
|
||||
while(!at_eof){
|
||||
|
||||
int blit_frame=0;
|
||||
@ -1346,6 +1351,7 @@ if(sh_audio && !demuxer2){
|
||||
v_pts=sh_video ? sh_video->pts : d_video->pts;
|
||||
// av = compensated (with out buffering delay) A-V diff
|
||||
AV_delay=(a_pts-v_pts);
|
||||
AV_delay-=audio_delay;
|
||||
AV_delay /= playback_speed;
|
||||
AV_delay-=mux_a->timer-(mux_v->timer-(v_timer_corr+v_pts_corr));
|
||||
// compensate input video timer by av:
|
||||
@ -1637,6 +1643,13 @@ static float forward_audio(float pts, demux_stream_t *d_audio, muxer_stream_t* m
|
||||
else samplesize = (sh_audio->wf ? sh_audio->wf->nBlockAlign : 1);
|
||||
avg = (sh_audio->wf ? sh_audio->wf->nAvgBytesPerSec : sh_audio->i_bps);
|
||||
|
||||
// after a demux_seek, a_pts will be zero until you read some audio.
|
||||
// carefully checking if a_pts is truely correct by reading tiniest amount of data possible.
|
||||
if (pts > a_pts && a_pts == 0.0 && samplesize) {
|
||||
if (demux_read_data(sh_audio->ds,mux_a->buffer,samplesize) <= 0) return a_pts; // EOF
|
||||
a_pts = calc_a_pts(d_audio);
|
||||
}
|
||||
|
||||
while (pts > a_pts) {
|
||||
int len;
|
||||
if (samplesize) {
|
||||
@ -1666,7 +1679,7 @@ static int slowseek(float end_pts, demux_stream_t *d_video, demux_stream_t *d_au
|
||||
if(frame_data->in_size<0) return 2;
|
||||
sh_video->timer += frame_data->frame_time;
|
||||
|
||||
a_pts = forward_audio(sh_video->pts - frame_data->frame_time, d_audio, mux_a);
|
||||
a_pts = forward_audio(sh_video->pts - frame_data->frame_time + audio_delay, d_audio, mux_a);
|
||||
|
||||
if (done) {
|
||||
frame_data->already_read = 1;
|
||||
@ -1688,6 +1701,29 @@ static int slowseek(float end_pts, demux_stream_t *d_video, demux_stream_t *d_au
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void fixdelay(demux_stream_t *d_video, demux_stream_t *d_audio, muxer_stream_t* mux_a, s_frame_data * frame_data, int framecopy) {
|
||||
// TODO: Find a way to encode silence instead of deleting video
|
||||
sh_video_t * sh_video = d_video->sh;
|
||||
vf_instance_t * vfilter = sh_video ? sh_video->vfilter : NULL;
|
||||
int done = 0;
|
||||
float a_pts;
|
||||
|
||||
// demux_seek has a weirdness that sh_video->pts is meaningless,
|
||||
// until a single frame is read... Same for audio actually too.
|
||||
// Reading one frame, and keeping it.
|
||||
frame_data->in_size = video_read_frame(sh_video, &frame_data->frame_time, &frame_data->start, force_fps);
|
||||
if(frame_data->in_size<0) return;
|
||||
sh_video->timer += frame_data->frame_time;
|
||||
frame_data->already_read = 1;
|
||||
|
||||
a_pts = forward_audio(sh_video->pts - frame_data->frame_time + audio_delay, d_audio, mux_a);
|
||||
|
||||
if (audio_delay > 0) return;
|
||||
else if (sh_video->pts - frame_data->frame_time + audio_delay >= a_pts) return;
|
||||
|
||||
slowseek(a_pts - audio_delay, d_video, d_audio, mux_a, frame_data, framecopy, 0);
|
||||
}
|
||||
|
||||
#ifdef USE_EDL
|
||||
static int edl_seek(edl_record_ptr next_edl_record, demuxer_t* demuxer, demux_stream_t *d_audio, muxer_stream_t* mux_a, s_frame_data * frame_data, int framecopy) {
|
||||
sh_video_t * sh_video = demuxer->video ? demuxer->video->sh : NULL;
|
||||
@ -1701,6 +1737,7 @@ static int edl_seek(edl_record_ptr next_edl_record, demuxer_t* demuxer, demux_st
|
||||
//if (vo_vobsub) vobsub_seek(vo_vobsub,sh_video->pts);
|
||||
resync_video_stream(sh_video);
|
||||
//if(vo_spudec) spudec_reset(vo_spudec);
|
||||
if (audio_delay != 0.0) fixdelay(demuxer->video, d_audio, mux_a, frame_data, framecopy);
|
||||
return 1;
|
||||
}
|
||||
// non-seekable stream.
|
||||
|
Loading…
Reference in New Issue
Block a user