Digital Video Camcorder Support in Windows 98 and Windows 2000

Microsoft Corporation

March 19, 1999

Summary: This article describes how developers of PC video-editing applications can call certain Microsoft® DirectShow™ application programming interfaces to control a digital video (DV) camcorder device connected to a PC running the Microsoft® Windows® 98 or Windows 2000 operating system. This paper also recommends a mechanism to preserve application performance while the camcorder performs time-consuming operations, and provides reference documentation for the interfaces as implemented by the DV camcorder driver.

Contents

Introduction
Connecting to the Interfaces
Getting Information from a DV Camcorder Device
Controlling a DV Camcorder Device
Managing Time-Consuming Operations
DV Implementation of DirectShow Interfaces
Controlling MSDV from GraphEdit.exe Using the MSDV Property Page

Introduction

Until recently, video editing on personal computers has been impractical for consumers, in part because digitized video data requires huge amounts of storage and no standards exist for control of analog consumer video camcorders. The introduction of the Digital Video (DV) standard addresses these two problems. It is now possible to store up to 20 minutes of digital video data in a 4-gigabyte (GB) file, and DV camcorders comply with standard device-control protocols so software developers can support a wide range of camcorders with a common set of application interfaces.

A Windows 98 or Windows 2000 video-editing application based on DirectShow can control a DV camcorder by calling the interfaces IAMExtDevice, IAMExtTransport, and IAMTimeCodeReader to get device capabilities, status, and timecodes, and to perform standard camcorder device-control operations such as play, rewind, fast-forward, pause, stop, and record.

Currently, all DV camcorders follow the function control protocol (FCP) defined by IEC 61883, Digital Interface for Consumer Electronic Audio/Video Equipment, for the transport of audio/video command requests and responses to DV camcorders attached to the IEEE1394 bus. Although DV cameras are currently limited to the 1394 bus and IEC61883 protocols, the DirectShow interfaces are not. The DV camcorder driver (Msdv.sys) is a Windows Driver Model (WDM) driver that accepts property sets from these DirectShow interfaces and translates them into commands that a DV camcorder can process. This model will allow a single application to control a camcorder that uses any type of protocol over any kind of bus, once a driver is available that can translate property sets into commands that the device can understand.

This article describes how developers of PC video-editing applications can call the DirectShow interfaces IAMExtDevice, IAMExtTransport, and IAMTimeCodeReader to control a DV camcorder device, recommends a mechanism to preserve application performance while the camcorder performs time-consuming operations, and provides reference documentation for the interfaces as implemented by the DV camcorder driver.

Note   The code fragments in this article are taken from the sample property page, DVcrPage.cpp. They have been edited for clarity, and omit code that would be present in a complete application. Developers should follow all recommended practices in their applications, such as using critical sections to protect data from access by multiple threads. For details, see the section "Managing Time-Consuming Operations" later in this article.

Click to copy the DvcrPage sample file.

Connecting to the Interfaces

A DirectShow application that controls a DV camcorder must connect to IAMExtDevice, IAMExtTransport, and IAMTimecodeReader interfaces before it can use them. These interfaces provide the following services:

To connect to the interfaces, the application enumerates devices on the system and obtains a pointer to the DV camcorder device, as described for AV devices in the DirectShow SDK. Briefly, the application:

  1. Creates a system hardware device enumerator by calling CoCreateInstance with CLSID_SystemDeviceEnum and IID_ICreateDevEnum.

  2. Creates an enumerator for a specific type of hardware device by declaring an IEnumMoniker interface pointer and passing it to ICreateDevEnum::CreateClassEnumerator with a device GUID of CLSID_VideoInputDeviceCateogry.

  3. Enumerates the list of devices by calling IEnumMoniker::Next.

  4. Calls IMoniker::BindToStorage to load the CLSID, friendly name, and device path for each device.

  5. Offers the user a list of friendly names that can be selected.
    If a DV camcorder is connected to the system, Msdv.sys would be in this list as "Microsoft DV Camera and VCR."

  6. Matches the user's choice to the information cached in Step 4.

  7. Calls IMoniker::BindToObject with the corresponding device path and the IID of one of the desired interfaces (for example, IID_IAMExtDevice). This creates the filter associated with the device and retrieves a pointer to that interface.

  8. Calls QueryInterface on the interface obtained in Step 7 to get pointers to the other interfaces that the application will use.

To use the DV implementation of the DirectShow interfaces, an application must include XprtDefs.h. This file contains all the definitions found in Edevdefs.h with additions that support DV camcorders.

For a complete discussion of enumerating and accessing hardware devices in DirectShow applications, see the DirectShow SDK, located at www.microsoft.com/directx/dxm/help/ds/default.htm.

Click to copy the XprtDefs sample file.

Getting Information from a DV Camcorder Device

A video-editing application would get information from a DV camcorder device to initialize its user interface (for example, controls in a dialog box or on a property page) and to update it after issuing commands to the device. For example, an application might:

Getting Device Capabilities

An application uses IAMExtDevice::GetCapability to find out the capabilities of the DV camcorder device—most importantly, whether the device is a full-fledged VCR or a DV camera that can only record or pause recording.

The following code fragment shows how an application would determine whether the device is a VCR or a camera and use that information to initialize dialog box controls. In this example, m_pDVcrExtDevice is a property page class member previously initialized with a pointer to IAMExtDevice. LoadIconOnTopOfButton is an internal function that covers textual buttons with graphics.

LONG lDeviceType = 0;
char szBuf[32];

m_pDVcrExtDevice->GetCapability(ED_DEVCAP_DEVICE_TYPE, &lDeviceType, 0);

// VCR can perform all operations; enable VCR-specific controls
if(lDeviceType == ED_DEVTYPE_VCR) {
   LoadString(g_hInst, IDS_DEVTYPE_VCR, szBuf, sizeof(szBuf));
   SetDlgItemText(m_hwnd, IDC_GBX_DEVICE_TYPE, szBuf);
   // Replace push buttons with icons
   LoadIconOnTopOfButton(IDC_BTN_DV_PLAY,    IDI_PLAY);
   LoadIconOnTopOfButton(IDC_BTN_DV_PAUSE,   IDI_PAUSE);
   LoadIconOnTopOfButton(IDC_BTN_DV_STOP,    IDI_STOP_EJECT);
   LoadIconOnTopOfButton(IDC_BTN_DV_RWND,    IDI_RWND);
   LoadIconOnTopOfButton(IDC_BTN_DV_FFWD,    IDI_FFWD);
   LoadIconOnTopOfButton(IDC_BTN_DV_STEP_FWD,IDI_STEP_FWD);
   LoadIconOnTopOfButton(IDC_BTN_DV_STEP_REV,IDI_STEP_REV);
} else {
   // Camera can only RECORD and RECORD_PAUSE; disable VCR-specific controls
   LoadString(g_hInst, IDS_DEVTYPE_CAMERA, szBuf, sizeof (szBuf));
   SetDlgItemText(m_hwnd, IDC_GBX_DEVICE_TYPE, szBuf);
   ShowWindow(GetDlgItem(m_hwnd, IDC_BTN_DV_PLAY),     FALSE);
   ShowWindow(GetDlgItem(m_hwnd, IDC_BTN_DV_PAUSE),    FALSE);
   ShowWindow(GetDlgItem(m_hwnd, IDC_BTN_DV_STOP),     FALSE);
   ShowWindow(GetDlgItem(m_hwnd, IDC_BTN_DV_RWND),     FALSE);
   ShowWindow(GetDlgItem(m_hwnd, IDC_BTN_DV_FFWD),     FALSE);
   ShowWindow(GetDlgItem(m_hwnd, IDC_BTN_DV_STEP_FWD), FALSE);
   ShowWindow(GetDlgItem(m_hwnd, IDC_BTN_DV_STEP_REV), FALSE);
   ShowWindow(GetDlgItem(m_hwnd, IDC_CHK_SLOW),        FALSE);
} 

// Both VCR and camera can RECORD and RECORD_PAUSE 
LoadIconOnTopOfButton(IDC_BTN_DV_RECORD,IDI_RECORD);
LoadIconOnTopOfButton(IDC_BTN_DV_RECORD_PAUSE,IDI_RECORD_PAUSE);

Getting Information about Media

An application uses IAMExtTransport::GetStatus to get information about the media in the device. The following code fragment shows how an application would determine whether the DV camcorder contains a tape and whether the tape is write-protected. In this example, m_pDVcrExtTransport is a property page class member previously initialized with a pointer to IAMExtTransport.

LONG lMediaType = 0;
BOOL bRecordInhibit = FALSE;

// Find out whether the transport contains a tape
m_pDVcrExtTransport->GetStatus(ED_MEDIA_TYPE, &lMediaType);
if(lMediaType == ED_MEDIA_NOT_PRESENT)
   SendMessage (GetDlgItem(m_hwnd, IDC_CHK_NO_TAPE),BM_SETCHECK, 1, 0);

// Find out whether tape is write-protected
m_pDVcrExtTransport->GetStatus(ED_RECORD_INHIBIT, (long *)&bRecordInhibit);
if(bRecordInhibit)    
   SendMessage (GetDlgItem(m_hwnd, IDC_CHK_WRITE_PROTECTED),BM_SETCHECK, 1, 0);

Getting Information about the Transport

An application should check the state of the DV camcorder's transport on initialization and after any command that might change the transport state. Because the device might not be able to respond immediately after such a command, an application should be prepared to handle a pending result. For details, see the section "Managing Time-Consuming Operations" later in this article.

The following code fragment shows how an application would call IAMExtTransport::GetTransportVideoParameters to determine the input signal mode of the device and then call IAMExtTransport::get_Mode to get the current state of the transport (playing, paused, recording, and so on). UpdateTransportState is an internal function that updates controls on a property page.

long lCurXPrtState;
LONG lInSignalMode = 0;

// Determine the input signal mode (NTS/PAL, SD/SDL)
m_pDVcrExtTransport->GetTransportVideoParameters(ED_MODE_SIGNAL_INPUT, &lInSignalMode);

if(ED_MODE_SIGNAL_525_60_SD == lInSignalMode)
   SendMessage (GetDlgItem(m_hwnd, IDC_RADO_SD_525_60),BM_SETCHECK, 1, 0);
else if(ED_MODE_SIGNAL_525_60_SDL == lInSignalMode)
   SendMessage (GetDlgItem(m_hwnd, IDC_RADO_SDL_525_60),BM_SETCHECK, 1, 0);
else if(ED_MODE_SIGNAL_625_50_SD == lInSignalMode)
   SendMessage (GetDlgItem(m_hwnd, IDC_RADO_SD_525_50),BM_SETCHECK, 1, 0);
else if(ED_MODE_SIGNAL_625_50_SDL == lInSignalMode)
   SendMessage (GetDlgItem(m_hwnd, IDC_RADO_SDL_525_50),BM_SETCHECK, 1, 0);
else {
   // Unsupported but still want to know if it is used.
   wsprintf(szBuf, "%x", lInSignalMode);  
   SetWindowText(GetDlgItem (m_hwnd, IDC_EDT_INPUT_SIGNAL), szBuf);
}

// Determine the current transport state and set controls accordingly
m_pDVcrExtTransport->get_Mode(&lCurXPrtState);
if(lDeviceType == ED_DEVTYPE_VCR)
   UpdateTransportState(lCurXPrtState); 

Getting Timecode and Track Number Data

An application can get current timecode and track number data from a DV tape while the tape is playing or in RecordPause state.

When the tape is playing, the DV implementation of IAMTimecodeReader::GetTimecode retrieves SMTPE timecode data from the video stream, so it is not subject to the time lag involved in sending a request to the device. If the transport is in a Pause state, ::GetTimecode executes a device control command to get the timecode from the current position on the tape.

The following code fragment shows how an application might call GetTimecode to retrieve the current timecode and absolute track number from a tape. In this example, m_pDVcrTmCdReader is a property page class member previously initialized with a pointer to IAMTimecodeReader. DisplayTimecode is an internal function that displays the timecode and track number on the property page.

TIMECODE_SAMPLE TimecodeSample;
TimecodeSample.timecode.dwFrames = 0;
TimecodeSample.dwFlags = ED_DEVCAP_TIMECODE_READ;

if(S_OK == m_pDVcrTmCdReader->GetTimecode(&TimecodeSample)) {
   DisplayTimecode(&TimecodeSample);                
   TimecodeSample.dwFlags = ED_DEVCAP_ATN_READ;
   if(S_OK == m_pDVcrTmCdReader->GetTimecode(&TimecodeSample))
      DisplayTimecode(&TimecodeSample);                
}

Controlling a DV Camcorder Device

An application issues commands to the device to perform standard camcorder operations such as play, rewind, fast forward, pause, stop, and record. (An application developer can also send commands to the device using the edit box on the property page when the debug version of the driver is loaded.)

Performing Standard Operations

An application uses IAMExtTransport::put_Mode to perform standard camcorder operations. For example, the following code fragment shows how an application would play a tape.

if(NOERROR == (hr = m_pDVcrExtTransport->put_Mode(ED_MODE_PLAY)))
   UpdateTransportState(ED_MODE_PLAY); 

The application can perform other operations by calling put_Mode with other mode flags:

If the DV camcorder supports trick play modes, the user can specify whether to fast-forward or rewind a tape at a faster or slower rate while the tape is playing. An application would handle such a request as in the following code fragment. In this example, m_lCurXPrtState, which is a data member of a property page class, contains the current transport state. BST_CHECKED is the state of a checkbox that indicates the user's choice on the property page.

if(m_lCurXPrtState == ED_MODE_STOP) {      // Tape is stopped
   if(NOERROR == (hr = m_pDVcrExtTransport->put_Mode(ED_MODE_FF)))
      UpdateTransportState(ED_MODE_FF);
   } else {                           // Tape is playing
      HRESULT hrChecked;
      long lMode;
      hrChecked = SendMessage (GetDlgItem(m_hwnd, IDC_CHK_SLOW),
                                 BM_GETCHECK, 0, 0);
      lMode = hrChecked == BST_CHECKED ? ED_MODE_PLAY_SLOWEST_FWD : 
                                 ED_MODE_PLAY_FASTEST_FWD;
      if(NOERROR == (hr = m_pDVcrExtTransport->put_Mode(lMode)))
         UpdateTransportState(lMode);
      }
   }

Issuing Vendor-Dependent Commands

In addition to the standard operations defined in the AV/C VCR Subunit specification, some independent hardware vendors (IHVs) specify a set of vendor-dependent commands.

An application can issue vendor-dependent commands to a device by calling IAMExtTransport::GetTransportBasicParameters with ED_RAW_EXT_DEV_CMD and passing the number of bytes in the command and a pointer to a BYTE array that contains the vendor-dependent command.

For example:

hr = m_pDVcrExtTransport->GetTransportBasicParameters(ED_RAW_EXT_DEV_CMD, &cntByte, (LPOLESTR *)bAvcRaw);

This usage of GetTransportBasicParameters is strictly a pass-through service. The application is responsible for all command validation and error checking.

Managing Time-Consuming Operations

Because a DV camcorder is a physical device, a developer must consider the time lag involved in certain operations, such as rewinding a tape. An application that controls a DV camcorder should handle time-consuming operations gracefully—notifying the user when the device is busy, maintaining a responsive user interface, and allowing the user to cancel pending operations.

The AV/C specification requires that a device must respond to a command within 100 milliseconds. However, if the requested operation cannot be completed within that time, the device can respond with a "pending" status. Unless the requesting application implements a mechanism to handle pending operations, it will hang until the device finishes the operation.

An application should implement a secondary thread to wait for notification that a pending operation is complete. This allows an application to maintain a more responsive UI because its primary thread can continue to work. For example, an application might monitor subsequent user requests and cancel a pending operation if it would make sense to do so, as when the device is rewinding a tape and the user issues a play command. Monitoring user requests also allows the application to protect the device from "button bashing"—being overwhelmed by the user issuing too many requests too quickly.

To handle time-consuming operations gracefully, an application should:

  1. Create a thread to wait for notification that a time-consuming command has finished.

  2. Create an event to signal completion of such a command.

  3. Call IAMExtTransport::GetStatus with ED_NOTIFY_HEVENT_GET and the address of the event to enable the device to signal the event.

  4. Call IAMExtTransport::GetStatus with ED_MODE_CHANGE_NOTIFY and the address of a local LONG to get the status of the transport.

  5. If the GetStatus call in step (4) returns a pending status, wait for the event to signal that the operation has finished.

  6. Release the event by calling IAMExtTransport::GetStatus with ED_NOTIFY_HEVENT_RELEASE.

The following code fragment shows how an application might implement such a mechanism in its main thread procedure. In this example:

HANDLE  Eventhandles[2];
HANDLE  hEvent = NULL;
LONG    lXPrtState;

// Get an event that will be signalled when the pending operation finishes.
hr = m_pDVcrExtTransport->GetStatus(ED_NOTIFY_HEVENT_GET, (long *) &hEvent);

while (m_hThread && hEvent && m_hThreadEndEvent) {

// Serialize the command among threads; only one active command is allowed.
// GetStatus writes the transport state to lXprtState .
   EnterCriticalSection(&m_csIssueCmd);  
      lXPrtState = 0;
      hr = m_pDVcrExtTransport->GetStatus(ED_MODE_CHANGE_NOTIFY, &lXPrtState);
   LeaveCriticalSection(&m_csIssueCmd); 

// Check for pending operation.
   if(hr == E_PENDING) {
      // Expect this call to complete asychronously.
      EventHandles[0] = hEvent;
      EventHandles[1] = m_hThreadEndEvent;
      WaitStatus = WaitForMultipleObjects(2, EventHandles, FALSE, INFINITE);

// Event signalled that the pending operation finished. 
// The COM interface calls SetLastError() with the final return code.
      if(WAIT_OBJECT_0 == WaitStatus) {  
         dwFinalRC = GetLastError();  
         UpdateTransportState(lXPrtState);

// Notification thread ended for a valid reason (e.g. user dismissed application).
      } else if (WAIT_OBJECT_0+1 == WaitStatus) {
         return 0;
         break;  // End this thread.
      } else {
         break;  // End this thread.

// Check for unexpected behavior or status other than pending.

// Release the event obtained with the earlier GetStatus call.
// The COM interface must not write to lXprtState after this call.
hr = m_pDVcrExtTransport->GetStatus(ED_NOTIFY_HEVENT_RELEASE, (long *) &hEvent);

DV Implementation of DirectShow Interfaces

This section contains reference information about the DV implementation of IAMExtDevice, IAMExtTransport, and IAMTimecodeReader. It lists the methods supported by the DV implementation and describes additional parameter values. This information supplements the documentation provided for these interfaces and methods in the DirectShow SDK.

Parameter values are defined in XprtDefs.h.

IAMExtDevice

IAMExtDevice is the base interface for controlling external devices. It controls general settings of external hardware and is used in combination with the IAMExtTransport interface, which controls a DV camcorder's more specific settings.

In addition to the standard IUnknown methods QueryInterface, AddRef, and Release, the DV camcorder implementation of IAMExtDevice provides the following methods. Methods not listed return E_NOTIMPL. Additional DV implementation-specific details follow this table.

GetCapability Retrieves the capabilities of the DV camcorder.
get_ExternalDeviceID The DV implementation retrieves the symbolic link of the DV camcorder device, which is guaranteed to be unique, even for two identical DV devices that are connected simultaneously to the IEEE 1394 bus.
get_ExternalDeviceVersion The DV implementation retrieves the version of the AV/C Digital Interface Command Set (VCR Subunit Specification) supported by the DV camcorder.
get_DevicePower Retrieves whether the DV camcorder's power mode is on. If the camcorder is off or in standby mode, this method will return an error code.
get_DevicePort Specifies the communication port to which the DV camcorder is connected. The DV implementation currently specifies only DEV_PORT_1394.

IAMExtDevice::GetCapability

HRESULT GetCapability(

long Capability,
long *pValue,
double *pdblValue );

The DV implementation of IAMExtDevice::GetCapability can return the following values to pValue when called with a Capability value of ED_DEVCAP_DEVICE_TYPE.

ED_DEVTYPE_CAMERA Simple camera that can only record or pause recording.
ED_DEVTYPE_UNKNOWN Unrecognized device type; returned when there is no tape and the drive cannot issue the play command. The application must advise the user to insert a tape and try the command again. This is returned when GetCapability(ED_DEVCAP_DEVICE_TYPE,&DeviceType, 0). Determine whether the tape is present though
hr=m_pDVcrExtTranport-> GetStatus(ED_MEDIA_TYPE,&ImediaType).

IAMExtTransport

IAMExtTransport provides methods that control specific behaviors of an external DV camcorder. These methods generally set and get the transport properties, which relate to how the DV camcorder and the computer exchange data.

In addition to the standard IUnknown methods QueryInterface, AddRef, and Release, the DV camcorder implementation of IAMExtTransport provides the following methods. Methods not listed return E_NOTIMPL. Additional DV implementation-specific details follow this table.

GetCapability Retrieves the general capabilities of a DV camcorder's transport.
put_MediaState Sets the current state of the videotape.
get_MediaState Retrieves the current state of the videotape.
GetStatus Determines the status of the transport.
GetTransportBasicParameters Retrieves the transport's basic parameter settings.
SetTransportBasicParameters Sets the transport's basic parameters.
GetTransportVideoParameters Retrieves the transport's video parameter settings.
SetTransportVideoParameters Sets the transport's video parameter settings.
GetTransportAudioParameters Retrieves the transport's audio parameter settings.
SetTransportAudioParameters Sets the transport's audio parameter settings.
put_Mode Sets the movement of the transport to a new mode (play, stop, record, edit, and so on).
get_Mode Retrieves the mode of the transport (play, stop, record, edit, and so on).

IAMExtTransport::GetStatus

HRESULT GetStatus(

long StatusItem,
long *pValue );

The DV implementation of IAMExtTransport::GetStatus adds the following StatusItem values:

ED_MODE_CHANGE_NOTIFY Requests the device to signal the event previously obtained by calling GetStatus with ED_NOTIFY_HEVENT_GET. On return, pValue is set to one of the following:

E_PENDING—The device accepted the command but cannot respond because it is busy.

NOERROR—The command finished without error.

ERROR_GEN_FAILURE—The device rejected the command.

ERROR_INVALID_FUNCTION—The device does not support the command.

ERROR_SEM_TIMEOUT—The device failed to respond within 100 milliseconds.

ERROR_INVALID_PARAMETER—The command was passed with an invalid parameter.

ED_NOTIFY_HEVENT_GET Gets a handle to an event. If subsequently calling GetStatus with ED_MODE_CHANGE_NOTIFY returns E_PENDING, an application can wait on this event using WaitForXxxObject (a non-busy wait).
ED_NOTIFY_HEVENT_RELEASE Releases an event previously obtained by calling GetStatus with ED_NOTIFY_HEVENT_GET. Even if the pending operation finishes, the application will not be signaled. On return, the pointer pValue is no longer valid and should not be used.
ED_MEDIA_TYPE Retrieves the type of media in the transport. On return, pValue is set to one of the following:

ED_MEDIA_DVC—The transport contains a DV tape.

ED_MEDIA_NOT_PRESENT—The transport is empty.

ED_MEDIA_UNKNOWN—The transport contains a tape of an unrecognized type.


IAMExtTransport::GetTransportBasicParameters

HRESULT GetTransportBasicParameters(

long Param,
long *pValue,
LPOLESTR *ppszData );

The DV implementation of IAMExtTransport::GetTransportBasicParameters adds the following Param value.

ED_RAW_EXT_DEV_CMD Invokes the vendor-dependent command specified at ppSzData, which is passed through to the device with no validation or error checking. The caller must set pValue to the number of bytes at ppSzData.

IAMExtTransport::GetTransportVideoParameters

HRESULT GetTransportVideoParameters(

long Param,
long *pValue );

The DV implementation of IAMExtTransport::GetTransportVideoParameters adds the following Param values.

ED_MODE_SIGNAL_INPUT Retrieves the signal format that the DV camcorder is designed to accept. On return, pValue can be one of the following values:

ED_MODE_SIGNAL_525_60_SD—NTSC signal.

ED_MODE_SIGNAL_525_60_SDL—NTSC long play signal.

ED_MODE_SIGNAL_625_50_SD—PAL signal.

ED_MODE_SIGNAL_625_50_SDL—PAL long play signal.

ED_MODE_SIGNAL_OUTPUT Retrieves the signal format that the DV camcorder is designed to transmit. On return, pValue can be any of the values listed for ED_MODE_SIGNAL_INPUT.

IAMExtTransport::put_Mode

The DV implementation of IAMExtTransport::put_Mode adds the following Mode values, which can also be used with IAMExtTransport::get_Mode.

ED_MODE_PLAY_FASTEST_FWD Forward the tape at the fastest speed supported by the device.
ED_MODE_PLAY_SLOWEST_FWD Forward the tape at the slowest speed supported by the device.
ED_MODE_PLAY_FASTEST_REV Reverse the tape at the fastest speed supported by the device.
ED_MODE_PLAY_SLOWEST_REV Reverse the tape at the slowest speed supported by the device.

IAMExtTransport::get_Mode

The DV implementation of IAMExtTransport::get_Mode adds the following Mode values.

ED_MODE_WIND The transport is stopped or it is rewinding or fast-forwarding the tape. This is an internal COM interface and is not exposed.
ED_MODE_REW_FASTEST The transport is rewinding the tape at high speed.

IAMTimecodeReader

IAMTimecodeReader reads SMPTE (Society of Motion Picture and Television Engineers) timecode from a DV camcorder.

In addition to the standard IUnknown methods QueryInterface, AddRef, and Release, the DV camcorder implementation of IAMTimecodeReader provides the following method. Methods not listed return E_NOTIMPL. Additional DV implementation-specific details follow this table.

GetTimecode Retrieves the most recent timecode, userbits, and flag values available in the stream.

IAMTimecodeReader

HRESULT GetTimecode(

PTIMECODE_SAMPLE pTimecodeSample );

In addition to ED_DEVCAP_TIMECODE_READ, the DV implementation of IAMTimecodeReader::GetTimecode defines the following pTimecodeSample->dwFlags values.

ED_DEVCAP_ATN_READ Retrieves the absolute track number from the beginning of the tape. This count monotonically increases from the beginning of the tape, whereas the SMPTE time code can restart at 00:00:00 for different recorded segments on the tape on some models of DV camcorders.

Interfaces Not Implemented

The following DirectShow interfaces are not implemented in the DV support for Windows 98 and Windows 2000:

put_MediaState(),

get_MediaState()

SetTransportBasicParameters()

GetTransportVideoParameters()

SetTransportVideoParameters()

GetTransportAudioParameters()

SetTransportAudioParameters()

Controlling MSDV from GraphEdt.exe Using the MSDV Property Page

Using Graphedt.exe (from DirectX Media SDK) you can build a number of graphs to experiment with MSDV. Here are some of the basic graphs you can construct for capturing DV files, playback of DV files, and transmission of DV files from the computer to a DV camcorder or DVCR.

Capture and Preview

This graph captures a DV stream from the camcorder to an AVI file while viewing the stream.

Playback

This graph plays a DV stream from a file to an active movie window.

Transmit

This graph plays a DV stream from a file to the camcorder (for recording to tape).

Microsoft DV Camera and VCR Property Page

From any graph containing the Microsoft DV Camera and VCR filter, you can open the following property page. This property page allows you to send commands to the camcorder. The following view shows the property page in VCR mode. In this mode, the property page displays information about the tape, timecode, and track number (ATN).

Control buttons in the bottom left section of the page can be used to control the transport. Commands for play, pause, fast forward, and rewind are available. When in pause state, buttons appear for frame advance and frame rewind. If the Slow box is checked, fast forward or rewind will play in slow motion. You can also queue the camera using PauseRecord, then use Record when transmitting to record AVI files to the tape.

The edit field in the Property Page is used to send a raw AV/C command to the device. This field is only visible when using the debug version of MSDV.sys.

---------------------------------------------

This document is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS DOCUMENT.

Microsoft Corporation may have patents or pending patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. The furnishing of this document does not give you any license to the patents, trademarks, copyrights, or other intellectual property rights except as expressly provided in any written license agreement from Microsoft Corporation.

Microsoft does not make any representation or warranty regarding specifications in this document or any product or item developed based on these specifications. Microsoft disclaims all express and implied warranties, including but not limited to the implied warranties or merchantability, fitness for a particular purpose and freedom from infringement. Without limiting the generality of the foregoing, Microsoft does not make any warranty of any kind that any item developed based on these specifications, or any portion of a specification, will not infringe any copyright, patent, trade secret or other intellectual property right of any person or entity in any country. It is your responsibility to seek licenses for such intellectual property rights where appropriate. Microsoft shall not be liable for any damages arising out of or in connection with the use of these specifications, including liability for lost profit, business interruption, or any other damages whatsoever. Some states do not allow the exclusion or limitation of liability or consequential or incidental damages; the above limitation may not apply to you.

Microsoft, DirectShow, Win32, Windows, and Windows NT are registered trademarks of Microsoft Corporation. Other product and company names mentioned herein may be the trademarks of their respective owners.

© 1999 Microsoft Corporation. All rights reserved.