Пример #1
0
int runtimeStart(Runtime* _runtime)
{
  int res;
  int exit_code = 0;
  RuntimeThreads* rt;

  if (_runtime == NULL)
    return EINVAL;

  rt = &_runtime->m_threads;
  rt->m_terminate = false;

  if ((res = pthread_create(&rt->m_inputThread, NULL, &threadInput, _runtime)) != 0)
  {
    fprintf(stderr, "pthread_create(input) failed: %d\n", res);
    exit_code = res;
    goto exit;
  }

  if ((res = pthread_create(&rt->m_videoThread, NULL, &threadAudio, _runtime)) != 0)
  {
    fprintf(stderr, "pthread_create(audio) failed: %d\n", res);
    exit_code = res;
    goto exit_join_input_thread;
  }

  return 0;


 //exit_join_video_thread:
  runtimeSetTerminate(_runtime);
  pthread_cancel(rt->m_videoThread);
  pthread_join(rt->m_videoThread, NULL);

 exit_join_input_thread:
  runtimeSetTerminate(_runtime);
  pthread_cancel(rt->m_inputThread);
  pthread_join(rt->m_inputThread, NULL);

 exit:
  runtimeSetTerminate(_runtime);
  return exit_code;
}
Пример #2
0
int runtimeStop(Runtime* _runtime)
{
  RuntimeThreads* rt;

  if (_runtime == NULL)
    return EINVAL;

  rt = &_runtime->m_threads;

  runtimeSetTerminate(_runtime);
  pthread_join(rt->m_videoThread, NULL);
  pthread_join(rt->m_inputThread, NULL);

  return 0;
}
Пример #3
0
static int threadInputSelectLoop(Runtime* _runtime, RCInput* _rc)
{
  int res;
  int maxFd = 0;
  fd_set fdsIn;
  static const struct timespec s_selectTimeout = { .tv_sec=1, .tv_nsec=0 };

  if (_runtime == NULL || _rc == NULL)
    return EINVAL;

  FD_ZERO(&fdsIn);

  FD_SET(_rc->m_serverFd, &fdsIn);
  if (maxFd < _rc->m_serverFd)
    maxFd = _rc->m_serverFd;

  if (_rc->m_stdinFd != -1)
  {
    FD_SET(_rc->m_stdinFd, &fdsIn);
    if (maxFd < _rc->m_stdinFd)
      maxFd = _rc->m_stdinFd;
  }

  if (_rc->m_eventInputFd != -1)
  {
    FD_SET(_rc->m_eventInputFd, &fdsIn);
    if (maxFd < _rc->m_eventInputFd)
      maxFd = _rc->m_eventInputFd;
  }

  if (_rc->m_connectionFd != -1)
  {
    FD_SET(_rc->m_connectionFd, &fdsIn);
    if (maxFd < _rc->m_connectionFd)
      maxFd = _rc->m_connectionFd;
  }


  if ((res = pselect(maxFd+1, &fdsIn, NULL, NULL, &s_selectTimeout, NULL)) < 0)
  {
    res = errno;
    fprintf(stderr, "pselect() failed: %d\n", res);
    return res;
  }


  if (FD_ISSET(_rc->m_serverFd, &fdsIn))
  {
    if ((res = rcInputAcceptConnection(_rc)) != 0)
    {
      fprintf(stderr, "rcInputAcceptConnection() failed: %d\n", res);
      return res;
    }
  }

  if (_rc->m_stdinFd != -1 && FD_ISSET(_rc->m_stdinFd, &fdsIn))
  {
    if ((res = rcInputReadStdin(_rc)) != 0)
    {
      fprintf(stderr, "rcInputReadStdin() failed: %d\n", res);
      return res;
    }
  }

  if (_rc->m_eventInputFd != -1 && FD_ISSET(_rc->m_eventInputFd, &fdsIn))
  {
    if ((res = rcInputReadEventInput(_rc)) != 0)
    {
      fprintf(stderr, "rcInputReadEventInput() failed: %d\n", res);
      return res;
    }
  }

  if (_rc->m_connectionFd != -1 && FD_ISSET(_rc->m_connectionFd, &fdsIn))
  {
    if ((res = rcInputReadConnection(_rc)) != 0)
    {
      fprintf(stderr, "rcInputReadConnection() failed: %d\n", res);
      return res;
    }
  }

  DriverManualControl driverManualControl;
  if ((res = rcInputGetManualControl(_rc, &driverManualControl)) != 0)
  {
    if (res != ENODATA)
    {
      fprintf(stderr, "rcInputGetManualControl() failed: %d\n", res);
      return res;
    }
  }
  else
  {
    if ((res = runtimeSetDriverManualControl(_runtime, &driverManualControl)) != 0)
    {
      fprintf(stderr, "runtimeSetDriverManualControl() failed: %d\n", res);
      return res;
    }
  }

  TargetDetectParams targetParams;
  if ((res = rcInputGetTargetDetectParams(_rc, &targetParams)) != 0)
  {
    if (res != ENODATA)
    {
      fprintf(stderr, "rcInputGetTargetDetectParams() failed: %d\n", res);
      return res;
    }
  }
  else
  {
    if ((res = runtimeSetTargetDetectParams(_runtime, &targetParams)) != 0)
    {
      fprintf(stderr, "runtimeSetTargetDetectParams() failed: %d\n", res);
      return res;
    }
  }

  return 0;
}




void* threadInput(void* _arg)
{
  int res = 0;
  intptr_t exit_code = 0;
  Runtime* runtime = (Runtime*)_arg;
  RCInput* rc;

  if (runtime == NULL)
  {
    exit_code = EINVAL;
    goto exit;
  }

  if ((rc = runtimeModRCInput(runtime)) == NULL)
  {
    exit_code = EINVAL;
    goto exit;
  }


  if ((res = rcInputOpen(rc, runtimeCfgRCInput(runtime))) != 0)
  {
    fprintf(stderr, "rcInputOpen() failed: %d\n", res);
    exit_code = res;
    goto exit;
  }


  if ((res = rcInputStart(rc)) != 0)
  {
    fprintf(stderr, "rcInputStart() failed: %d\n", res);
    exit_code = res;
    goto exit_rc_close;
  }


  printf("Entering input thread loop\n");
  while (!runtimeGetTerminate(runtime))
  {
    if ((res = threadInputSelectLoop(runtime, rc)) != 0)
    {
      fprintf(stderr, "threadInputSelectLoop() failed: %d\n", res);
      exit_code = res;
      goto exit_rc_stop;
    }
  }
  printf("Left input thread loop\n");


 exit_rc_stop:
  if ((res = rcInputStop(rc)) != 0)
    fprintf(stderr, "rcInputStop() failed: %d\n", res);


 exit_rc_close:
  if ((res = rcInputClose(rc)) != 0)
    fprintf(stderr, "rcInputClose() failed: %d\n", res);


 exit:
  runtimeSetTerminate(runtime);
  return (void*)exit_code;
}
Пример #4
0
static int threadVideoSelectLoop(Runtime* _runtime, CodecEngine* _ce, V4L2Input* _v4l2, FBOutput* _fb)
{
  int res;
  int maxFd = 0;
  fd_set fdsIn;
  static const struct timespec s_selectTimeout = { .tv_sec=1, .tv_nsec=0 };

  if (_runtime == NULL || _ce == NULL || _v4l2 == NULL || _fb == NULL)
    return EINVAL;

  FD_ZERO(&fdsIn);

  FD_SET(_v4l2->m_fd, &fdsIn);
  if (maxFd < _v4l2->m_fd)
    maxFd = _v4l2->m_fd;

  if ((res = pselect(maxFd+1, &fdsIn, NULL, NULL, &s_selectTimeout, NULL)) < 0)
  {
    res = errno;
    fprintf(stderr, "pselect() failed: %d\n", res);
    return res;
  }

  if (!FD_ISSET(_v4l2->m_fd, &fdsIn))
  {
    fprintf(stderr, "pselect() did not select V4L2\n");
    return EBUSY;
  }

  const void* frameSrcPtr;
  size_t frameSrcSize;
  size_t frameSrcIndex;
  if ((res = v4l2InputGetFrame(_v4l2, &frameSrcPtr, &frameSrcSize, &frameSrcIndex)) != 0)
  {
    fprintf(stderr, "v4l2InputGetFrame() failed: %d\n", res);
    return res;
  }

  void* frameDstPtr;
  size_t frameDstSize;
  if ((res = fbOutputGetFrame(_fb, &frameDstPtr, &frameDstSize)) != 0)
  {
    fprintf(stderr, "fbOutputGetFrame() failed: %d\n", res);
    return res;
  }


  TargetDetectParams targetParams;
  TargetLocation     targetLocation;
  if ((res = runtimeGetTargetDetectParams(_runtime, &targetParams)) != 0)
  {
    fprintf(stderr, "runtimeGetTargetDetectParams() failed: %d\n", res);
    return res;
  }

  size_t frameDstUsed = frameDstSize;
  if ((res = codecEngineTranscodeFrame(_ce,
                                       frameSrcPtr, frameSrcSize,
                                       frameDstPtr, frameDstSize, &frameDstUsed,
                                       &targetParams,
                                       &targetLocation)) != 0)
  {
    fprintf(stderr, "codecEngineTranscodeFrame(%p[%zu] -> %p[%zu]) failed: %d\n",
            frameSrcPtr, frameSrcSize, frameDstPtr, frameDstSize, res);
    return res;
  }


  if ((res = fbOutputPutFrame(_fb)) != 0)
  {
    fprintf(stderr, "fbOutputPutFrame() failed: %d\n", res);
    return res;
  }

  if ((res = v4l2InputPutFrame(_v4l2, frameSrcIndex)) != 0)
  {
    fprintf(stderr, "v4l2InputPutFrame() failed: %d\n", res);
    return res;
  }


  if ((res = runtimeSetTargetLocation(_runtime, &targetLocation)) != 0)
  {
    fprintf(stderr, "runtimeSetTargetLocation() failed: %d\n", res);
    return res;
  }

  return 0;
}




void* threadVideo(void* _arg)
{
  int res = 0;
  intptr_t exit_code = 0;
  Runtime* runtime = (Runtime*)_arg;
  CodecEngine* ce;
  V4L2Input* v4l2;
  FBOutput* fb;
  struct timespec last_fps_report_time;

  if (runtime == NULL)
  {
    exit_code = EINVAL;
    goto exit;
  }

  if (   (ce   = runtimeModCodecEngine(runtime)) == NULL
      || (v4l2 = runtimeModV4L2Input(runtime))   == NULL
      || (fb   = runtimeModFBOutput(runtime))    == NULL)
  {
    exit_code = EINVAL;
    goto exit;
  }


  if ((res = codecEngineOpen(ce, runtimeCfgCodecEngine(runtime))) != 0)
  {
    fprintf(stderr, "codecEngineOpen() failed: %d\n", res);
    exit_code = res;
    goto exit;
  }

  if ((res = v4l2InputOpen(v4l2, runtimeCfgV4L2Input(runtime))) != 0)
  {
    fprintf(stderr, "v4l2InputOpen() failed: %d\n", res);
    exit_code = res;
    goto exit_ce_close;
  }

  if ((res = fbOutputOpen(fb, runtimeCfgFBOutput(runtime))) != 0)
  {
    fprintf(stderr, "fbOutputOpen() failed: %d\n", res);
    exit_code = res;
    goto exit_v4l2_close;
  }


  ImageDescription srcImageDesc;
  ImageDescription dstImageDesc;
  if ((res = v4l2InputGetFormat(v4l2, &srcImageDesc)) != 0)
  {
    fprintf(stderr, "v4l2InputGetFormat() failed: %d\n", res);
    exit_code = res;
    goto exit_fb_close;
  }
  if ((res = fbOutputGetFormat(fb, &dstImageDesc)) != 0)
  {
    fprintf(stderr, "fbOutputGetFormat() failed: %d\n", res);
    exit_code = res;
    goto exit_fb_close;
  }
  if ((res = codecEngineStart(ce, runtimeCfgCodecEngine(runtime), &srcImageDesc, &dstImageDesc)) != 0)
  {
    fprintf(stderr, "codecEngineStart() failed: %d\n", res);
    exit_code = res;
    goto exit_fb_close;
  }

  if ((res = v4l2InputStart(v4l2)) != 0)
  {
    fprintf(stderr, "v4l2InputStart() failed: %d\n", res);
    exit_code = res;
    goto exit_ce_stop;
  }

  if ((res = fbOutputStart(fb)) != 0)
  {
    fprintf(stderr, "fbOutputStart() failed: %d\n", res);
    exit_code = res;
    goto exit_v4l2_stop;
  }


  if ((res = clock_gettime(CLOCK_MONOTONIC, &last_fps_report_time)) != 0)
  {
    fprintf(stderr, "clock_gettime(CLOCK_MONOTONIC) failed: %d\n", errno);
    exit_code = res;
    goto exit_fb_stop;
  }


  printf("Entering video thread loop\n");
  while (!runtimeGetTerminate(runtime))
  {
    struct timespec now;
    long long last_fps_report_elapsed_ms;

    if ((res = clock_gettime(CLOCK_MONOTONIC, &now)) != 0)
    {
      fprintf(stderr, "clock_gettime(CLOCK_MONOTONIC) failed: %d\n", errno);
      exit_code = res;
      goto exit_fb_stop;
    }

    last_fps_report_elapsed_ms = (now.tv_sec  - last_fps_report_time.tv_sec )*1000
                               + (now.tv_nsec - last_fps_report_time.tv_nsec)/1000000;
    if (last_fps_report_elapsed_ms >= 10*1000)
    {
      last_fps_report_time.tv_sec += 10;

      if ((res = codecEngineReportLoad(ce, last_fps_report_elapsed_ms)) != 0)
        fprintf(stderr, "codecEngineReportLoad() failed: %d\n", res);

      if ((res = v4l2InputReportFPS(v4l2, last_fps_report_elapsed_ms)) != 0)
        fprintf(stderr, "v4l2InputReportFPS() failed: %d\n", res);
    }


    if ((res = threadVideoSelectLoop(runtime, ce, v4l2, fb)) != 0)
    {
      fprintf(stderr, "threadVideoSelectLoop() failed: %d\n", res);
      exit_code = res;
      goto exit_fb_stop;
    }
  }
  printf("Left video thread loop\n");


 exit_fb_stop:
  if ((res = fbOutputStop(fb)) != 0)
    fprintf(stderr, "fbOutputStop() failed: %d\n", res);

 exit_v4l2_stop:
  if ((res = v4l2InputStop(v4l2)) != 0)
    fprintf(stderr, "v4l2InputStop() failed: %d\n", res);

 exit_ce_stop:
  if ((res = codecEngineStop(ce)) != 0)
    fprintf(stderr, "codecEngineStop() failed: %d\n", res);


 exit_fb_close:
  if ((res = fbOutputClose(fb)) != 0)
    fprintf(stderr, "fbOutputClose() failed: %d\n", res);

 exit_v4l2_close:
  if ((res = v4l2InputClose(v4l2)) != 0)
    fprintf(stderr, "v4l2InputClose() failed: %d\n", res);

 exit_ce_close:
  if ((res = codecEngineClose(ce)) != 0)
    fprintf(stderr, "codecEngineClose() failed: %d\n", res);


 exit:
  runtimeSetTerminate(runtime);
  return (void*)exit_code;
}
// Video thread
void* threadVideo(void* _arg)
{
	intptr_t exit_code = 0;
	Runtime* runtime = (Runtime*)_arg;
	CodecEngine* ce;
	FBOutput* fb;
	int res = 0;

	struct timespec last_fps_report_time;

	ImageDescription srcImageDesc;
	ImageDescription dstImageDesc;

	if (runtime == NULL)
	{
		exit_code = EINVAL;
		goto exit;
	}

	if ((ce   = runtimeModCodecEngine(runtime)) == NULL
			|| (fb   = runtimeModFBOutput(runtime))    == NULL)
	{
		exit_code = EINVAL;
		goto exit;
	}

	if ((res = codecEngineOpen(ce, runtimeCfgCodecEngine(runtime))) != 0)
	{
		fprintf(stderr, "codecEngineOpen() failed: %d\n", res);
		exit_code = res;
		goto exit;
	}

	if ((res = fbOutputOpen(fb, runtimeCfgFBOutput(runtime))) != 0)
	{
		fprintf(stderr, "fbOutputOpen() failed: %d\n", res);
		exit_code = res;
		goto exit_ce_close;
	}

	if ((res = fbOutputGetFormat(fb, &dstImageDesc)) != 0)
	{
		fprintf(stderr, "fbOutputGetFormat() failed: %d\n", res);
		exit_code = res;
		goto exit_fb_close;
	}

	memcpy(&srcImageDesc, &dstImageDesc, sizeof(srcImageDesc));
	srcImageDesc.m_format = ImageSourceFormat;
	srcImageDesc.m_imageSize = FrameSourceSize;

	if ((res = codecEngineStart(ce, runtimeCfgCodecEngine(runtime), &srcImageDesc, &dstImageDesc)) != 0)
	{
		fprintf(stderr, "codecEngineStart() failed: %d\n", res);
		exit_code = res;
		goto exit_fb_close;
	}

	if ((res = fbOutputStart(fb)) != 0)
	{
		fprintf(stderr, "fbOutputStart() failed: %d\n", res);
		exit_code = res;
		goto exit_ce_close;
	}

	if ((res = clock_gettime(CLOCK_MONOTONIC, &last_fps_report_time)) != 0)
	{
		fprintf(stderr, "clock_gettime(CLOCK_MONOTONIC) failed: %d\n", errno);
		exit_code = res;
		goto exit_fb_stop;
	}


	printf("Open default soundcard\n");
	init_soundcard();

	printf("Entering video thread loop\n");
	while (!runtimeGetTerminate(runtime))
	{
		struct timespec now;
		long long last_fps_report_elapsed_ms;

		if ((res = clock_gettime(CLOCK_MONOTONIC, &now)) != 0)
		{
			fprintf(stderr, "clock_gettime(CLOCK_MONOTONIC) failed: %d\n", errno);
			exit_code = res;
			goto exit_fb_stop;
		}

		last_fps_report_elapsed_ms = (now.tv_sec  - last_fps_report_time.tv_sec )*1000
				+ (now.tv_nsec - last_fps_report_time.tv_nsec)/1000000;

		if (last_fps_report_elapsed_ms >= 10*1000)
		{
			last_fps_report_time.tv_sec += 10;

			if ((res = codecEngineReportLoad(ce, last_fps_report_elapsed_ms)) != 0)
				fprintf(stderr, "codecEngineReportLoad() failed: %d\n", res);

			if ((res = InputReportFPS(last_fps_report_elapsed_ms)) != 0)
				fprintf(stderr, "InputReportFPS() failed: %d\n", res);

		}

		if ((res = threadVideoSelectLoop(runtime, ce, fb)) != 0)
		{
			fprintf(stderr, "threadVideoSelectLoop() failed: %d\n", res);
			exit_code = res;
			goto exit_fb_stop;
		}
	}
	printf("Left video thread loop\n");

	exit_fb_stop:
	if ((res = fbOutputStop(fb)) != 0)
		fprintf(stderr, "fbOutputStop() failed: %d\n", res);

	exit_ce_stop:
	if ((res = codecEngineStop(ce)) != 0)
		fprintf(stderr, "codecEngineStop() failed: %d\n", res);

	exit_fb_close:
	if ((res = fbOutputClose(fb)) != 0)
		fprintf(stderr, "fbOutputClose() failed: %d\n", res);

	exit_ce_close:
	if ((res = codecEngineClose(ce)) != 0)
		fprintf(stderr, "codecEngineClose() failed: %d\n", res);

	exit:
	runtimeSetTerminate(runtime);

	printf("Close default soundcard\n");
	close_soundcard();

	return (void*)exit_code;
}