fix video/audio synchronization code in theora

This commit is contained in:
Juan Linietsky 2015-11-03 09:30:28 -03:00
parent 61ecb6a5e6
commit eb419bee04
2 changed files with 33 additions and 12 deletions

View file

@ -266,14 +266,14 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
theora_p=1;
}else if(!vorbis_p && vorbis_synthesis_headerin(&vi,&vc,&op)>=0){
/* it is vorbis */
if (audio_track_skip) {
vorbis_info_clear(&vi);
vorbis_comment_clear(&vc);
audio_track_skip--;
} else {
copymem(&vo,&test,sizeof(test));
vorbis_p=1;
}
if (audio_track_skip) {
vorbis_info_clear(&vi);
vorbis_comment_clear(&vc);
audio_track_skip--;
} else {
copymem(&vo,&test,sizeof(test));
vorbis_p=1;
}
}else{
/* whatever it is, we don't care about it */
ogg_stream_clear(&test);
@ -392,6 +392,7 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
fprintf(stderr,"Ogg logical stream %lx is Vorbis %d channel %ld Hz audio.\n",
vo.serialno,vi.channels,vi.rate);
//_setup(vi.channels, vi.rate);
}else{
/* tear down the partial vorbis setup */
vorbis_info_clear(&vi);
@ -401,6 +402,7 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
playing = false;
buffering=true;
time=0;
audio_frames_wrote=0;
};
float VideoStreamPlaybackTheora::get_time() const {
@ -431,8 +433,9 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
return; //no new frames need to be produced
bool frame_done=false;
bool audio_done=false;
while (!frame_done) {
while (!frame_done || !audio_done) {
//a frame needs to be produced
ogg_packet op;
@ -490,6 +493,17 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
audio_pending=true;
if (vd.granulepos>=0) {
// print_line("wrote: "+itos(audio_frames_wrote)+" gpos: "+itos(vd.granulepos));
}
//print_line("mix audio!");
audio_frames_wrote+=ret-to_read;
//print_line("AGP: "+itos(vd.granulepos)+" added "+itos(ret-to_read));
} else {
/* no pending audio; is there a pending packet to decode? */
@ -503,6 +517,9 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
};
}
audio_done = videobuf_time < (audio_frames_wrote/float(vi.rate));
if (buffer_full)
break;
}
@ -567,7 +584,9 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
}
}
#else
if (!frame_done){
if (!frame_done || !audio_done){
//what's the point of waiting for audio to grab a page?
buffer_data();
@ -709,8 +728,9 @@ VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
texture = Ref<ImageTexture>( memnew(ImageTexture ));
mix_callback=NULL;
mix_udata=NULL;
audio_track=0;
audio_track=0;
delay_compensation=0;
audio_frames_wrote=0;
};
VideoStreamPlaybackTheora::~VideoStreamPlaybackTheora() {

View file

@ -32,6 +32,7 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
void video_write(void);
float get_time() const;
ogg_sync_state oy;
ogg_page og;
ogg_stream_state vo;
@ -122,7 +123,7 @@ public:
Ref<VideoStreamPlayback> instance_playback() {
Ref<VideoStreamPlaybackTheora> pb = memnew( VideoStreamPlaybackTheora );
pb->set_audio_track(audio_track);
pb->set_audio_track(audio_track);
pb->set_file(file);
return pb;
}