Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / Mac Programming / April 2007



Tip: Looking for answers? Try searching our database.

Getting "white" for all pixels in pixmap

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
William Bertelsen - 18 Apr 2007 18:53 GMT
I am trying to read pixels from a quicktime movie on windows. I am aparently
loading the movie and creating a matching 32 bit per pixel gworld and
finding an interesting time, but the pixels are white.

I am very new to this and may have overlooked something important. It seems
that everything is fine except the actual pixels.

first I call my own function int error = getMovie("filename.mov", movie,
width, height, duration, frames);
to get the movie handle and its size and duration ect

That returns valid values

Then I call GWorldPtr gworld = createGWorld(width,height,pixMapHandle);

to get a gworld. It is always 32 bit no matter what the movie might
originally is. I need it in that format.

Then I call SetMovieGWorld(movie, gworld, GetGWorldDevice(gworld)); to bind
the movie to the gworld.

Next I call my own function renderNextFrame(movie); which finds the next
interesting time and renders it.. or so I hope.

After all this I et the baseaddress of the pixmap and look at the bytes,
which are all 255.

It is next to impossible (for me) to tell where the error is, but I append
all the code of the sample app, in which I have declared the above mentioned
functions. It would be greatly appresiated if someone would take a quick
look at the code and point out the error.

I _assume_ that the problem is related to locking the pixmap or the setting
of a new time and rendering. When exactly should I lock, and should I not
unlock as well?

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

void main()

{

OSErr errCode = InitializeQTML(0);

EnterMovies();

Movie movie;

int width;

int height;

float duration;

int frames;

int error = getMovie("c:\\a.mov", movie, width, height, duration, frames);

PixMapHandle pixMapHandle;

GWorldPtr gworld = createGWorld(width,height,pixMapHandle);

SetMovieGWorld(movie, gworld, GetGWorldDevice(gworld));

renderNextFrame(movie);

Ptr data = GetPixBaseAddr(pixMapHandle);

for(int i=0;i<100;i++) //just looking at the 25 first pixels

{

unsigned char a = *((unsigned char*)data++);

unsigned char r = *((unsigned char*)data++);

unsigned char g = *((unsigned char*)data++);

unsigned char b = *((unsigned char*)data++);

}

getch();

}

int getMovie(char* fileName, Movie& movie, int& width, int& height, float&
duration, int& frames)

{

FSSpec spec;

short refNumber=0;

OSErr errCode = NativePathNameToFSSpec(fileName, &spec, 0);

if(errCode) return 2;

errCode = OpenMovieFile(&spec,&refNumber, fsRdPerm);

if(errCode) return 3;

errCode = NewMovieFromFile(&movie, refNumber, 0,NULL,0,0);

if(errCode) return 4;

TimeValue tv = GetMovieDuration(movie);

Rect r;

GetMovieBox(movie, &r);

width=r.right;

height=r.bottom;

TimeScale ts = GetMovieTimeScale(movie);//fps

Fixed ffr=GetMoviePreferredRate(movie);

duration = (float)tv/(float)ts;

Track track = GetMovieIndTrackType(movie,1, 'vfrr',
movieTrackCharacteristic);

Media media = GetTrackMedia(track);

frames = GetMediaSampleCount(media);

return 0;

}

GWorldPtr createGWorld(int width, int height, PixMapHandle &pixMapHandle)

{

GWorldPtr gworld;

Rect bounds;

OSErr errCode;

bounds.top = bounds.left = 0;

bounds.right = width;

bounds.bottom = height;

errCode = QTNewGWorld(&gworld,32,&bounds,NULL,NULL,NULL);

if(errCode) return 0;

//clear the first frame.. is this nessesary?

LockPixels(GetGWorldPixMap(gworld));

SetGWorld(gworld,NULL);

Rect rect;

rect.left = rect.top = 0;

rect.right = width;

rect.bottom = height;

EraseRect(&rect);

pixMapHandle = GetGWorldPixMap(gworld);

return gworld;

}

void renderNextFrame(Movie movie)

{

short flags = nextTimeMediaSample;

OSType whichMediaType = 'vide';

//flags |= nextTimeEdgeOK;

TimeValue movieTime=0;

TimeValue duration;

GetMovieNextInterestingTime(movie,

flags,

1,

&whichMediaType,

movieTime,

0,

&movieTime,

&duration);

SetMovieTimeValue(movie,movieTime);

MoviesTask(movie,0);

}
William Bertelsen - 19 Apr 2007 11:51 GMT
It seems that I need to call StartMovie() before reading pixels. I have not
tested it very much yet, but the colors that I get, they are faily accurate
looking now. A redish movie has redish colors and a bluish one is sorta
blue. If it is correct pixels, which I wil test later, it works now, but...
why do I need to StartMovie? The samples I have seen, which are rarely
complete programs, they never call startmovie.
Jan E. Schotsman - 19 Apr 2007 16:26 GMT
> It seems that I need to call StartMovie() before reading pixels. I have
> not tested it very much yet, but the colors that I get, they are faily
> accurate looking now. A redish movie has redish colors and a bluish one
> is sorta blue. If it is correct pixels, which I wil test later, it
> works now, but... why do I need to StartMovie? The samples I have seen,
> which are rarely complete programs, they never call startmovie.

You need to call SetMovieActive.
Also call MoviesTask after acter calling SetMovieTime.
You can set a callback on MoviesTask that does something with the
image, then steps to the next frame/time.

Jan E.
William Bertelsen - 19 Apr 2007 16:55 GMT
> You need to call SetMovieActive.
> Also call MoviesTask after acter calling SetMovieTime.
> You can set a callback on MoviesTask that does something with the image,
> then steps to the next frame/time.

Thanks! That works as well.
I  called the moviesTask before as well, but I needed either startmovie or
setmovieactive.
I find little or no info on the two and what exactly the difference is.

What I want is generally just to open a movie and get the frames one by one.
Rather fast and with controll than quick and without. I preload the data to
memory and deal with it from there, so it is fine to set frame 0, read the
pixels, set frame 1 etc without callbacks, since I will not be doing
anything else when reading the pixels.

Is this what I get from opening the movie, setting the gworld , setting
active and interesting time and reading the pixmap and then next
interesting, or arethere some side efects to this method? I suspected tht
StartMovie might actually start up some background processing which ran the
frames, but I could not really see that that hapened.
Jan E. Schotsman - 27 Apr 2007 20:06 GMT
>> You need to call SetMovieActive.
>> Also call MoviesTask after acter calling SetMovieTime.
[quoted text clipped - 5 lines]
> or setmovieactive.
> I find little or no info on the two and what exactly the difference is.

From the documentation for StartMovie accessible in Xcode (Mac
programming tool):

You are not required to call this function to start a movie. It is
included in the QuickTime API for convenience. Before playing the
movie, the Movie Toolbox makes the movie active, prerolls the movie,
and sets the movie to its preferred playback rate. You can use
SetMoviePreferredRate (III-1740) to change this setting.

With apologies for the late reaction. I forgot about this thread.

Jan E.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.