Solved

Changing video source input from NTSC to PAL

Posted on 2002-05-04
16
531 Views
Last Modified: 2010-04-04
I have an application that is snapping frames from video input provided by a PAL format video device. I have a frame grabber card which defaults to expecting NTSC format though this can be changed to PAL by using the appropriate dialog displayed by the driver (via the MCI API).

However, I do not want to use this dialog and do it programmatically instead.

I have hunted around in the MSDN MCI API help which is very vague on the subject :-(

Any help is appreciated!

Cheers,

Raymond.
0
Comment
Question by:rwilson032697
  • 8
  • 6
  • 2
16 Comments
 
LVL 17

Expert Comment

by:inthe
ID: 6991010
hi ray :)
i dunno if this'll help ,i dont have a card to test anything on but i searched my vc msdn and (after alot of searching )found
MCI_SETVIDEO which can pass MCI_DGV_SETVIDEO_ITEM which is can be passed

MCI_DGV_SETVIDEO_SRC_NTSC
[Specifies NTSC. ]

MCI_DGV_SETVIDEO_SRC_PAL
[Specifies PAL. ]

if you have a copy locally just search for one of the above consts else its here on ms site:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/mmcmd_74fj.asp

The consts are declared in DIGITALV.H
"Include file for the MCI Digital Video Command Set"

/* values for the dwTo field of MCI_SETVIDEO_PARMS
   used with MCI_DGV_SETVIDEO_SOURCE */

#define MCI_DGV_SETVIDEO_SRC_NTSC           0x00004000L
#define MCI_DGV_SETVIDEO_SRC_RGB            0x00004001L
#define MCI_DGV_SETVIDEO_SRC_SVIDEO         0x00004002L
#define MCI_DGV_SETVIDEO_SRC_PAL            0x00004003L
#define MCI_DGV_SETVIDEO_SRC_SECAM          0x00004004L
#define MCI_DGV_SETVIDEO_SRC_GENERIC        0x00004005L


you might want to take a look at DIGITALV.H as it has alot of stuff in it i havent seen declared for delphi before.(its in patformSDK and vc)

Regards Barry
0
 
LVL 17

Expert Comment

by:inthe
ID: 6991090
This may be complete nonsense but i had to have a go ,
well it compiles at least so may give a starting point.. :-)

uses mmsystem;

procedure TForm1.Button1Click(Sender: TObject);
type
MCI_DGV_SETVIDEO_PARMS = record
    dwCallback     : DWORD;
    dwItem         : DWORD;
    dwValue        : DWORD;
    dwOver         : DWORD;
    lpstrQuality   : PChar;
    lpstrAlgorithm : PChar;
    dwSourceNumber : DWORD;
end;
const
 MCI_DGV_SETVIDEO_SRC_NTSC = $00004000;
 MCI_DGV_SETVIDEO_SRC_PAL  = $00004003;
 MCI_DGV_SETVIDEO_ITEM     = $00100000;
var
sv : MCI_DGV_SETVIDEO_PARMS;
Flags : Integer;
e : integer;
begin
e := 0;
sv.dwItem := MCI_DGV_SETVIDEO_ITEM;
sv.dwValue := MCI_DGV_SETVIDEO_SRC_PAL;
SV.dwCallback := Form1.Handle;
Flags := MCI_NOTIFY + MCI_SET;
e := MCISendCommand(1,MCI_SET_VIDEO,Flags,LongInt(@sv));
showmessage(inttostr(e));
end;

when i run it i get error 274

"The MCI device you are using does not support the
specified command."
 which would be right for me as i have no card.
let us know how you get on.
Regards Barry
0
 
LVL 17

Expert Comment

by:inthe
ID: 6991094
ps,
i was unsure of the proper flags to use but i assume the above two MCI_NOTIFY + MCI_SET are at least needed.
couldnt really find much info on Flags apart from the three main ones..
0
 
LVL 12

Author Comment

by:rwilson032697
ID: 6992097
Hi Barry!

Looks like you may be onto it there. Unfortunately my dev machine doesn't have a frame grabber card in it either, the client machine does (makes for interesting debugging!).

I'll give this a go, see where I get with it and let you know (hopefully in a couple of days).

Cheers,

Raymond.
0
 
LVL 17

Expert Comment

by:inthe
ID: 6992779
ok ,
 oh and i guess you realise but just in case not better get a proper deviceid for first param of mciSendCommand,i just chucked a 1 in to stop compiler errors ;)
0
 
LVL 12

Author Comment

by:rwilson032697
ID: 7005424
Barry,

Got to the clients machine to test it out without much success I'm afraid :-(

Here is the unit I have that wraps up your code sample above:

unit CCMCIUtils;

interface

uses
  Windows;

const
  MCI_DGV_SETVIDEO_SRC_NTSC    = $00004000;
  MCI_DGV_SETVIDEO_SRC_RGB     = $00004001;
  MCI_DGV_SETVIDEO_SRC_SVIDEO  = $00004002;
  MCI_DGV_SETVIDEO_SRC_PAL     = $00004003;
  MCI_DGV_SETVIDEO_SRC_SECAM   = $00004004;
  MCI_DGV_SETVIDEO_SRC_GENERIC = $00004005;

const
  MCI_DGV_SETVIDEO_ITEM     = $00100000;

Procedure SetMCIVideoStreamFormat(MCIVideoStreamFormat : DWORD);

implementation

uses
  forms,
  mmsystem,
  VideoCap,
  Dialogs,
  SYSUtils;
 
type
  MCI_DGV_SETVIDEO_PARMS = record
                             dwCallback     : DWORD;
                             dwItem         : DWORD;
                             dwValue        : DWORD;
                             dwOver         : DWORD;
                             lpstrQuality   : PChar;
                             lpstrAlgorithm : PChar;
                             dwSourceNumber : DWORD;
                           end;

Procedure SetMCIVideoStreamFormat(MCIVideoStreamFormat : DWORD);
var
  sv    : MCI_DGV_SETVIDEO_PARMS;
  Flags : Integer;
  e     : integer;
begin
  e := 0;
  sv.dwItem := MCI_DGV_SETVIDEO_ITEM;
  sv.dwValue := MCIVideoStreamFormat;
  SV.dwCallback := Application.MainForm.Handle;
  Flags := MCI_NOTIFY + MCI_SET;
  e := MCISendCommand(MCIGetDeviceID(PChar(gCapVideoDriverName)), MCI_SET_VIDEO, Flags, LongInt(@sv));
  showmessage(inttostr(e));
end;

end.


Tracing through in the debugger suggests that it should work. The gCapVideoDriverName variable contains the name of the driver that was opened as returned by capGetDriverDescription. The result of the mciSendCommand call was 257 ('Invalid MCI device ID.  Use the ID returned when opening the MCI device.');

The MCIGetDeviceID call returned 0 for the device ID (which MSDN notes is a failure result).

The MSDN mentions that the device ID is returned by the MCI_OPEN command, though I never issue that command. I just attach a window handle to the capture device using capCreateCaptureWindow.

After hunting around in the MSDN for a while I suspect there may be another issue: According to the MSDN, MCI_SET_VIDEO and MCI_SETVIDEO are not the same critters, though only MCI_SET_VIDEO is defined in mmsystem.pas in the Delphi VCL source... Also, I suspect that MCI_SET is not required in the flags as is not mentioned in the MSDN in relation to this command (not a definitive statement though, I know :-)

All in all, fairly frustrating! Perhaps I should try using the MCI_OPEN command before attaching the window handle to the device...

Cheers,

Raymond.
0
 
LVL 17

Expert Comment

by:inthe
ID: 7007437
hi raymond,
no luck eh..i also read about the mci_open part didnt really think much of it,though on reflecting i guess it could be important.
like trying to read a file without opening it first maybe.

i guess you know how to use mci_open but in case not
here is a procedure i saved from Alan Lloyd some time ago,you wont need much of it just down to here:
DevId := mciOpenParms.wDeviceId;  

:

uses
  MMSystem;

procedure TForm1.Button1Click(Sender: TObject);
var
  mciOpenParms : TMCI_OPEN_PARMS;
  mciStatusParms : TMCI_Status_Parms;
  mmRes, DevId, dwFlags, TrackMSF, TrackId, TrackMin, TrackSec : DWord;
begin
  {open mci device ...}
  {... set up open parms structure}
  FillChar(mciOpenParms,  SizeOf(mciOpenParms), #0);
  with mciOpenParms do begin
    lpstrDeviceType := 'cdaudio';
    lpstrElementName := 'G:'; // my CD drive
  end;
  {... set action flags}
  dwFlags := MCI_WAIT or MCI_OPEN_TYPE or MCI_OPEN_ELEMENT;
  {... send command to mci}
  mmRes := mciSendCommand(DevId, MCI_OPEN, dwFlags, longint(@mciOpenParms));
  if mmRes <> 0 then
    ShowMessage('MCI_OPEN failed : ' + IntToStr(mmRes));
  DevId := mciOpenParms.wDeviceId;  // returned value

  {get track length ...}
  TrackId := 8; // my test track
  {... set up status parms structure}
  FillChar(mciStatusParms,  SizeOf(TMCI_Status_Parms), #0);
  with mciStatusParms do begin
    dwItem := MCI_STATUS_LENGTH;
    dwTrack := TrackId;
  end;
  {... set action flags}
  dwFlags := MCI_WAIT or MCI_STATUS_ITEM or MCI_TRACK;
  {... send command to mci}
  mmRes := mciSendCommand(DevId, MCI_STATUS, dwFlags,
longint(@mciStatusParms));
  if mmRes <> 0 then
    ShowMessage('MCI_Status failed : ' + IntToStr(mmRes));
  {... extract information fromdwReturn element of status parms}
  TrackMSF := mciStatusParms.dwReturn;  // returned value

  {close mci device}
  mciSendCommand(DevId, MCI_CLOSE, 0, 0);

  {extract length from returned dword}
  TrackMin := MCI_MSF_MINUTE(TrackMSF);
  TrackSec := MCI_MSF_SECOND(TrackMSF);

  {display info}
  Label1.Caption := Format('Track %d - %d min %d sec', [TrackId, TrackMin,
TrackSec]);
end;



just wondering i dont suppose theres  a simple registry key you could change? have you tried running a reg spy(from sysinternals etc) to check what happens in the system when doing the change from the dialog box.?
0
 
LVL 12

Author Comment

by:rwilson032697
ID: 7007860
Hi Barry,

That didn't seem to work! Here's the code below (derived from your code above) as it stands in my app.

The changes I have made are because it is a video grabber device I am trying to open (some more grovelling in the MSDN involved too :-( )

Unfortunately every device (digitalvideo, other, scanner, vcr) I tried returned error 263: "The specified device is not open or is not recognised by MCI"

I haven't tried regmon yet, but that's gonna happen soon if this doesn't pan out :-)

Cheers,

Raymond.

var
  DevID : DWord;

Procedure InitialiseMCIDevice;
var
  mciOpenParms : TMCI_OPEN_PARMS;
  mciStatusParms : TMCI_Status_Parms;
  mmRes, dwFlags, TrackMSF, TrackId, TrackMin, TrackSec : DWord;
  GenParm: TMCI_Generic_Parms;
begin
 {open mci device ...}
 {... set up open parms structure}
 FillChar(mciOpenParms, SizeOf(mciOpenParms), #0);
 with mciOpenParms do
 begin
   lpstrDeviceType := 'digitalvideo';
//   lpstrElementName := '';
 end;

(*
Device Type  Identifier  Description
cdaudio  MCI_DEVTYPE_CD_AUDIO  CD audio player
dat  MCI_DEVTYPE_DAT  Digital audio tape player
digitalvideo  MCI_DEVTYPE_DIGITAL_VIDEO  Digital video in a window
mmmovie  MCI_DEVTYPE_ANIMATION  Animation
other  MCI_DEVTYPE_OTHER  Nonstandard MCI device type
overlay  MCI_DEVTYPE_OVERLAY  Overlay device (analog video in a window)
scanner  MCI_DEVTYPE_SCANNER  Image scanner
sequencer  MCI_DEVTYPE_SEQUENCER  MIDI sequencer
vcr  MCI_DEVTYPE_VCR  Videotape recorder or player
videodisc  MCI_DEVTYPE_VIDEODISC  Videodisc player
waveaudio  MCI_DEVTYPE_WAVEFORM_AUDIO  Audio device that plays digitized waveform files
*)

 {... set action flags} // Don't do MCI_OPEN_ELEMENT as it is a frame grabber
 dwFlags := MCI_WAIT or MCI_OPEN_TYPE {or MCI_OPEN_ELEMENT};


 {... send command to mci}
 mmRes := mciSendCommand(DevId, MCI_OPEN, dwFlags, longint(@mciOpenParms));
 if mmRes <> 0 then
   ShowMessage('MCI_OPEN failed : ' + IntToStr(mmRes))
 else
   begin
     DevId := mciOpenParms.wDeviceId;  // returned value

     // Close the device now...
     dwFlags := MCI_NOTIFY;
     mciSendCommand(DevId, MCI_CLOSE, dwFlags, longint(@GenParm));
   end;
end;
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 12

Author Comment

by:rwilson032697
ID: 7007898
I found another way to set the video in type:

There is a 'setvideo' command you can use with mcisendstring. The catch? You need the device ID :-(

See: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/mmcmdstr_8t67.asp

Cheers,

Raymond.
0
 
LVL 12

Author Comment

by:rwilson032697
ID: 7007965
... another thought ...

My code uses capCreateCaptureWindow to associate a window handle with the capture device. I wonder if I can use the name you supply when calling that function as the name of a capture device.

I may give that a go too when I am at the client machine next...

Cheers,

Raymond.
0
 
LVL 17

Accepted Solution

by:
inthe earned 200 total points
ID: 7009963
hi raymond,

this opening is causing a problem ,

is the string 'digitalvideo' right in:

with mciOpenParms do
begin
  lpstrDeviceType := 'digitalvideo';

its just i was reading your last link on commands and under "open" command it mentions :

MCI reserves "cdaudio" for the CD audio device type, "videodisc" for the videodisc device type, "sequencer" for the MIDI sequencer device type, "AVIVideo" for the digital-video device type, and "waveaudio" for the waveform-audio device type.


0
 
LVL 12

Author Comment

by:rwilson032697
ID: 7010013
Hi Barry,

I used digitalvideo as that was what was listed in the area of MSDN I found which seemed to desctibe it! I will give AVIVideo a go too.

Cheers,

Raymond.
0
 
LVL 12

Author Comment

by:rwilson032697
ID: 7029084
Hi Barry,

Still having not much luck :-( I did try using the AVIVideo device type and the OPEN command succeeded! But the command to set the formt to PAL returned a command not supported error.

After quite some searching in MSDN, culminating in a complete grep of my MSVC installation I determing that MCI_SET_VIDEO and MCI_SETVIDEO are indeed two separate commands, with different numbers. My next attempt will be to try the MCI_SETVIDEO command instead of the MCI_SET_VIDEO command!

Oddly, the MSDN states this video format command is specific to the digitalvideo device type. Hopefully AVIVideo is an alias for digitalvideo :-)

Cheers,

Raymond.
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9005034
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept answer from inthe

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0
 
LVL 12

Author Comment

by:rwilson032697
ID: 9015899
Hi Barry,

I never did get the wretched frame grabber working. Next time I'll probably look at using DirectX of some sort instead of this bloody awful MCI crap...

Cheers,

Raymond.
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9017625
Thankyou for your response.

Paul (pnh73)
EE Cleanup Volunteer
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now