Esempio n. 1
0
// card number passed as void * (using cast)
static void * sdi_monitor(void *arg)
{
    long                card = (long)arg;
    sv_handle           *sv = a_sv[card];
    sv_fifo             *poutput;
    sv_info             status_info;
    sv_storageinfo      storage_info;
    printf("card = %ld\n", card);

    SV_CHECK( sv_status( sv, &status_info) );

    SV_CHECK( sv_storage_status(sv,
                            0,
                            NULL,
                            &storage_info,
                            sizeof(storage_info),
                            0) );

    SV_CHECK( sv_fifo_init( sv,
                            &poutput,       // FIFO handle
                            FALSE,          // bInput (FALSE for playback)
                            TRUE,           // bShared (TRUE for input/output share memory)
                            TRUE,           // bDMA
                            FALSE,          // reserved
                            0) );           // nFrames (0 means use maximum)

    SV_CHECK( sv_fifo_start(sv, poutput) );

    // Loop forever reading frames and displaying.
    // This will not use 99% CPU since sv_fifo_getbuffer() will block
    // until a hardware buffer frame is available.
    int last_res = -1;
    while (1)
    {
        int res;
        if ((res = read_picture(card, sv, poutput)) != SV_OK)
        {
            // Display error only when things change
            if (res != last_res) {
                fprintf(stderr, "card %ld: failed to capture video: (%d) %s\n", card, res,
                    res == SV_ERROR_INPUT_VIDEO_NOSIGNAL ? "INPUT_VIDEO_NOSIGNAL" : sv_geterrortext(res));
                // reset FIFO if error indicates FIFO problem
                if (res == SV_ERROR_FIFO_PUTBUFFER)
                {
                    fprintf(stderr, "SV_ERROR_FIFO_PUTBUFFER: restarting fifo\n");
                    SV_CHECK( sv_fifo_reset(sv, poutput) );
                    SV_CHECK( sv_fifo_start(sv, poutput) );
                }
            }
            last_res = res;
            usleep( 2 * 1000 * 1000);       // 2 second poll
            continue;
        }

        // Only display OK message once
        if (res != last_res && res == SV_OK) {
            fprintf(stderr, "card %ld: Video signal OK\n", card);
        }

        last_res = res;
    }

    return NULL;
}
Esempio n. 2
0
void * loop_in(void * arg) 
{
  loop_handle * hd = (loop_handle *) arg;
  sv_fifo_bufferinfo infosrc;
  sv_fifo_info status_src;
  unsigned int lastdrop_src = (unsigned int) ~0;
  int bufferid;
  int res = SV_OK;

  /*
  // Start the input FIFO.
  */
  res = sv_fifo_start(hd->svsrc, hd->fifosrc);
  if(res != SV_OK)  {
    printf("sv_fifo_start(src) failed %d '%s'\n", res, sv_geterrortext(res));
    hd->running = FALSE;
  }

  while (hd->running) {
    /*
    // >>> Handle input FIFO <<<
    */
    do {
      res = sv_fifo_getbuffer(hd->svsrc, hd->fifosrc, &hd->bufsrc, NULL,
        SV_FIFO_FLAG_NODMAADDR |
        (hd->bancstreamer ? SV_FIFO_FLAG_ANC : 0) |
        (hd->bvideoonly ? SV_FIFO_FLAG_VIDEOONLY : 0) |
        (hd->baudioonly ? SV_FIFO_FLAG_AUDIOONLY : 0) |
        (hd->bplayback ? SV_FIFO_FLAG_FLUSH : 0)
      );

      switch(res) {
      case SV_ERROR_NOCARRIER:
      case SV_ERROR_INPUT_VIDEO_NOSIGNAL:
      case SV_ERROR_INPUT_VIDEO_RASTER:
      case SV_ERROR_INPUT_VIDEO_DETECTING:
      case SV_ERROR_INPUT_KEY_NOSIGNAL:
      case SV_ERROR_INPUT_KEY_RASTER:
        printf("v");	// Inform user about missing video
        fflush(stdout);
        res = SV_ACTIVE;
        break;
      case SV_ERROR_INPUT_AUDIO_NOAIV:
      case SV_ERROR_INPUT_AUDIO_NOAESEBU:
        // In these two cases, getbuffer returned a valid buffer.
        // So, we can continue without audio.
        printf("a");	// Inform user about missing audio
        fflush(stdout);
        res = SV_OK;
        break;
      case SV_ERROR_VSYNCPASSED:
        printf("NOTE: vsyncpassed possibly caused by signal disconnect\n");
        res = SV_ACTIVE;
        break;
      default:;
      }

      if(res == SV_ACTIVE) {
        // wait for next vsync and try again
        sv_fifo_vsyncwait(hd->svsrc, hd->fifosrc);
      }
    } while(res == SV_ACTIVE && hd->running);

    if (res != SV_OK)  {
      printf("sv_fifo_getbuffer(src) failed %d '%s'\n", res, sv_geterrortext(res));
      hd->running = FALSE;
      break;
    }

    dvs_mutex_enter(&hd->common.lock);
    bufferid = get_free_bufferid(hd);
    dvs_mutex_leave(&hd->common.lock);

    fill_buffer(hd, TRUE, hd->bufsrc, bufferid);

    if(hd->banc && (bufferid >= 0)) {
      //Get list pointer
      anc_element_t * current_element = &hd->anclist[bufferid];

      //If there are valid packets delete them
      if( current_element->next ) {
        //Delete all elements in list
        delete_element( bufferid, current_element->next );
        //Set first element to zero
        memset( current_element, 0, sizeof(anc_element_t) );
      }
      
      //Try to get anc packets
      while( res==SV_OK ) {
        res = sv_fifo_anc( hd->svsrc, hd->fifosrc, hd->bufsrc, &current_element->ancbuffer );
        if( res == SV_OK ) {
          current_element->valid = 1;

          //Log
          if( hd->bverbose ) {
            printf("Recorded anc_element. Buffer:%d, DID:0x%x, SDID:0x%x\n", bufferid, current_element->ancbuffer.did, current_element->ancbuffer.sdid );
          }

          //I need to allocate one more packet buffer
          current_element->next = malloc( sizeof( anc_element_t ));
          if( current_element->next != 0 )
          {
            //Set all values to zero
            memset( current_element->next, 0, sizeof( anc_element_t ));
            
            //Build the list
            current_element->next->prev = current_element;
            current_element = current_element->next;
          } else {
            printf("malloc failed %d '%s'\n", res, sv_geterrortext(res));
            hd->running = FALSE;
          }
        }
      }
      // This errorcode shows that no more packets are in the frame
      if( res == SV_ERROR_NOTAVAILABLE ) {
        res = SV_OK;
      }
    }

    res = sv_fifo_putbuffer(hd->svsrc, hd->fifosrc, hd->bufsrc, &infosrc);
    if(res != SV_OK)  {
      printf("sv_fifo_putbuffer(src) failed %d '%s'\n", res, sv_geterrortext(res));
      hd->running = FALSE;
      break;
    }

    res = sv_fifo_status(hd->svsrc, hd->fifosrc, &status_src);
    if(res != SV_OK)  {
      printf("sv_fifo_status(src) failed %d '%s'\n", res, sv_geterrortext(res));
      hd->running = FALSE;
      break;
    }

    // Save input delay
    hd->indelay_info  = status_src.recordtick - infosrc.when;
    hd->inavail_info  = status_src.availbuffers; 
    
    if(hd->bverbose || ((unsigned int)status_src.dropped > lastdrop_src)) {
      printf("ID %2d - in  %06d %d %d %d (%u)\n", bufferid, infosrc.when, status_src.nbuffers, status_src.availbuffers, status_src.dropped - lastdrop_src, infosrc.clock_low);
    }

    // Report dropped frames in input FIFO.
    if((unsigned int)status_src.dropped > lastdrop_src) {
      printf("input fifo dropped - delay might have changed\n");
    }
    lastdrop_src = status_src.dropped;

    dvs_mutex_enter(&hd->common.lock);
    if(bufferid >= 0) {
      hd->common.inputtick[bufferid] = infosrc.when;
    }
    dvs_mutex_leave(&hd->common.lock);

    /*
    // Signal that a new input buffer is ready
    */
    dvs_cond_broadcast(&hd->common.ready, &hd->common.lock, FALSE);
  }

  res = sv_fifo_stop(hd->svsrc, hd->fifosrc, 0);
  if(res != SV_OK)  {
    printf("sv_fifo_stop(src) failed %d '%s'\n", res, sv_geterrortext(res));
  }

  hd->exitcode = TRUE;
  dvs_thread_exit(&hd->exitcode, &hd->finish);

  return NULL;
}