[MPlayer-dev-eng] [PATCH] Preparing for -delay for MEncoder
Oded Shimon
ods15 at ods15.dyndns.org
Fri Jul 8 15:13:57 CEST 2005
Trying to build a -delay for MEncoder, made a patch here That doesn't
change MEncoder's behavior at all, as preparation for -delay, to prevent
the next patch being much larger/more complicated.
Works for me..
If no-one objects, I'll commit tommorrow.
- ods15
-------------- next part --------------
Index: cfg-mencoder.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfg-mencoder.h,v
retrieving revision 1.101
diff -u -r1.101 cfg-mencoder.h
--- cfg-mencoder.h 2 Jul 2005 19:00:12 -0000 1.101
+++ cfg-mencoder.h 8 Jul 2005 13:07:50 -0000
@@ -220,7 +220,7 @@
{"audio-density", &audio_density, CONF_TYPE_INT, CONF_RANGE|CONF_GLOBAL, 1, 50, NULL},
{"audio-preload", &audio_preload, CONF_TYPE_FLOAT, CONF_RANGE|CONF_GLOBAL, 0, 2, NULL},
- {"audio-delay", &audio_delay, CONF_TYPE_FLOAT, CONF_MIN|CONF_GLOBAL, 0, 0, NULL},
+ {"audio-delay", &audio_delay_fix, CONF_TYPE_FLOAT, CONF_MIN|CONF_GLOBAL, 0, 0, NULL},
{"x", "-x is obsolete, use -vf scale=w:h for scaling.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
{"xsize", "-xsize is obsolete, use -vf crop=w:h:x:y for cropping.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
Index: mencoder.c
===================================================================
RCS file: /cvsroot/mplayer/main/mencoder.c,v
retrieving revision 1.292
diff -u -r1.292 mencoder.c
--- mencoder.c 3 Jul 2005 10:09:09 -0000 1.292
+++ mencoder.c 8 Jul 2005 13:07:51 -0000
@@ -146,7 +146,7 @@
static float c_total=0;
static float audio_preload=0.5;
-static float audio_delay=0.0;
+static float audio_delay_fix=0.0;
static int audio_density=2;
float force_fps=0;
@@ -233,6 +233,18 @@
static char * end_at_string=0;
//static uint8_t* flip_upside_down(uint8_t* dst, const uint8_t* src, int width, int height);
+typedef struct {
+ unsigned char* start;
+ int in_size;
+ float frame_time;
+ int already_read;
+} s_frame_data;
+
+/** \brief Seeks audio forward to pts by dumping audio packets
+ \return The current audio pts.
+*/
+static float forward_audio(float pts, demux_stream_t *d_audio, muxer_stream_t* mux_a);
+
#ifdef USE_EDL
#include "edl.h"
static edl_record_ptr edl_records = NULL; ///< EDL entries memory area
@@ -240,11 +252,10 @@
static short edl_muted; ///< Stores whether EDL is currently in muted mode.
static short edl_seeking; ///< When non-zero, stream is seekable.
static short edl_seek_type; ///< When non-zero, frames are discarded instead of seeking.
-static int edl_skip; ///< -1 OR the value of in_size of an already read frame.
/** \brief Seeks for EDL
\return 1 for success, 0 for failure, 2 for EOF.
*/
-int edl_seek(edl_record_ptr next_edl_record, demuxer_t* demuxer, demux_stream_t *d_audio, muxer_stream_t* mux_a, float * frame_time, unsigned char ** start, int framecopy);
+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);
#endif
#include "cfg-mplayer-def.h"
@@ -342,6 +353,7 @@
int file_format=DEMUXER_TYPE_UNKNOWN;
int i=DEMUXER_TYPE_UNKNOWN;
void *vobsub_writer=NULL;
+s_frame_data frame_data = { .start = NULL, .in_size = 0, .frame_time = 0., .already_read = 0 };
uint32_t ptimer_start;
uint32_t audiorate=0;
@@ -898,8 +910,8 @@
if (verbose>1) print_wave_header(mux_a->wf);
-if(audio_delay!=0.0){
- mux_a->h.dwStart=audio_delay*mux_a->h.dwRate/mux_a->h.dwScale;
+if(audio_delay_fix!=0.0){
+ mux_a->h.dwStart=audio_delay_fix*mux_a->h.dwRate/mux_a->h.dwScale;
mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_SettingAudioDelay,mux_a->h.dwStart*mux_a->h.dwScale/(float)mux_a->h.dwRate);
}
if(muxer->fix_stream_parameters)
@@ -1023,7 +1035,6 @@
next_edl_record = edl_records = NULL;
edl_muted = 0;
edl_seeking = 1;
-edl_skip = -1;
if (edl_filename) {
next_edl_record = edl_records = edl_parse_file();
}
@@ -1031,12 +1042,9 @@
while(!at_eof){
- float frame_time=0;
int blit_frame=0;
float a_pts=0;
float v_pts=0;
- unsigned char* start=NULL;
- int in_size;
int skip_flag=0; // 1=skip -1=duplicate
if((end_at_type == END_AT_SIZE && end_at <= ftello(muxer_f)) ||
@@ -1057,7 +1065,7 @@
mp_msg(MSGT_CPLAYER, MSGL_DBG4, "EDL_SKIP: start [%f], stop [%f], length [%f]\n",
next_edl_record->start_sec, next_edl_record->stop_sec, next_edl_record->length_sec);
- result = edl_seek(next_edl_record, demuxer, d_audio, mux_a, &frame_time, &start, mux_v->codec==VCODEC_COPY);
+ result = edl_seek(next_edl_record, demuxer, d_audio, mux_a, &frame_data, mux_v->codec==VCODEC_COPY);
if (result == 2) { at_eof=1; break; } // EOF
else if (result == 0) edl_seeking = 0; // no seeking
@@ -1190,16 +1198,15 @@
// get video frame!
-#ifdef USE_EDL
- if (edl_skip != -1) { in_size = edl_skip; edl_skip = -1; }
- else
-#endif
- in_size=video_read_frame(sh_video,&frame_time,&start,force_fps);
- if(in_size<0){ at_eof=1; break; }
- sh_video->timer+=frame_time; ++decoded_frameno;
- frame_time /= playback_speed;
+ if (!frame_data.already_read) {
+ frame_data.in_size=video_read_frame(sh_video,&frame_data.frame_time,&frame_data.start,force_fps);
+ sh_video->timer+=frame_data.frame_time;
+ }
+ frame_data.frame_time /= playback_speed;
+ if(frame_data.in_size<0){ at_eof=1; break; }
+ ++decoded_frameno;
- v_timer_corr-=frame_time-(float)mux_v->h.dwScale/mux_v->h.dwRate;
+ v_timer_corr-=frame_data.frame_time-(float)mux_v->h.dwScale/mux_v->h.dwRate;
if(demuxer2){ // 3-pass encoding, read control file (frameno.avi)
// find our frame:
@@ -1258,8 +1265,8 @@
switch(mux_v->codec){
case VCODEC_COPY:
- mux_v->buffer=start;
- if(skip_flag<=0) muxer_write_chunk(mux_v,in_size,(sh_video->ds->flags&1)?0x10:0);
+ mux_v->buffer=frame_data.start;
+ if(skip_flag<=0) muxer_write_chunk(mux_v,frame_data.in_size,(sh_video->ds->flags&1)?0x10:0);
break;
case VCODEC_FRAMENO:
mux_v->buffer=(unsigned char *)&decoded_frameno; // tricky
@@ -1267,7 +1274,7 @@
break;
default:
// decode_video will callback down to ve_*.c encoders, through the video filters
- blit_frame=decode_video(sh_video,start,in_size,
+ blit_frame=decode_video(sh_video,frame_data.start,frame_data.in_size,
skip_flag>0 && (!sh_video->vfilter || ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) != CONTROL_TRUE));
if (sh_video->vf_inited < 0) mencoder_exit(1, NULL);
@@ -1441,6 +1448,8 @@
}
#endif
+ frame_data = (s_frame_data){ .start = NULL, .in_size = 0, .frame_time = 0., .already_read = 0 };
+
if(ferror(muxer_f)) {
mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ErrorWritingFile, out_filename);
mencoder_exit(1, NULL);
@@ -1603,9 +1612,37 @@
return timeleft;
}
+static float forward_audio(float pts, demux_stream_t *d_audio, muxer_stream_t* mux_a) {
+ sh_audio_t * sh_audio = d_audio ? d_audio->sh : NULL;
+ int samplesize, avg;
+ float a_pts = 0.;
+
+ if (!sh_audio) return a_pts;
+
+ if (sh_audio->audio.dwScale) samplesize = sh_audio->audio.dwSampleSize;
+ else samplesize = (sh_audio->wf ? sh_audio->wf->nBlockAlign : 1);
+ avg = (sh_audio->wf ? sh_audio->wf->nAvgBytesPerSec : sh_audio->i_bps);
+
+ a_pts = d_audio->pts + (ds_tell_pts(d_audio) - sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
+ while (pts > a_pts) {
+ int len;
+ if (samplesize) {
+ len = avg * (pts - a_pts > 0.5 ? 0.5 : pts - a_pts);
+ len/= samplesize; if(len<1) len=1;
+ len*= samplesize;
+ len = demux_read_data(sh_audio->ds,mux_a->buffer,len);
+ } else {
+ unsigned char * crap;
+ len = ds_get_packet(sh_audio->ds, &crap);
+ }
+ if (len <= 0) break; // EOF of audio.
+ a_pts = d_audio->pts + (ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
+ }
+ return a_pts;
+}
+
#ifdef USE_EDL
-int edl_seek(edl_record_ptr next_edl_record, demuxer_t* demuxer, demux_stream_t *d_audio, muxer_stream_t* mux_a, float * frame_time, unsigned char ** start, int framecopy) {
- sh_audio_t * sh_audio = d_audio->sh;
+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;
vf_instance_t * vfilter = sh_video ? sh_video->vfilter : NULL;
int done = 0;
@@ -1628,45 +1665,24 @@
// slow seek, read every frame.
- if (sh_audio->audio.dwScale) samplesize = sh_audio->audio.dwSampleSize;
- else samplesize = (sh_audio->wf ? sh_audio->wf->nBlockAlign : 1);
- avg = (sh_audio->wf ? sh_audio->wf->nAvgBytesPerSec : sh_audio->i_bps);
-
while (!interrupted) {
- float a_pts = 0.;
- int in_size;
+ float a_pts;
- in_size = video_read_frame(sh_video, frame_time, start, force_fps);
- if(in_size<0) return 2;
- sh_video->timer += *frame_time;
-
- if (sh_audio) {
- a_pts = d_audio->pts + (ds_tell_pts(d_audio) - sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
- while (sh_video->pts - *frame_time > a_pts) {
- int len;
- if (samplesize) {
- len = avg * (sh_video->pts - a_pts - *frame_time);
- len/= samplesize; if(len<1) len=1;
- len*= samplesize;
- len = demux_read_data(sh_audio->ds,mux_a->buffer,len);
- } else {
- unsigned char * crap;
- len = ds_get_packet(sh_audio->ds, &crap);
- }
- if (len <= 0) break; // EOF of audio.
- a_pts = d_audio->pts + (ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
- }
- }
+ 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 2;
+ sh_video->timer += frame_data->frame_time;
+
+ a_pts = forward_audio(sh_video->pts - frame_data->frame_time, d_audio, mux_a);
if (done) {
- edl_skip = in_size;
+ frame_data->already_read = 1;
if (!framecopy || (sh_video->ds->flags & 1)) return 1;
}
if (sh_video->pts >= next_edl_record->stop_sec) done = 1;
if (vfilter) {
int softskip = (vfilter->control(vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) == CONTROL_TRUE);
- decode_video(sh_video, *start, in_size, !softskip);
+ decode_video(sh_video, frame_data->start, frame_data->in_size, !softskip);
}
mp_msg(MSGT_MENCODER, MSGL_STATUS,
More information about the MPlayer-dev-eng
mailing list