Mercurial > mplayer.hg
comparison mencoder.c @ 15831:1d2b2c0d7e89
-don't encode more audio than needed; -edl_skip is int, not short; -don't read audio_data to skip in mux_a->buffer; -edl_seek works on input streams, not output; -one-frame accuracy fix ; patch by Oded Shimon
author | nicodvb |
---|---|
date | Mon, 27 Jun 2005 19:10:11 +0000 |
parents | 9b4bbb6098f6 |
children | da752f91c5f2 |
comparison
equal
deleted
inserted
replaced
15830:d2b045f3261d | 15831:1d2b2c0d7e89 |
---|---|
237 static edl_record_ptr edl_records = NULL; ///< EDL entries memory area | 237 static edl_record_ptr edl_records = NULL; ///< EDL entries memory area |
238 static edl_record_ptr next_edl_record = NULL; ///< only for traversing edl_records | 238 static edl_record_ptr next_edl_record = NULL; ///< only for traversing edl_records |
239 static short edl_muted; ///< Stores whether EDL is currently in muted mode. | 239 static short edl_muted; ///< Stores whether EDL is currently in muted mode. |
240 static short edl_seeking; ///< When non-zero, stream is seekable. | 240 static short edl_seeking; ///< When non-zero, stream is seekable. |
241 static short edl_seek_type; ///< When non-zero, frames are discarded instead of seeking. | 241 static short edl_seek_type; ///< When non-zero, frames are discarded instead of seeking. |
242 static short edl_skip; ///< -1 OR the value of in_size of an already read frame. | 242 static int edl_skip; ///< -1 OR the value of in_size of an already read frame. |
243 /** \brief Seeks for EDL | 243 /** \brief Seeks for EDL |
244 \return 1 for success, 0 for failure, 2 for EOF. | 244 \return 1 for success, 0 for failure, 2 for EOF. |
245 */ | 245 */ |
246 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); | 246 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); |
247 #endif | 247 #endif |
1043 mp_msg(MSGT_CPLAYER, MSGL_DBG4, "EDL_SKIP: start [%f], stop [%f], length [%f]\n", | 1043 mp_msg(MSGT_CPLAYER, MSGL_DBG4, "EDL_SKIP: start [%f], stop [%f], length [%f]\n", |
1044 next_edl_record->start_sec, next_edl_record->stop_sec, next_edl_record->length_sec); | 1044 next_edl_record->start_sec, next_edl_record->stop_sec, next_edl_record->length_sec); |
1045 | 1045 |
1046 result = edl_seek(next_edl_record, demuxer, d_audio, mux_a, &frame_time, &start, mux_v->codec==VCODEC_COPY); | 1046 result = edl_seek(next_edl_record, demuxer, d_audio, mux_a, &frame_time, &start, mux_v->codec==VCODEC_COPY); |
1047 | 1047 |
1048 if (result == 2) break; // EOF | 1048 if (result == 2) { at_eof=1; break; } // EOF |
1049 else if (result == 0) edl_seeking = 0; // no seeking | 1049 else if (result == 0) edl_seeking = 0; // no seeking |
1050 else { // sucess | 1050 else { // sucess |
1051 edl_muted = 0; | 1051 edl_muted = 0; |
1052 if (last_pos >= sh_video->pts) { | 1052 if (last_pos >= sh_video->pts) { |
1053 // backwards seek detected!! Forget about this EDL skip altogether. | 1053 // backwards seek detected!! Forget about this EDL skip altogether. |
1089 tottime -= mux_a->timer; | 1089 tottime -= mux_a->timer; |
1090 if (tottime > 1./audio_density) tottime = 1./audio_density; | 1090 if (tottime > 1./audio_density) tottime = 1./audio_density; |
1091 } | 1091 } |
1092 else tottime = 1./audio_density; | 1092 else tottime = 1./audio_density; |
1093 | 1093 |
1094 // let's not output more audio than necessary | |
1095 if (tottime <= 0) break; | |
1094 | 1096 |
1095 if(aencoder) | 1097 if(aencoder) |
1096 { | 1098 { |
1097 if(mux_a->h.dwSampleSize) /* CBR */ | 1099 if(mux_a->h.dwSampleSize) /* CBR */ |
1098 { | 1100 { |
1167 | 1169 |
1168 | 1170 |
1169 audiosamples++; | 1171 audiosamples++; |
1170 audiorate+= (GetTimerMS() - ptimer_start); | 1172 audiorate+= (GetTimerMS() - ptimer_start); |
1171 | 1173 |
1172 // let's not output more audio than necessary | |
1173 if (stop_time(demuxer, mux_v) != -1 && stop_time(demuxer, mux_v) <= mux_a->timer) break; | |
1174 } | 1174 } |
1175 } | 1175 } |
1176 | 1176 |
1177 // get video frame! | 1177 // get video frame! |
1178 | 1178 |
1590 #ifdef USE_EDL | 1590 #ifdef USE_EDL |
1591 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) { | 1591 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) { |
1592 sh_audio_t * sh_audio = d_audio->sh; | 1592 sh_audio_t * sh_audio = d_audio->sh; |
1593 sh_video_t * sh_video = demuxer->video ? demuxer->video->sh : NULL; | 1593 sh_video_t * sh_video = demuxer->video ? demuxer->video->sh : NULL; |
1594 vf_instance_t * vfilter = sh_video ? sh_video->vfilter : NULL; | 1594 vf_instance_t * vfilter = sh_video ? sh_video->vfilter : NULL; |
1595 int done = 0; | |
1596 int samplesize, avg; | |
1595 | 1597 |
1596 if (!sh_video) return 0; | 1598 if (!sh_video) return 0; |
1597 if (sh_video->pts >= next_edl_record->stop_sec) return 1; // nothing to do... | 1599 if (sh_video->pts >= next_edl_record->stop_sec) return 1; // nothing to do... |
1598 | 1600 |
1599 if (!edl_seek_type) { | 1601 if (!edl_seek_type) { |
1608 return 0; | 1610 return 0; |
1609 } | 1611 } |
1610 | 1612 |
1611 // slow seek, read every frame. | 1613 // slow seek, read every frame. |
1612 | 1614 |
1615 if (sh_audio->audio.dwScale) samplesize = sh_audio->audio.dwSampleSize; | |
1616 else samplesize = (sh_audio->wf ? sh_audio->wf->nBlockAlign : 1); | |
1617 avg = (sh_audio->wf ? sh_audio->wf->nAvgBytesPerSec : sh_audio->i_bps); | |
1618 | |
1613 while (!interrupted) { | 1619 while (!interrupted) { |
1614 float a_pts = 0.; | 1620 float a_pts = 0.; |
1615 int in_size; | 1621 int in_size; |
1616 | 1622 |
1617 in_size = video_read_frame(sh_video, frame_time, start, force_fps); | 1623 in_size = video_read_frame(sh_video, frame_time, start, force_fps); |
1618 if(in_size<0) return 2; | 1624 if(in_size<0) return 2; |
1619 sh_video->timer += *frame_time; | 1625 sh_video->timer += *frame_time; |
1620 | 1626 |
1621 if (sh_audio) { | 1627 if (sh_audio) { |
1622 a_pts = d_audio->pts + (ds_tell_pts(d_audio) - sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; | 1628 a_pts = d_audio->pts + (ds_tell_pts(d_audio) - sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; |
1623 while (sh_video->pts > a_pts) { | 1629 while (sh_video->pts - *frame_time > a_pts) { |
1624 int len; | 1630 int len; |
1625 if (mux_a->h.dwSampleSize) { | 1631 if (samplesize) { |
1626 len = mux_a->wf->nAvgBytesPerSec * (sh_video->pts - a_pts); | 1632 len = avg * (sh_video->pts - a_pts - *frame_time); |
1627 len/= mux_a->h.dwSampleSize; if(len<1) len=1; | 1633 len/= samplesize; if(len<1) len=1; |
1628 len*= mux_a->h.dwSampleSize; | 1634 len*= samplesize; |
1629 len = demux_read_data(sh_audio->ds,mux_a->buffer,len); | 1635 len = demux_read_data(sh_audio->ds,mux_a->buffer,len); |
1630 } else { | 1636 } else { |
1631 len = ds_get_packet(sh_audio->ds,(unsigned char**) &mux_a->buffer); | 1637 unsigned char * crap; |
1638 len = ds_get_packet(sh_audio->ds, &crap); | |
1632 } | 1639 } |
1633 if (len <= 0) break; // EOF of audio. | 1640 if (len <= 0) break; // EOF of audio. |
1634 a_pts = d_audio->pts + (ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; | 1641 a_pts = d_audio->pts + (ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; |
1635 } | 1642 } |
1636 } | 1643 } |
1637 | 1644 |
1638 if (sh_video->pts >= next_edl_record->stop_sec) { | 1645 if (done) { |
1639 edl_skip = in_size; | 1646 edl_skip = in_size; |
1640 if (!framecopy || (sh_video->ds->flags & 1)) return 1; | 1647 if (!framecopy || (sh_video->ds->flags & 1)) return 1; |
1641 } | 1648 } |
1649 if (sh_video->pts >= next_edl_record->stop_sec) done = 1; | |
1642 | 1650 |
1643 if (vfilter) { | 1651 if (vfilter) { |
1644 int softskip = (vfilter->control(vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) == CONTROL_TRUE); | 1652 int softskip = (vfilter->control(vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) == CONTROL_TRUE); |
1645 decode_video(sh_video, *start, in_size, !softskip); | 1653 decode_video(sh_video, *start, in_size, !softskip); |
1646 } | 1654 } |