コード例 #1
0
int framecatcher::getRGBImage(int frame, unsigned char*& rgb32BitData, int& width, int& height){

	if(stream == NULL)
		return 0;

	int errCode = 0;
	xine_play(stream,0,0);
	xine_play(stream,0,frame); // 1 frame 2 mseconds

	uint8_t   *yuv = NULL, *y = NULL, *u = NULL, *v =NULL ;
	int ratio = 0, format = 0;

	if (!xine_get_current_frame(stream, &width, &height, &ratio, &format, NULL)){
		errCode= xine_get_error(stream);
		return errCode;
	}

	yuv = new uint8_t[((width+8) * (height+1) * 2)];
	if (yuv == NULL){
		std::cerr << "Out of Memory!";
		return 0;
	}

	if (!xine_get_current_frame(stream, &width, &height, &ratio, &format, yuv)){
		errCode= xine_get_error(stream);

		if(yuv != NULL)
					delete[] yuv;

		return errCode;
	}

	/*
	 * convert to yv12 if necessary
	 */
	switch (format){
		case XINE_IMGFMT_YUY2:
		{
			uint8_t *yuy2 = yuv;

			yuv = new uint8_t[(width * height * 2)];
			if (yuv == NULL){
				std::cerr << "Not enough memory to make screenshot!" << std::endl;
				return 0;
			}

			y = yuv;
			u = yuv + width * height;
			v = yuv + width * height * 5 / 4;

			yuy2Toyv12 (y, u, v, yuy2, width, height);

			delete [] yuy2;
		}
		break;
		case XINE_IMGFMT_YV12:
		y = yuv;
		u = yuv + width * height;
		v = yuv + width * height * 5 / 4;

		break;
		default:
		{
			std::cerr << "Format Not Supported" << std::endl;

			if(yuv != NULL)
				delete [] yuv;

			return 0;
		}
	}

	rgb32BitData = yv12ToRgb (y, u, v, width, height);
	delete [] yuv;
	return 1;
}
コード例 #2
0
static Epsilon_Image *
epsilon_generate_thumb (Epsilon * e)
{
  int ret = XINE_THUMB_SUCCESS;
  Epsilon_Image *img = NULL;
  unsigned char *buf = NULL;
  int cnt, attempts = 0, length = -1, pos_perc, pos_time, new_perc, new_time,
  req_perc = 500, req_time = 500;
  static int old_length = -1;
  char cfg[PATH_MAX];
  epsilon_xine_param *param;

  param = calloc (1, sizeof (epsilon_xine_param));
  if (!(param->xine = xine_new ()))
    {
      return NULL;
    }
  snprintf (cfg, PATH_MAX, "%s%s", xine_get_homedir (), ".xine/config");
  xine_config_load (param->xine, cfg);
  xine_init (param->xine);

  /* opening xine output ports */
  if (!
      (param->vo_port =
       xine_open_video_driver (param->xine, "none", XINE_VISUAL_TYPE_NONE,
			       (void *) NULL)))
    {
      goto done;
    }

  param->ao_port = xine_open_audio_driver (param->xine, "none", NULL);

  /* open a xine stream connected to these ports */
  if (!
      (param->stream =
       xine_stream_new (param->xine, param->ao_port, param->vo_port)))
    {
      goto done;
    }


  if (!xine_open (param->stream, e->src))
    {
      ret = XINE_THUMB_FAIL;
      goto done;
    }

    if (XINE_THUMBNAILER_DEBUG) printf("Starting xine thumbnail process..\n");

try_get_chance:
  new_perc = -1;
  new_time = req_time;

  if (!xine_play (param->stream, 0, new_time))
    {
      new_time = -1;
      new_perc = req_perc;	/* 0..65535 */
      if (!xine_play (param->stream, new_perc, 0))
	{
	  ret = XINE_THUMB_FAIL;
	  if (XINE_THUMBNAILER_DEBUG) printf("Coudln't play video %s..\n", e->src);
	  goto close_stream;
	}
    }

  /* get position */
  for (cnt = 0; ((cnt < 50) &&
		 (!xine_get_pos_length
		  (param->stream, &pos_perc, &pos_time, &length)
		  || (length == old_length))); cnt++)
    usleep (1000);

  if (length < 0)
    {
      if (XINE_THUMBNAILER_DEBUG) printf("Video is 0 length!..\n");
      ret = XINE_THUMB_FAIL;
      goto close_stream;
    }

  /* wait till position changes */
  for (cnt = 0;
       (cnt < 50) &&
       (!xine_get_pos_length (param->stream, &new_perc, &new_time, &length) ||
	((new_perc == pos_perc) && (new_time == pos_time))); cnt++)
    {
      usleep (1000);
    }

  /* get snapshot */
  int w, h, ratio, format;

  old_length = length;

  /* ask what size a snapshot would be (if we can make one) */
  if (!xine_get_current_frame (param->stream, &w, &h, &ratio, &format, NULL))
    {
      attempts++;
      if (attempts < 10)
	{
	  if (req_time < 10000)
	    req_time += 1000;
	  if (req_perc < 10000)
	    req_perc += 1000;
	  goto try_get_chance;

	}
      else
	{
	  if (XINE_THUMBNAILER_DEBUG) printf("Exhausted attempts to thumbnail..\n");
	  ret = XINE_THUMB_FAIL;
	  goto close_stream;
	}
    }
  else if ((w <= 0) || (h <= 0))
    {
      if (XINE_THUMBNAILER_DEBUG) printf("Width/Height of video invalid: %d:%d..\n", w,h);
      ret = XINE_THUMB_FAIL;
      goto close_stream;
    }
  else
    {
      /* know we know the size, get a buffer for the snapshot */
      if (!(buf = malloc (w * h * 2)))
	{
	  if (XINE_THUMBNAILER_DEBUG) printf("Couldn't allocate memory for thumbnail buffer..\n");
	  ret = XINE_THUMB_FAIL;
	  goto close_stream;
	}

      /* make a snapshot! */
      if (!xine_get_current_frame
	  (param->stream, &w, &h, &ratio, &format, buf))
	{
	  if (XINE_THUMBNAILER_DEBUG) printf("Couldn't retrieve current video frame..\n");
	  ret = XINE_THUMB_FAIL;
	  goto close_stream;
	}

      else if ((w <= 0) || (h <= 0))
	{
	  if (XINE_THUMBNAILER_DEBUG) printf("Width/height of video invalid: %d:%d..\n",w,h);
	  ret = XINE_THUMB_FAIL;
	  goto close_stream;
	}

      if (format == XINE_IMGFMT_YUY2)
	{
	  unsigned char *buf2 = malloc (w * h * 2);
	  unsigned char *tmp = buf;
	  i_yuy2_to_yv12 (buf, buf2, w, h);

	  buf = buf2;
	  free (tmp);

	  format = XINE_IMGFMT_YV12;
	}

      if (format == XINE_IMGFMT_YV12)
	{
	  ret = yv12_to_rgb (e->src, w, h, &buf, &img);

	  if (ret != XINE_THUMB_SUCCESS)
	    {
	      if (img)
		{
		  if (++attempts > 10)
		    goto close_stream;
		  free(img->data);
		  free(img);
		  img = NULL;
		  if (ret == XINE_THUMB_RETRY)
		    {
		      if (buf)
			{
			  free (buf);
			  buf = NULL;
			  if ((req_perc += (attempts * 1000)) > 65535)
			    req_perc = 1000;
			  if ((req_time += (attempts * 2500)) > length)
			    req_time = 3000;
			  goto try_get_chance;
			}

	              if (XINE_THUMBNAILER_DEBUG) printf("Exhausted attempts to thumbnail pos 2..\n");
		      ret = XINE_THUMB_FAIL;
		      goto close_stream;
		    }
		}

	      else
		{
		  if (XINE_THUMBNAILER_DEBUG) printf("Couldn't complete yv12_to_rgb..\n");
		  ret = XINE_THUMB_FAIL;
		  goto close_stream;
		}
	    }
	}

      ret = XINE_THUMB_SUCCESS;

    close_stream:
      if (buf)
	{
	  free (buf);
	  buf = NULL;
	}
      xine_close (param->stream);

    done:
      if (ret != XINE_THUMB_SUCCESS)
	{
	  if (img)
	    {
	      free(img->data);
	      free(img);
	      img = NULL;
	    }
	}

      if (param->stream)
	{
	  xine_dispose (param->stream);
	  param->stream = NULL;
	}
      if (param->ao_port)
	{
	  xine_close_audio_driver (param->xine, param->ao_port);
	  param->ao_port = NULL;
	}
      if (param->vo_port)
	{
	  xine_close_video_driver (param->xine, param->vo_port);
	  param->vo_port = NULL;
	}

      free (param);

      return img;
    }
   return NULL;
}