⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rxiso.cpp

📁 VHPD1394 V1.15驅動程序源碼
💻 CPP
字号:
/************************************************************************
 *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
 *  PURPOSE.
 ************************************************************************/

/************************************************************************
 *
 *  Module:       rxiso.cpp
 *  Long name:    VHPD1394 isochronous receive example
 *  Description:  This sample demonstrates how to use the VHPD1394
 *                device driver to receive isochronous data from an
 *                isochronous channel.
 *                This sample is based on the VHPDLib C++ class library.
 *                It demonstrates the usage of the class CVhpdIsoListener.
 *
 *  Runtime Env.: implemented as Win32 console application
 *  Used link libraries:
 *                vhpdlib.lib, setupapi.lib, user32.lib
 *  Author(s):    Frank Senf
 *  Company:      Thesycon GmbH, Ilmenau
 ************************************************************************/

// standard includes
#include <stdio.h>
#include <conio.h>

// definitions of used classes
#include "IsoListener.h"


// print prefixes
#define PFX     "RXISO: "
#define PFXERR  "RXISO Error: "
// standard help message
static const char g_UseHelp[] = "For help, use RXISO -h.";


// GLOBAL VARIABLES

// isochronous listener instance
CIsoListener g_IsoListener;

// parameters of the isochronous data stream to receive
// expected maximum number of bytes contained in a single isochronous frame
// has to be DWORD-aligned
// (no default, always has to be specified)
unsigned long g_MaxBytesPerIsoFrame;
// number of the channel to receive (default is channel 0)
int g_Channel =0;
// number of DWORDSs that will be stripped from the start of
// each isochronous frame before putting it to user data buffer
// (default is 1 DWORD)
unsigned long g_QuadsToStrip =1;
// speed of the isochronous data stream to receive
// (default is 400 MBit/s)
VHPD_BUS_SPEED g_UsedSpeed =BusSpeed400;

// parameters of the buffer pool used for receiving
// 8 buffers in pool
unsigned long g_NumberOfBuffers =8;
// each buffer holds 160 isochronous frames, so it is filled in 20 ms
unsigned long g_FramesPerBuffer =160;

// name of the output file (optional)
const char* g_OutFileName =NULL;


/*******************************************************************/
// support functions
/*******************************************************************/

//
// display usage information
//
void
PrintHelp(void)
{

  fprintf(stdout,
    "\n"
    "usage: RXISO MaxBytesPerIsoFrame <Options>\n"
    "\n"
    " MaxBytesPerIsoFrame (required)\n"
    "  expected maximum number of bytes contained in a single isochronous frame\n"
    "  (has to be DWORD-aligned)\n"
    "\n"
    " Options:\n"
    "  -cChannel: isochronous channel to be used for reception (optional, default %d)\n"
    "  -sSpeed: transfer speed of the selected channel (optional)\n"
    "           (1 -> 100MBit/s, 2 -> 200MBit/s, 4 -> 400MBit/s, default %d)\n"
    "  -qQuadletsToStrip: number of DWORDs to strip from start of\n"
    "                     each iso frame (optional, default %d)\n"
    "  -nBufferCount: number of buffers in buffer queue\n"
    "                 (optional, default %d)\n"
    "  -bFramesPerBuffer: number of isochronous frames to fit in one buffer\n"
    "                     (optional, default %d)\n"
    "  -fOutputFile:  file that will be used to store the isochronous data\n"
    "                 Data will not be stored if this parameter is omitted\n"
    "                 The file will be OVERWRITTEN WITHOUT ANY WARNING!\n"
    ,g_Channel,g_UsedSpeed,g_QuadsToStrip,g_NumberOfBuffers,g_FramesPerBuffer);

  fprintf(stdout,"\nPress any key to continue\n");
  getch();
  
  
} // PrintHelp



/*******************************************************************/
// main function
/*******************************************************************/
int __cdecl main(int argc, char *argv[])
{

/*******************************************************************/
// fixed command line argument

  // check for required arguments
  if ( argc < 2 ) {
    // at least MaxBytesPerIsoFrame has to be specified
    PrintHelp();
    return 1;
  }

  // store values for required arguments
  int val;
  if ( 1==sscanf(argv[1]," %i ",&val) ) {
    // check if MaxBytesPerIsoFrame is DWORD-aligned
    if ( val%sizeof(unsigned long) ) {
      fprintf(stderr, PFXERR" MaxBytesPerIsoFrame is not DWORD-aligned\n");
      return 3;
    } else {
      // store value
      g_MaxBytesPerIsoFrame = val;
    }
  } else {
    // invalid option format, ignore it
    fprintf(stderr, PFXERR"Invalid MaxBytesPerIsoFrame argument\n");
    return 4;
  }


/*******************************************************************/
// optional command line options

  int i;
  char* p;
  for ( i=1; i<argc; i++ ) {
    p = argv[i];
    if ( (*p) == '-' ) {
      p++;
      switch ( *p ) {
        case 'h':
        case 'H':
        case '?':
          // help
          PrintHelp();
          return 0;
                
        // isochronous channel
        case 'c':
          // read number
          if ( 1==sscanf(p+1," %i ",&val) ) {
            if ( val>=0 && val<=63 ) {
              // valid channel number, store it
              g_Channel = val;
            } else {
              // invalid channel number, ignore it
              fprintf(stderr, PFXERR"Invalid channel number %d ignored\n",val);
            }
          } else {
            // invalid option format, ignore it
            fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
          }
          break;
        // transfer rate of isochronous data stream
        case 's':
          // read number
          if ( 1==sscanf(p+1," %i ",&val) ) {
            // check value
            switch ( val ) {
              case 1:
                g_UsedSpeed = BusSpeed100; break;
              case 2:
                g_UsedSpeed = BusSpeed200; break;
              case 4:
                g_UsedSpeed = BusSpeed400; break;
              default:
                // invalid transfer rate, ignore it
                fprintf(stderr, PFXERR"Invalid transfer rate %d, ignored\n",val);
                break;
            } // switch
          } else {
            // invalid option format, ignore it
            fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
          }
          break;
        // DWORDs top strip at the start of each iso frame
        case 'q':
          // read number
          if ( 1==sscanf(p+1," %i ",&val) ) {
            // store value
            g_QuadsToStrip = val;
          } else {
            // invalid option format, ignore it
            fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
          }
          break;
        // buffer count
        case 'n':
          // read number
          if ( 1==sscanf(p+1," %i ",&val) ) {
            // store value
            g_NumberOfBuffers = val;
          } else {
            // invalid option format, ignore it
            fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
          }
          break;
        // buffer size (in iso frames per buffer)
        case 'b':
          // read number
          if ( 1==sscanf(p+1," %i ",&val) ) {
            // store value
            g_FramesPerBuffer = val;
          } else {
            // invalid option format, ignore it
            fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
          }
          break;
        // output file name
        case 'f':
          if ( *(p+1) != 0 ) {
            // save string pointer
            g_OutFileName = p+1;
          } else {
            // invalid filename
            fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
          }
          break;
        // unknown options
        default:
          fprintf(stderr, PFXERR"Unrecognized option '%s' ignored. %s\n",argv[i],g_UseHelp);
          break;
      } // switch
    }
  } // for


/*******************************************************************/
// setup g_IsoListener

  unsigned long Status;
  // open the output file if a file name was given
  if ( g_OutFileName != NULL ) {
    Status = g_IsoListener.OpenFile(g_OutFileName);
    if ( Status != 0 ) {
      // ERROR !!!
      fprintf(stderr, PFXERR"Open output file '%s' failed (0x%08X)\n",g_OutFileName, Status);
      return 10;
    }
  }

  // prepare an OS-internal device list used for the open call
  HDEVINFO DevList; DevList = NULL;
  // device list will contain devices that provide the VHPD_IID interface
  // please refer to to the documentation (chapter 7.4) for details on how 
  // to define your private interface (strongly recommended)
  const GUID VhpdDefaultIID = VHPD_IID;
  DevList = g_IsoListener.CreateDeviceList(&VhpdDefaultIID);
  if ( DevList == NULL ) {
    // ERROR !!!
    fprintf(stderr, PFXERR"CreateDeviceList failed\n");
    goto Exit;
  }
  // open a handle to a device, we use device zero for now
  Status = g_IsoListener.Open(0,DevList,&VhpdDefaultIID);
  if ( Status != VHPD_STATUS_SUCCESS ) {
    // ERROR !!!
    // this may be caused by the fact that currently no device associated to the
    // VHPD1394 driver is connected to the local node (this computer)
    fprintf(stderr, PFXERR"Failed to open the device (0x%08X)\n",Status);
    goto Exit;
  }
  // device opened, destroy the device list, we don't need it anymore
  g_IsoListener.DestroyDeviceList(DevList);
  DevList = NULL;

  // setup the IsoListener
  // NOTE: we call CVhpdIsoChannel::SetupListen()
  Status = g_IsoListener.SetupListen(
              (g_MaxBytesPerIsoFrame*8000), // expected maximum bandwidth (bytes/s)
              g_FramesPerBuffer,  // isochronous frames hold by a single buffer
              g_NumberOfBuffers,  // number of buffers used for data reception
              g_Channel,          // number of isochronous channel
              g_UsedSpeed,        // transfer speed of isochronous channel
              g_QuadsToStrip      // quadlets to strip from each isochronous frame
              );
  if ( Status != VHPD_STATUS_SUCCESS ) {
    // ERROR !!!
    fprintf(stderr, PFXERR"Failed to initialize receiver (0x%08X)\n",Status);
    goto Exit;
  }

  // start worker thread of g_IsoListener
  // this submits all buffers of the g_IsoListener pool to the driver and
  // finally starts data reception
  if ( !g_IsoListener.StartThread() ) {
    // ERROR !!!
    fprintf(stderr, PFXERR"Failed to start worker thread\n");
    goto Exit;
  }


/*******************************************************************/
// now loop until we are told to exit

  fprintf(stdout, PFX"Receiving isochronous data ... press any key to exit\n");
  for(;;) {
    // query current data rate transported via this file handle
    VHPD_QUERY_RATE_COUNTER RateCount;
    memset(&RateCount,0x0,sizeof(RateCount));
    Status = g_IsoListener.QueryRateCounter(&RateCount);
    if (Status != VHPD_STATUS_SUCCESS) {
      // ERROR !!!
      fprintf(stderr, "\n"PFXERR"Failed to query data rate (0x%08X)",Status);
      break;
    }
    // convert to bytes per second
    __int64 r;
    r = RateCount.CurrentMeanValue/*bytes*/;
    r = (1000*r) / RateCount.FilterDelay/*ms*/;
    // display state of data reception
    fprintf(stdout, PFX"Avg. rate is %I64d Bytes/s  %d buffer errors (last 0x%08X)     \r",
    (__int64)r, g_IsoListener.GetErrorCount(),g_IsoListener.GetLastError());

    // check if thread is still running
    // worker thread may terminate itself, even if ShutdownThread was not called
    // (e.g. because PostProcessBuffer returns false or an internal error was detected)
    if ( g_IsoListener.ThreadExited() ) {
      fprintf(stdout,"\n"PFX"Worker thread has terminated ... aborting.\n");
      break;
    }

    // check for user break
    if ( _kbhit() ) {
      _getch();
      break;
    }

    // suspend some time
    Sleep(500);

  } // for()

  fprintf(stdout, "\n"PFX"Exiting ...\n");

  // stop data reception
  g_IsoListener.StopChannel();

/*******************************************************************/
// ERROR!!! or normal exit

// release claimed resources
Exit:
  if ( !g_IsoListener.ShutdownThread() ) {
    // ERROR !!!
    fprintf(stderr, PFXERR"FATAL: Failed to stop worker thread\n");
  }
  g_IsoListener.CloseFile();
  g_IsoListener.Shutdown();
  g_IsoListener.Close();

  return 0;

} // main

/*************************** EOF **************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -