Ejemplo n.º 1
0
/* fas_seek_to_frame */
fas_error_type fas_seek_to_frame (fas_context_ref_type context, int target_index)
{

  fas_error_type fas_error;

  if ((NULL == context) || (FAS_FALSE == context->is_video_active))
    return private_show_error("invalid or unopened context", FAS_INVALID_ARGUMENT);

  //  printf("seeking to %d (from %d)!\n", target_index, context->current_frame_index);
  if (target_index == context->current_frame_index)
    return FAS_SUCCESS;

  fas_error = fas_seek_to_nearest_key (context, target_index);

  if (fas_error != FAS_SUCCESS)
    return private_show_error("error advancing to key frame before seek", fas_error);

  if (fas_get_frame_index(context) > target_index)
    return private_show_error("error advancing to key frame before seek (index isn't right)", fas_error);

  while (fas_get_frame_index(context) < target_index)
    {
      if (fas_frame_available(context))
	fas_step_forward(context);
      else
	return private_show_error("error advancing to request frame (probably out of range)", FAS_SEEK_ERROR);
    }


  return FAS_SUCCESS;
}
Ejemplo n.º 2
0
int fas_get_frame_count (fas_context_ref_type context)
{
  int current_frame;
  int fast;
  fas_error_type fas_error;

  fast = fas_get_frame_count_fast(context);
  if (fast >= 0)
    return fast;

  current_frame = fas_get_frame_index(context);


  fas_error = private_complete_seek_table(context);
  if (FAS_SUCCESS != fas_error)
  {
    private_show_error("failed in get_frame_count trying to complete the seek table", fas_error);
    return -1;
  }

  //  seek_show_raw_table(stderr, context->seek_table);

  fas_error = fas_seek_to_frame(context, current_frame);
  if (FAS_SUCCESS != fas_error)
  {
    private_show_error("failed in get_frame_count when trying to seek back to original location", fas_error);
    return -1;
  }

  fast = fas_get_frame_count_fast(context);
  if (fast < 0)
    private_show_warning("get_frame_count failed");

  return fast;
}
Ejemplo n.º 3
0
int main (int argc, char **argv)
{
  char * out_dir;
  char out_file[128];
  int i;
  seek_table_type table;
  fas_error_type video_error;
  fas_context_ref_type context, seek_context;

  cmdname = argv[0];

  if (argc < 3) {
    show_help();
    fail("arguments\n");
  }

  table = read_table_file(argv[2]);
  if (table.num_entries == 0)
    fail("bad table\n");

  fas_initialize (FAS_FALSE, FAS_RGB24);

  video_error = fas_open_video (&context, argv[1]);
  if (video_error != FAS_SUCCESS)    fail("fail on open\n");

  video_error = fas_put_seek_table(context, table);
  if (video_error != FAS_SUCCESS)    fail("fail on put_seek_table\n");

  video_error = fas_open_video (&seek_context, argv[1]);
  if (video_error != FAS_SUCCESS)    fail("fail on open\n");


  if (argc >= 4) {
    out_dir = argv[3];
    create_dir(out_dir);
  } else {
    out_dir = ".";
  }

  for(i=0;i<table.num_entries;i++)
    {
      fas_raw_image_type image_buffer;
      //      int frame_index = table.array[table.num_entries - i - 1].display_index;
      int frame_index = table.array[i].display_index;
      if (FAS_SUCCESS != fas_seek_to_frame(context, frame_index))
	fail("failed on seek");

      if (FAS_SUCCESS != fas_get_frame (context, &image_buffer))
	fail("failed on rgb image\n");

      sprintf(out_file, "%s/frame_%04d.ppm", out_dir, frame_index);

      fprintf(stderr, "Writing %s (seek_table_value=%d frame_index=%d)\n", out_file, frame_index, fas_get_frame_index(context));
      ppm_save(&image_buffer, out_file);

      fas_free_frame (image_buffer);
    }

  success();
}
Ejemplo n.º 4
0
/* fas_step_forward */
fas_error_type fas_step_forward (fas_context_ref_type context)
{
  AVPacket packet;
  int frameFinished;


  if ((NULL == context) || (FAS_TRUE != context->is_video_active)) {
    return private_show_error("invalid or unopened context", FAS_INVALID_ARGUMENT);
  }

  if (!context->is_frame_available)
    {
      private_show_warning ("tried to advance after end of frames");
      return FAS_SUCCESS;
    }

  context->current_frame_index++;

  while (FAS_TRUE)
    {
      if (av_read_frame(context->format_context, &packet) < 0)
	{
	  /* finished */
	  context->is_frame_available = FAS_FALSE;
	  context->seek_table.completed = seek_true;
	  return FAS_SUCCESS;
	}

      if (packet.stream_index == context->stream_idx)
	{
	  context->previous_dts = context->current_dts;
	  context->current_dts = packet.dts;

	  /* seek support: set first_dts */
	  if (context->first_dts == AV_NOPTS_VALUE)
	    context->first_dts = packet.dts;

	  /* seek support: set key-packet info to previous packet's dts, when possible */
	  /* note this -1 approach to setting the packet is a workaround for a common failure. setting
	     to 0 would work just incur a huge penalty in videos that needed -1. Might be worth testing.
	  */
	  if (packet.flags & AV_PKT_FLAG_KEY)
	    {
	      //fprintf(stderr, "Packet: (F:%d %lld %lld)\n", context->current_frame_index, packet.pts, packet.dts);

	      if (context->previous_dts == AV_NOPTS_VALUE)
		context->keyframe_packet_dts = packet.dts;
	      else
		context->keyframe_packet_dts = context->previous_dts;
	    }

	  avcodec_decode_video2(context->codec_context, context->frame_buffer, &frameFinished, &packet);

	  if (frameFinished)
	    {
	      /* seek support: (try to) add entry to seek_table */
	      if (context->frame_buffer->key_frame)
		{
		  //		fprintf(stderr, "Frame : (PXX F%d: %lld %lld)\n", context->current_frame_index, packet.pts, packet.dts);

		  seek_entry_type entry;
		  entry.display_index = context->current_frame_index;
		  entry.first_packet_dts = context->keyframe_packet_dts;
		  entry.last_packet_dts = packet.dts;

		  if (fas_get_frame_index(context) == FIRST_FRAME_INDEX)
		    entry.first_packet_dts = context->first_dts;

		  seek_append_table_entry(&context->seek_table, entry);
		}

	      if (context->current_frame_index - FIRST_FRAME_INDEX + 1 > context->seek_table.num_frames)
		context->seek_table.num_frames = context->current_frame_index - FIRST_FRAME_INDEX + 1;

	      break;
	    }
	}

      av_free_packet(&packet);
    }

  context->rgb_already_converted = FAS_FALSE;
  context->gray8_already_converted = FAS_FALSE;
  av_free_packet(&packet);
  return FAS_SUCCESS;
}
Ejemplo n.º 5
0
void do_random_test(fas_context_ref_type context, int start, int stop, int count)
{
  //  printf ("start: %d  stop: %d\n", start, stop );

  while (fas_get_frame_index(context) < start)
    if (FAS_SUCCESS != fas_step_forward(context))
      fail("failed on advancement\n");

  fas_raw_image_type *ref_frames = malloc( (stop - start + 1)* sizeof(fas_raw_image_type));
  
  int i;
  fas_error_type video_error;

  while (fas_get_frame_index(context) <= stop)
    {
      i = fas_get_frame_index(context) - start;

      video_error = fas_get_frame(context, &(ref_frames[i]));
      if (video_error != FAS_SUCCESS)    fail("fail on test(1)\n");

      video_error = fas_step_forward(context);
      if (video_error != FAS_SUCCESS)    fail("fail on test(2)\n");

    }

  int index = -1;
  int prev_index;

  for (i=0;i<count;i++)
    {
      int offset = random() % (stop - start + 1);
      prev_index = index;
      index = start + offset;

      video_error = fas_seek_to_frame(context, index);
      if (video_error != FAS_SUCCESS)    fail("fail on test(seek)\n");


      fas_raw_image_type test_frame;
      video_error = fas_get_frame(context, &test_frame);
      if (video_error != FAS_SUCCESS)    fail("fail on test(seek2)\n");

      //      printf("offset: %d / %d\n", offset, stop - start + 1);
      
      if (!compare_frames(test_frame, ref_frames[offset]))
	{	  
	  char buffer[70];
	  
	  sprintf(buffer, "fail-%d-test.ppm", index);
	  ppm_save(&test_frame, buffer);
	  sprintf(buffer, "fail-%d-ref.ppm", index);
	  ppm_save(&ref_frames[offset], buffer);
	  sprintf(buffer, "failed on compare after seeking (%d->%d)\n", prev_index, index);
	  
	  fail(buffer);
	}
      
      fas_free_frame(test_frame);
    }
  
  for (i=0;i<stop - start + 1;i++)
    free(ref_frames[i].data);
    
  free(ref_frames);
}