Digital Video Camcorder Support in Windows — 14

Platform Design Notes

Designing Hardware and Drivers for the Microsoft® Windows® Family of Operating Systems

Digital Video Camcorder Support in Windows

Abstract

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® operating system. This paper also recommends a mechanism to preserve application performance while the camcorder performs time-consuming operations. The information in this paper applies to for Windows 98 SE, Windows Millennium Edition, Windows 2000, and Windows XP.

Note: Msdv.sys is a kernel streaming minidriver that utilizes the system-supplied streaming class driver, Stream.sys, to control a DVcamcorder device. For documentation about writing kernel streaming minidrivers, see "Streaming Devices" in the Windows DDK.

September 28, 2001

Contents

Introduction 3

Connecting to the Interfaces 3

Getting Information from a DVCamcorder Device 5

Getting Device Capabilities 5

Getting Information about Media 5

Getting Information about the Signal Mode and Transport State 6

Getting Timecode and Track Number Data 6

Controlling a DVCamcorder Device 7

Performing Standard Operations 7

Issuing Raw AV/C Commands 8

Registering for Removal Events 10

Managing Time-Consuming Operations 11

Controlling MSDV from GraphEdt.exe Using the MSDV Property Page 11

Microsoft Disclaimer: 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.

© 2001 Microsoft Corporation. All rights reserved.

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 because 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 file of approximately 4GB on a FAT32 system (the file size limit). A file on an NTFS system can store as much digital video data as will fit in the maximum file size on that system (the size of the disk partition).

·  DVcamcorders 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 video-editing application based on DirectShow can control a DVcamcorder 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 DVcamcorders 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 DVcamcorders attached to the IEEE1394 bus. Although DV cameras are currently limited to the 1394 bus and IEC61883 protocols, the DirectShow interfaces are not. The DVcamcorder driver (Msdv.sys) is a WDM driver that accepts property sets from these DirectShow interfaces and translates them into commands that a DVcamcorder 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 DVcamcorder device, recommends a mechanism to preserve application performance while the camcorder performs time-consuming operations. These interfaces are documented in the DirectX 8.1 SDK.

Note: The code fragments in this article are taken from the sample property page, DVcrPage.cpp. The sample consists only of this source code file and does not include a make file or other files needed to compile the sample. Code fragments have been edited for clarity, and they omit code that would be present in a complete application. Developers should follow all recommended practices in their applications, such as use of critical sections to protect data from access by multiple threads. For details, see “Managing Time-Consuming Operations” later in this article.

Connecting to the Interfaces

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

·  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 DVcamcorder’s more specific settings.

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

·  IAMTimecodeReader reads SMPTE (Society of Motion Picture and Television Engineers) timecode and absolute track number (ATN) from a DVcamcorder.

To connect to the interfaces, the application enumerates devices on the system and obtains a pointer to the DVcamcorder device, as described 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_VideoInputDeviceCategory.

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

4. Calls IMoniker::BindToStorage to load the CLSID, FriendlyName, DevicePath, and Description for each device.

Developers are encouraged to display Description, if supported, instead of FriendlyName to users, because Description provides a more specific identification of the device.

5. Offers the user a list of friendly names that can be selected.

If a DVcamcorder is connected to the system, Msdv.sys would appear in this list as “Microsoft DV Camera and VCR.” This string could be localized; check Msdv.inf files for localized versions of Windows.

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 DVimplementation of the DirectShow interfaces, an application must include Xprtdefs.h. This file contains all the definitions found in Edevdefs.h with additions that support DVcamcorders.

For a complete discussion of enumerating and accessing hardware devices in DirectShow applications, see the DirectShow SDK.

Getting Information from a DVCamcorder Device

A video-editing application would get information from a DVcamcorder 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:

1. Determine device capabilities, device ID, and mode of operation (VCR or camera), and enable or disable controls accordingly.

2. Determine whether the transport contains media, the type of the media, and whether it is write-protected.

3. Determine whether the device supports DV (NTSC or PAL) or MPEG2TS signal mode.

4. Monitor the current state of the transport and update its user interface with fresh information—for example, whether the device is currently playing a tape.

Getting Device Capabilities

An application uses IAMExtDevice::GetCapability to find out the capabilities of the DVcamcorder 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.

LONG lDeviceType = 0;

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

if(lDeviceType == ED_DEVTYPE_VCR) {

//lDeviceType can be one of the following:

// ED_DEVTYPE_VCR

// ED_DEVTYPE_CAMERA

// ED_DEVTYPE_UNKNOWN

// If ED_DEVTYPE_VCR, enable VCR-specific controls.

} else {

// Camera can only RECORD and RECORD_PAUSE.

// Unknown device is assumed not to have VCR capabilities.

// If ED_DEVTYPE_CAMERA or ED_DEVTYPE_UNKNOWN,

// disable VCR-specific controls.

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 DVcamcorder contains a tape and whether the tape is write-protected. This fragment assumes that the device type is ED_DEVTYPE_VCR and the device has recording capabilities, as determined by a previous call to GetCapabilities with ED_DEVCAP_DEVICE_TYPE combined with ED_DEVCAP_CAN_RECORD.

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);

// Media type can be one of the following:

// ED_MEDIA_NOT_PRESENT

// ED_MEDIA_DVC

// ED_MEDIA_VHS

// Find out whether tape is write-protected

m_pDVcrExtTransport->GetStatus(ED_RECORD_INHIBIT, (long *)&bRecordInhibit);

Getting Information about the Signal Mode and Transport State

An application should check the state of the DVcamcorder’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 “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).

long lCurXPrtState;

LONG lInSignalMode = 0;

// Determine the input signal mode (NTS/PAL, SD/SDL)

m_pDVcrExtTransport->GetTransportVideoParameters(ED_MODE_SIGNAL_INPUT, &lInSignalMode);

// Update property page controls according to lInSignalMode.

// lInSignalMode can be one of the following:

// ED_MODE_SIGNAL_525_60_SD

// ED_MODE_SIGNAL_525_60_SDL

// ED_MODE_SIGNAL_625_50_SD

// ED_MODE_SIGNAL_625_50_SDL

// ED_MODE_SIGNAL_MPEG2TS

// Determine the current transport state and set controls accordingly

m_pDVcrExtTransport->get_Mode(&lCurXPrtState);

// For a list of valid modes, see IAMExtTransport::put_Mode

// and IAMExtTransport::get_Mode later in this document.

Getting Timecode and Track Number Data

An application can get current timecode and track number data from a DV tape while it is playing or paused. 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

TIMECODE_SAMPLE TimecodeSample;

TimecodeSample.timecode.dwFrames = 0;

TimecodeSample.dwFlags = ED_DEVCAP_TIMECODE_READ;

hr = m_pDVcrTmCdReader->GetTimecode(&TimecodeSample);

The TIMECODE_SAMPLE structure is defined in the DirectShow SDK:

typedef struct tagTIMECODE_SAMPLE {

LONGLONG qwTick;

TIMECODE timecode;

DWORD dwUser;

DWORD dwFlags;

} TIMECODE_SAMPLE;

In the TIMECODE_SAMPLE structure for this example:

·  dwUser is set to 0x1 0x0 ‘BF’, where BF is a “blank flag” that indicates discontinuity.

·  dwFlags is set to ED_DEVCAP_TIMECODE_READ, which is specific to the DVcamcorder implementation.

The TIMECODE_SAMPLE structure has a TIMECODE structure as a member:

typedef struct tagTIMECODE {

WORD wFrameRate;

WORD wFrameFract;

DWORD dwFrames;

}TIMECODE;

In the TIMECODE structure for this example:

·  dwFrames contains a timecode in the format 0xhhmmssff (hours, minutes, seconds, and frames).

If dwFlags in a TIMECODE_SAMPLE structure is set to ED_DEVCAP_ATN_READ, then dwUser is set to the “blank flag” and timecode.dwFrames contains the track number.

For more information about the TIMECODE_SAMPLE and TIMECODE structures, see the DirectShow SDK documentation.

Controlling a DVCamcorder 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.

hr = m_pDVcrExtTransport->put_Mode(ED_MODE_PLAY)

// If hr is NOERROR, the play operation succeeded

The application can perform other operations by calling put_Mode with other mode flags, such as ED_MORE_FREEZE or ED_MODE_STEP_FWD. For a list of the modes supported by put_Mode, see IAMExtTransport::put_Mode later in this document.

IAMExtTransport::get_Mode implements two additional flags, ED_MODE_REW_FASTEST (fastest rewrind) and ED_MODE_REV_PLAY (reverse play). An application can determine whether the device is in these modes by calling get_Mode, but it cannot put the device into these modes with put_Mode.