Ejemplo n.º 1
0
/* 服务端 - 客户端回调 */
void client_cb(channel_ref_t* channel, channel_cb_event_e e) {
    if (e & channel_cb_event_close) {
        connector_count--;
        if (connector_count == 0) {
            printf("all client closed\n");
            loop_exit(channel_ref_get_loop(channel));
        }
    }
}
Ejemplo n.º 2
0
int main(int argc, char* argv[])
{
  loop_handle * hd = &global_handle;
  dvs_thread thread_in;
  dvs_thread thread_out;
  int res = TRUE;
  int c;

  memset(hd, 0, sizeof(loop_handle));
  hd->running = TRUE;
  hd->ndelay = 4;

  while(--argc) {
    argv++;                                       // skip progamname
    if(**argv == '-') {
      c = tolower(*++*argv);                      // get option character
      ++*argv;
      if(**argv == '=') ++*argv;                  // skip equalsign
      if(**argv == ' ') ++*argv;                  // skip space
      switch(c) {
      case '2':
        hd->buse2cards = TRUE;
        break;
      case 'a':
        hd->baudioonly = TRUE;
        break;
      case 'b':
        hd->bottom2top = TRUE;  // flipping by using bottom2top
        break;
      case 'd':	
        hd->ndelay = atoi(*argv);	
        break;
      case 'f':	
        hd->bfieldbased = TRUE;	
        break;
      case 'v':
        hd->bvideoonly = TRUE;
        break;
      case 'x':
        hd->bverbose = TRUE;
        break;
      case 'p':
        hd->banc = TRUE;
        break;
      case 'q':
        hd->bancstreamer = TRUE;
        break;
      default:
        res = usage();
      }
    } else {
      res = usage();
    }
  }

  if(hd->banc && hd->bancstreamer) {
    printf("Parameter for anc overrides anc streamer.\n");
    hd->bancstreamer = FALSE;
  }

  signal(SIGTERM, signal_handler);
  signal(SIGINT,  signal_handler);

  if(res) {
    res = loop_init(hd);
  }

  if(res) {
    if(!dvs_thread_create(&thread_in, loop_in, hd, &hd->finish)) {
      printf("Creating input thread failed.\n");
      res = FALSE;
    }
  }

  if(res) {
    if(!dvs_thread_create(&thread_out, loop_out, hd, &hd->finish)) {
      printf("Creating output thread failed.\n");
      res = FALSE;
    }
  }

  if(res) {
    do {
      if(hd->bplayback) {
        printf("playback mode\n");
      } else {
        printf("loop-through mode\n");
      }

      c = getc(stdin);
      hd->bplayback = !hd->bplayback;
    } while (hd->running);
  }

  dvs_cond_broadcast(&hd->common.ready, &hd->common.lock, FALSE);
  dvs_thread_exitcode(&thread_in, &hd->finish);
  dvs_thread_exitcode(&thread_out, &hd->finish);

  loop_exit(hd);

  signal(SIGTERM, NULL);
  signal(SIGINT, NULL);

  return (res == TRUE) ? 0 : 1;
}
Ejemplo n.º 3
0
int loop_init(loop_handle * hd)
{
  sv_fifo_configinfo config;
  int modesrc  = 0;
  int modedst  = 0;
  int syncmode = 0;
  int res;
  int i;
  char anclayout[1024];

  // Open first card.
  hd->svsrc = sv_open("");
  if (hd->svsrc == NULL) {
    printf("loop_init: sv_open(\"\") failed\n");
    loop_exit(hd);
    return FALSE;
  }

  if(hd->buse2cards) {
    // Open second card.
    hd->svdst = sv_open("PCI,card:1");
    if(hd->svdst == NULL) {
      printf("loop_init: sv_open(\"PCI.card:1\") failed\n");
      loop_exit(hd);
      return FALSE;
    }
  } else {
    // Use first card for output as well.
    hd->svdst = hd->svsrc;
  }

  // Get current videomode from first card.
  res = sv_option_get(hd->svsrc, SV_OPTION_VIDEOMODE, &modesrc);
  if(res != SV_OK) {
    printf("loop_init: sv_option_get() failed\n");
    loop_exit(hd);
    return FALSE;
  }

  // Get current videomode from second card.
  res = sv_option_get(hd->svdst, SV_OPTION_VIDEOMODE, &modedst);
  if(res != SV_OK) {
    printf("loop_init: sv_option_get() failed\n");
    loop_exit(hd);
    return FALSE;
  }

  // Compare if both videomodes do match.
  if((modesrc & SV_MODE_MASK) != (modedst & SV_MODE_MASK)) {
    printf("loop_init: Raster of source and destination board do not match.\n");
    loop_exit(hd);
    return FALSE;
  }

  // Check sync mode
  res = sv_query(hd->svsrc, SV_QUERY_SYNCMODE, 0, &syncmode);
  if(res != SV_OK) {
    printf("loop_init: sv_query(SV_QUERY_SYNCMODE) failed\n");
    loop_exit(hd);
    return FALSE;
  }

  if(syncmode == SV_SYNC_INTERNAL) {
    printf("Error:\tPlease configure another sync mode,\n\tit is not possible to have a stable in to out delay with SV_SYNC_INTERNAL.\n");
    loop_exit(hd);
    return FALSE;
  }

  switch(modesrc & SV_MODE_MASK) {
  case SV_MODE_SMPTE274_47P:
  case SV_MODE_SMPTE274_48P:
  case SV_MODE_SMPTE274_50P:
  case SV_MODE_SMPTE274_59P:
  case SV_MODE_SMPTE274_60P:
  case SV_MODE_SMPTE274_71P:
  case SV_MODE_SMPTE274_72P:
    hd->bdualsdi = TRUE;
    break;
  }

  // Get information about current raster.
  res = sv_storage_status(hd->svsrc, 0, NULL, &hd->storage, sizeof(sv_storageinfo), 0);
  if(res != SV_OK) {
    printf("loop_init: sv_storage_status() failed = %d '%s'\n", res, sv_geterrortext(res));
  }

  // How many ticks does a frame last?
  hd->vinterlace = hd->storage.vinterlace;

  //frame to field correction
  hd->ndelay = hd->ndelay * hd->storage.vinterlace;

  //fieldbased correction
  if(hd->bfieldbased) {
    hd->vinterlace = 1;
  }

  if(hd->banc) {
    // Disable the fifo ancgenerator because else you will get double packets in loopback
    res = sv_option_set(hd->svdst, SV_OPTION_ANCGENERATOR, SV_ANCDATA_DISABLE );
    if(res != SV_OK) {
      printf("loop_init: sv_option_set() failed\n");
      loop_exit(hd);
      return FALSE;
    }
  }

  // Init input FIFO.
  res = sv_fifo_init(hd->svsrc, &hd->fifosrc,
    TRUE,  // input FIFO
    FALSE,
    TRUE,  // enable DMA mode
    (hd->bancstreamer ? SV_FIFO_FLAG_ANC : 0) |
    (hd->bfieldbased ? SV_FIFO_FLAG_FIELD : 0),  // enable field-based mode
    0      // use maximum available buffers
  );
  if(res != SV_OK)  {
    printf("sv_fifo_init(src) failed %d '%s'\n", res, sv_geterrortext(res));
    loop_exit(hd);
    return FALSE;
  }

  res = sv_fifo_sanitylevel(hd->svsrc, hd->fifosrc, SV_FIFO_SANITY_LEVEL_FATAL, SV_FIFO_SANITY_VERSION_1);
  if(res != SV_OK)  {
    printf("sv_fifo_sanitylevel(dst) failed %d '%s'\n", res, sv_geterrortext(res));
  }

  // Init output FIFO.
  res = sv_fifo_init(hd->svdst, &hd->fifodst,
    FALSE,  // output FIFO
    FALSE,
    TRUE,   // enable DMA mode
    (hd->bancstreamer ? SV_FIFO_FLAG_ANC : 0),
    0       // use maximum available buffers
  );
  if(res != SV_OK)  {
    printf("sv_fifo_init(dst) failed %d '%s'\n", res, sv_geterrortext(res));
    loop_exit(hd);
    return FALSE;
  }

  res = sv_fifo_sanitylevel(hd->svdst, hd->fifodst, SV_FIFO_SANITY_LEVEL_FATAL, SV_FIFO_SANITY_VERSION_1);
    if(res != SV_OK)  {
    printf("sv_fifo_sanitylevel(dst) failed %d '%s'\n", res, sv_geterrortext(res));
  }

  if(hd->bverbose && hd->bancstreamer) {
    int required = 0;

    res = sv_fifo_anclayout(hd->svsrc, hd->fifosrc, anclayout, sizeof(anclayout), &required);
    if(res == SV_ERROR_BUFFERSIZE)  {
      printf("sv_fifo_anclayout(src) buffer too small (required %d)\n", required);
    } else if(res != SV_OK)  {
      printf("sv_fifo_anclayout(src) failed %d '%s'\n", res, sv_geterrortext(res));
    } else {
      printf("ANC layout (input):\n%s\n", anclayout);
    }

    res = sv_fifo_anclayout(hd->svdst, hd->fifodst, anclayout, sizeof(anclayout), &required);
    if(res == SV_ERROR_BUFFERSIZE)  {
      printf("sv_fifo_anclayout(dst) buffer too small (required %d)\n", required);
    } else if(res != SV_OK)  {
      printf("sv_fifo_anclayout(dst) failed %d '%s'\n", res, sv_geterrortext(res));
    } else {
      printf("ANC layout (output):\n%s\n", anclayout);
    }
  }

  // Fetch some information about FIFO buffer sizes.
  res = sv_fifo_configstatus(hd->svsrc, hd->fifosrc, &config);
  if(res != SV_OK)  {
    printf("sv_fifo_configstatus(src) failed %d '%s'\n", res, sv_geterrortext(res));
    loop_exit(hd);
    return FALSE;
  }

  // Allocate sufficient memory for video and audio data.
  for(i = 0; i < MAX_ID; i++) {
    memset( &hd->anclist[i], 0, sizeof(hd->anclist[i]) );
    hd->livebuffer_org[i] = malloc(config.vbuffersize + config.abuffersize + (config.dmaalignment-1));
    hd->livebuffer[i] = (char *)((uintptr)(hd->livebuffer_org[i] + (config.dmaalignment-1)) & ~(uintptr)(config.dmaalignment-1));
    if(!hd->livebuffer_org[i]) {
      printf("malloc(%d) livebuffer %d failed\n", config.vbuffersize + config.abuffersize + (config.dmaalignment-1), i);
      loop_exit(hd);
      return FALSE;
    }

    if(config.ancbuffersize && hd->bancstreamer) {
      hd->ancbuffer_org[i] = malloc(config.ancbuffersize + (config.dmaalignment-1));
      hd->ancbuffer[i] = (char *)((uintptr)(hd->ancbuffer_org[i] + (config.dmaalignment-1)) & ~(uintptr)(config.dmaalignment-1));
      if(!hd->ancbuffer_org[i]) {
        printf("malloc(%d) ancbuffer %d failed\n", config.ancbuffersize + (config.dmaalignment-1), i);
        loop_exit(hd);
        return FALSE;
      }
    }
  }

  // Allocate sufficient memory for video and audio data.
  hd->blackbuffer_org = malloc(config.vbuffersize + config.abuffersize + (config.dmaalignment-1));
  hd->blackbuffer = (char *)((uintptr)(hd->blackbuffer_org + (config.dmaalignment-1)) & ~(uintptr)(config.dmaalignment-1));
  if(!hd->blackbuffer_org) {
    printf("malloc(%d) blackbuffer failed\n", config.vbuffersize + config.abuffersize + (config.dmaalignment-1));
    loop_exit(hd);
    return FALSE;
  }
  memset(hd->blackbuffer_org, 0, config.vbuffersize + config.abuffersize + (config.dmaalignment-1));

  // Allocate sufficient memory for video and audio data.
  hd->nobuffer_org = malloc(config.vbuffersize + config.abuffersize + (config.dmaalignment-1));
  hd->nobuffer = (char *)((uintptr)(hd->nobuffer_org + (config.dmaalignment-1)) & ~(uintptr)(config.dmaalignment-1));
  if(!hd->nobuffer_org) {
    printf("malloc(%d) nobuffer failed\n", config.vbuffersize + config.abuffersize + (config.dmaalignment-1));
    loop_exit(hd);
    return FALSE;
  }
  memset(hd->nobuffer_org, 0xff, config.vbuffersize + config.abuffersize + (config.dmaalignment-1));

  dvs_mutex_init(&hd->common.lock);
  dvs_cond_init(&hd->common.ready);

  return TRUE;
}