Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.0 / libzmpeg3 / video / seek.C
diff --git a/cinelerra-5.0/libzmpeg3/video/seek.C b/cinelerra-5.0/libzmpeg3/video/seek.C
deleted file mode 100644 (file)
index a869329..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-#include "../libzmpeg3.h"
-
-static void
-toc_error()
-{
-  zerr( "frame accurate seeking without a table of contents \n"
-    "is no longer supported.  Use mpeg3toc <mpeg file> <table of contents>\n"
-    "to generate a table of contents and load the table of contents instead.\n");
-}
-
-void zvideo_t::
-cache_frame()
-{
-  if( output_src[0] ) {
-    int coded_size = coded_picture_width * coded_picture_height;
-    int chrom_size = chrom_width * chrom_height;
-    track->frame_cache->put_frame(framenum-1,
-      output_src[0], output_src[1], output_src[2],
-      coded_size, chrom_size, chrom_size);
-  }
-}
-
-int zvideo_t::
-drop_frames(long frames, int cache_it)
-{
-  int result = 0;
-  long frame_number = framenum + frames;
-//zmsgs("drop frames framenum %d frames %ld\n", framenum, frames);
-
-/* Read the selected number of frames and skip b-frames */
-  while(!result && frame_number > framenum ) {
-    if( cache_it ) {
-      result = read_frame_backend(0);
-      if( !result && ref_frames > 1 )
-        cache_frame();
-    }
-    else {
-//zmsgs("framenum %d frame_offset "_LX" last_packet_start "_LX" repeat %d/%d",
-//  framenum,track->frame_offsets[framenum+1],vstream->demuxer->last_packet_start,
-//  repeat_fields, current_field);
-      result = read_frame_backend(frame_number - framenum);
-//zmsgs(" type %c\n","XIPBD"[pict_type]);
-    }
-  }
-
-  return result;
-}
-
-int zbits_t::
-next_start_code()
-{
-//zmsg("1\n");
-  /* search forwards */
-  prev_byte_align();
-  int64_t stream_end = demuxer->stream_end;
-  if( demuxer->src->is_transport_stream() )
-    demuxer->stream_end = demuxer->program_byte + MAX_TS_PROBE;
-  else if( demuxer->src->is_program_stream() )
-    demuxer->stream_end = demuxer->program_byte + MAX_PGM_PROBE;
-  int zcode = -1, result = -1;
-
-  while( !eof() ) {
-    int bits = (uint8_t)zcode!=0 ? 24 : 8;
-    zcode = (zcode<<bits) | get_bits_noptr(bits);
-    if( (zcode&0xffffff) == PACKET_START_CODE_PREFIX ) {
-      zcode = (zcode<<8) + get_byte_noptr();
-      reset(result = zcode);
-//zmsgs("5 %04x\n",zcode);
-      break;
-    }
-  }
-
-  demuxer->stream_end = stream_end;
-  return result;
-}
-
-/* Line up on the beginning of the next code. */
-int zbits_t::
-next_code(uint32_t zcode)
-{
-  while(!eof() && show_bits_noptr(32) != zcode ) {
-    get_byte_noptr();
-  }
-  return eof();
-}
-
-/* Line up on the beginning of the previous code. */
-int zdemuxer_t::
-prev_code(uint32_t zcode)
-{
-  uint32_t current_code = 0;
-#define PREV_CODE_MACRO { current_code >>= 8; \
-  current_code |= ((uint32_t)read_prev_char()) << 24; }
-
-  PREV_CODE_MACRO
-  PREV_CODE_MACRO
-  PREV_CODE_MACRO
-  PREV_CODE_MACRO
-
-  while( !bof() && current_code != zcode ) {
-    PREV_CODE_MACRO
-  }
-  return bof();
-}
-
-int zvideo_t::
-seek_byte(int64_t byte)
-{
-  byte_seek = byte;
-  return 0;
-}
-
-int zvideo_t::
-seek_frame(long frame)
-{
-  frame_seek = frame;
-  return 0;
-}
-
-int zvideo_t::
-rewind_video(int preload)
-{
-  vstream->reset();
-  framenum = 0;
-  if( track->frame_offsets )
-    vstream->seek_byte(track->frame_offsets[0]);
-  else
-    vstream->seek_byte(0);
-  track->reset_pts();
-  repeat_data = ref_frames = 0;
-  last_number = framenum = -1;
-  return preload ? read_frame_backend(0) : 0;
-}
-
-int zvideo_t::
-seek()
-{
-  int result = 0;
-  int64_t byte;
-  long frame_number;
-  int debug = 0;
-  demuxer_t *demux = vstream->demuxer;
-
-/* Must do seeking here so files which don't use video don't seek. */
-/* Seeking is done in the demuxer */
-/* Seek to absolute byte */
-  if( byte_seek >= 0 ) {
-    byte = byte_seek;
-    byte_seek = -1;
-    if( byte != demux->tell_byte() ) {
-      demux->seek_byte(byte);
-      track->reset_pts();
-      if( byte > 0 ) {
-  //zmsg("1\n");
-        demux->start_reverse();
-  //zmsgs("1 "_LD"\n", demux->tell_byte());
-        for( int i=0; i<2; ++i ) {     /* Rewind 2 I-frames */
-          if( has_gops ?
-            demux->prev_code(GOP_START_CODE) :
-            demux->prev_code(SEQUENCE_START_CODE) ) break;
-        }
-  //zmsgs("2 "_LD"\n", demux->tell_byte());
-        demux->start_forward();
-        if( track->frame_offsets ) {
-          int64_t offset = demux->tell_byte();
-          for( int k=0; k<track->total_keyframe_numbers; ++k ) {
-            frame_number = track->keyframe_numbers[k];
-            if( track->frame_offsets[frame_number] >= offset ) {
-              /* first entry is special */
-              framenum = frame_number>0 ? frame_number-1 : 0;
-              break;
-            }
-          }
-        }
-        else {
-          /* framenum no longer accurate, clear subtitles */
-          reset_subtitles();
-        }
-      }
-      else { /* Read first frame */
-        rewind_video();
-      }
-      vstream->reset();
-      repeat_data = ref_frames = 0;
-  //zmsgs("4 "_LD"\n", demux->tell_byte());
-      while( !result && !demux->eof() && demux->tell_byte() < byte ) {
-        result = read_frame_backend(0);
-      }
-    }
-  }
-  else if( frame_seek >= 0 ) {
-    /* Seek to a frame number */
-    frame_number = frame_seek;
-    frame_seek = -1;
-    if( frame_number != framenum ) {
-      if( debug ) zmsgs("%d\n", __LINE__);
-      if( frame_number < 0 ) frame_number = 0;
-      if( frame_number > maxframe ) frame_number = maxframe;
-      if(debug) zmsgs("%d %ld %d\n", __LINE__, frame_number, framenum);
-      /* Seek to I frame in table of contents. */
-      /* Determine time between seek position and previous subtitle. */
-      /* Subtract time difference from subtitle display time. */
-      if( frame_number > 0 && track->frame_offsets ) {
-        if( debug ) zmsgs("%d\n", __LINE__);
-        track->frame_cache->reset();
-        if( debug ) zmsgs("%d\n", __LINE__);
-        if( frame_number < framenum || 
-            frame_number-framenum > SEEK_THRESHOLD ) {
-          int idx = track->find_keyframe_index(frame_number);
-          /* back up 2 I frames, data may reference old refframes */
-          if( --idx < 0 ) idx = 0;
-          idx = track->keyframe_numbers[idx];
-          byte = track->frame_offsets[idx];
-          /* maybe lots of frames in one block, move is to earliest frame */
-          while( idx > 0 && track->frame_offsets[idx-1] == byte ) --idx;
-          if( debug ) zmsgs("%ld idx=%d, byte="_LD"\n", frame_number,idx,byte);
-          framenum = idx-1;
-          vstream->seek_byte(byte);
-          track->reset_pts();
-          repeat_data = ref_frames = 0;
-          /* get the first I-frame.  It does not count in the frame sequence */
-          /*   phys order is IBBPBBPBB... presentation order is BBIBBPBB... */
-          result = read_frame_backend(0);
-        }
-        if( debug ) zmsgs("%d %ld %d\n", __LINE__,frame_number,framenum);
-        if( !result && frame_number > framenum ) {
-          /* Read up to current frame */
-          int n = frame_number - framenum;
-          result = drop_frames(n, n < MAX_CACHE_FRAMES ? 1 : 0);
-          if( debug ) zmsgs("%d\n", __LINE__);
-        }
-      }
-      else if( frame_number == 0 ) {
-        result = rewind_video();
-      }
-      else {
-        /* No support for seeking without table of contents */
-        toc_error();
-        result = 1;
-      }
-    }
-  }
-  else if( framenum < 0 ) {   /* preload */
-    result = rewind_video(1);
-  }
-  else
-    return 0;
-
-  seek_time = 0;
-  return result;
-}
-
-int zvideo_t::
-previous_frame()
-{
-  int result = 0;
-  int64_t target_byte = 0;
-  demuxer_t *demux = vstream->demuxer;
-  if( demux->tell_byte() <= 0 ) return 1;
-  /* Get location of end of previous picture */
-  demux->start_reverse();
-  result = demux->prev_code(PICTURE_START_CODE);
-  if( !result ) result = demux->prev_code(PICTURE_START_CODE);
-  if( !result ) result = demux->prev_code(PICTURE_START_CODE);
-  if( !result ) target_byte = demux->tell_byte();
-  if( !result ) { /* Rewind 2 I-frames */
-    if( has_gops )
-      result = demux->prev_code(GOP_START_CODE);
-    else
-      result = demux->prev_code(SEQUENCE_START_CODE);
-  }
-
-  if( !result )
-  {
-    if( has_gops )
-      result = demux->prev_code(GOP_START_CODE);
-    else
-      result = demux->prev_code(SEQUENCE_START_CODE);
-  }
-
-  demux->start_forward();
-  vstream->reset();
-
-  result = 0;    /* Read up to correct byte */
-  repeat_data = ref_frames = 0;
-  while( !result && !demux->eof() && demux->tell_byte() < target_byte ) {
-    result = read_frame_backend(0);
-  }
-  repeat_data = 0;
-
-  return 0;
-}
-