@@ -535,7 +535,6 @@ static void PrepareDecoder(TheoraDecoder *ctx)
535535// This massive function is where all the effort happens.
536536static int PumpDecoder (TheoraDecoder * ctx , int desired_frames )
537537{
538- int wasted_frames = 0 ;
539538 int had_new_video_frames = 0 ;
540539
541540 if (!ctx -> prepped )
@@ -553,15 +552,10 @@ int wasted_frames = 0;
553552
554553 if (ctx -> current_seek_generation != ctx -> seek_generation ) // seek requested
555554 {
556- unsigned int total_seek_attempts = 0 ;
557- const unsigned long max_keyframe_distance = 1 << ctx -> tinfo .keyframe_granule_shift ; // maximum frames between keyframes.
558- //const unsigned long max_keyframe_ms = (unsigned int) (max_keyframe_distance * (1000.0 / ctx->fps));
559555 unsigned long targetms ;
560- unsigned long targetframe ;
561556 long seekpos ;
562557 long lo , hi ;
563558 int found = 0 ;
564- int seek_only_backwards = 0 ;
565559
566560 if (!ctx -> io -> seek )
567561 goto cleanup ; // seeking unsupported.
@@ -582,8 +576,6 @@ unsigned int total_seek_attempts = 0;
582576 targetms = ctx -> new_seek_position_ms ;
583577 Mutex_Unlock (ctx -> lock );
584578
585- targetframe = targetms * (ctx -> fps / 1000.0 );
586-
587579 lo = 0 ;
588580 hi = ctx -> streamlen ;
589581
@@ -594,7 +586,8 @@ unsigned int total_seek_attempts = 0;
594586
595587 while ((!ctx -> halt ) && (ctx -> current_seek_generation == ctx -> seek_generation ))
596588 {
597- total_seek_attempts ++ ;
589+ //const int max_keyframe_distance = 1 << ctx->tinfo.keyframe_granule_shift;
590+
598591 // Do a binary search through the stream to find our starting point.
599592 // This idea came from libtheoraplayer (no relation to theoraplay).
600593 if (ctx -> io -> seek (ctx -> io , seekpos ) == -1 )
@@ -618,81 +611,46 @@ total_seek_attempts++;
618611 if (ctx -> granulepos >= 0 )
619612 {
620613 const int serialno = ogg_page_serialno (& ctx -> page );
614+ unsigned long ms ;
615+
621616 if (ctx -> tpackets ) // always tee off video frames if possible.
622617 {
623- unsigned long frame , distance ;
624-
625618 if (serialno != ctx -> tserialno )
626619 continue ;
627-
628- frame = (unsigned long ) th_granule_frame (ctx -> tdec , ctx -> granulepos );
629- distance = targetframe - frame ;
630- //printf("frame=%lu targetframe=%lu distance=%lu maxdistance=%lu backwardsonly=%s\n", frame, targetframe, distance, max_keyframe_distance, seek_only_backwards ? "true" : "false");
631- if ((frame < targetframe ) && ((distance >= max_keyframe_distance ) && (distance <= (max_keyframe_distance * 2 ))))
632- found = 1 ; // found something close enough to the target! We'll decode forward through the next keyframe to the actual target.
633- else if (seek_only_backwards && ((frame < targetframe ) && (distance >= max_keyframe_distance )))
634- found = 1 ; // we're at least a keyframe back, if we overshot by two, oh well, good enough.
635- else if (seek_only_backwards || ((frame > targetframe ) && ((frame - targetframe ) < max_keyframe_distance )) || ((frame < targetframe ) && ((distance < max_keyframe_distance ))))
636- {
637- // we're less than a keyframe from the target in either direction, just seek backwards until we
638- // have enough distance to hit a keyframe, since binary searching by byte position will likely fail now.
639- seek_only_backwards = 1 ;
640- }
641- else // adjust binary search position and try again.
642- {
643- const long newpos = (lo / 2 ) + (hi / 2 );
644- if (targetframe > frame )
645- lo = newpos ;
646- else
647- hi = newpos ;
648- } // else
620+ ms = (unsigned long ) (th_granule_time (ctx -> tdec , ctx -> granulepos ) * 1000.0 );
649621 } // else
650622 else
651623 {
652- unsigned long ms ;
653624 if (serialno != ctx -> vserialno )
654625 continue ;
655626 ms = (unsigned long ) (vorbis_granule_time (& ctx -> vdsp , ctx -> granulepos ) * 1000.0 );
656- if ((ms < targetms ) && ((targetms - ms ) >= 500 ) && ((targetms - ms ) <= 1000 )) // !!! FIXME: tweak this number?
657- found = 1 ; // found something close enough to the target!
658- else // adjust binary search position and try again.
659- {
660- const long newpos = (lo / 2 ) + (hi / 2 );
661- if (targetms > ms )
662- lo = newpos ;
663- else
664- hi = newpos ;
665- } // else
666627 } // else
667628
629+ if ((ms < targetms ) && ((targetms - ms ) >= 500 ) && ((targetms - ms ) <= 1000 )) // !!! FIXME: tweak this number?
630+ found = 1 ; // found something close enough to the target!
631+ else // adjust binary search position and try again.
632+ {
633+ const long newpos = (lo / 2 ) + (hi / 2 );
634+ if (targetms > ms )
635+ lo = newpos ;
636+ else
637+ hi = newpos ;
638+ } // else
668639 break ;
669640 } // if
670641 } // while
671642
672643 if (found )
673644 break ;
674645
675- if (seek_only_backwards ) {
676- // the theoretical maximum is 65052 bytes per Ogg page, which is probably larger than most, but skipping back multiple
677- // pages is likely necessary to move back full frames in most videos anyhow, not to mention the interleaved audio packets.
678- const long pageseeksize = 512 * 1024 ;
679- if (seekpos == 0 )
680- break ; // we did the best we could, just go from here.
681- else if (seekpos < pageseeksize )
682- seekpos = 0 ; // last try.
683- else
684- seekpos -= pageseeksize ;
685- } else {
686- const long newseekpos = (lo / 2 ) + (hi / 2 );
687- if (seekpos == newseekpos )
688- break ; // we did the best we could, just go from here.
689- seekpos = newseekpos ;
690- }
646+ const long newseekpos = (lo / 2 ) + (hi / 2 );
647+ if (seekpos == newseekpos )
648+ break ; // we did the best we could, just go from here.
649+ seekpos = newseekpos ;
691650 } // while
692651
693652 // at this point, we have seek'd to something reasonably close to our target. Now decode until we're as close as possible to it.
694653 vorbis_synthesis_restart (& ctx -> vdsp );
695- printf ("Total seek attempts: %d\n" , total_seek_attempts );
696654 ctx -> resolving_audio_seek = ctx -> vpackets ;
697655 ctx -> resolving_video_seek = ctx -> tpackets ;
698656 ctx -> seek_target = targetms ;
@@ -808,14 +766,7 @@ printf("Total seek attempts: %d\n", total_seek_attempts);
808766 ctx -> need_keyframe = 0 ;
809767
810768 if (ctx -> resolving_video_seek && !ctx -> need_keyframe && ((playms >= ctx -> seek_target ) || ((ctx -> seek_target - playms ) <= (unsigned long ) (1000.0 / ctx -> fps ))))
811- {
812- printf ("Resolving video seek at %u playms, frame %llu\n" , playms , (unsigned long long ) th_granule_frame (ctx -> tdec , ctx -> granulepos ));
813- printf ("Wasted %d frames\n" , wasted_frames );
814- wasted_frames = 0 ;
815769 ctx -> resolving_video_seek = 0 ;
816- }
817-
818- if (ctx -> resolving_video_seek ) { wasted_frames ++ ; }
819770
820771 if (!ctx -> resolving_video_seek )
821772 {
0 commit comments