[osg-users] problem of qt plugin for rtsp real time streaming
hui
opencvyang at yahoo.com
Sun Jul 6 00:12:24 PDT 2008
Hi,
Sorry I forget I should send plain text email so my previous email is totally cannot be read.
Here is my question. I try to make rtsp work with osg quicktime plugin. According one user's idea, I make
some change in qt plugin as follows:
1. I add load movie from url:
if (CFURLRef urlRef = CFURLCreateWithBytes(NULL, (const UInt8 *)url, strlen(url), kCFStringEncodingUTF8, NULL)) {
Handle dataRef;
OSType dataRefType;
error = QTNewDataReferenceFromCFURL(urlRef, 0, &dataRef, &dataRefType);
if (error == noErr) {
error = NewMovieFromDataRef(movie, newMovieIdleImportOK, NULL, dataRef, dataRefType);
error = GetMoviesError();
}
CFRelease(urlRef);
}
2. 2. open it with a function as prepreroolMovie ( quicktime api said this is required for streaming):
err = MakeMovieFromURL(filename.c_str(),&_movie);
// add prepreroll
err = PrePrerollMovie(_movie, 0, GetMoviePreferredRate(_movie),
NewMoviePrePrerollCompleteProc(MovieData::MoviePrePrerollCompleteProc),
(void *)this);
<< here get problem, if http, it is ok, but rtsp PrePrerollMovie() will return -1.
What I cannot understand is: I implement this with glut and it never get an error.
// simpleQTtest.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "simpleQTtest.h"
#include <GL/glew.h>
#include <glvu.hpp>
#include <ppm.hpp>
#include <GL/glut.h>
#include "QTML.h"
#include "Movies.h"
#include "ImageCompression.h"
#include "MacErrors.h"
GLVU glvu;
#define MAX_LOADSTRING 100
Movie theMovie;
Rect box;
GLuint textureUnit;
unsigned char *image;
int width, height;
void userDisplayFunc0()
{
glvu.BeginFrame();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glColor3f(1,0,0);
//glutSolidTorus(0.25,1,32,64);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureUnit);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,image);
glBegin(GL_QUADS);
glTexCoord2d(0.0, 0.0); glVertex3d(-0.5, -0.5, 0);
glTexCoord2d(0.0, 1.0); glVertex3d(-0.5, 0.5, 0);
glTexCoord2d(1.0, 1.0); glVertex3d(0.5, 0.5, 0);
glTexCoord2d(1.0, 0.0); glVertex3d(0.5, -0.5, 0);
glEnd();
glvu.EndFrame();
}
void loadPPMImage()
{
LoadPPM("sample.ppm", image, width, height);
}
void UpdateMovieGWorld(Movie m)
{
CGrafPtr port;
GDHandle dev;
GetMovieGWorld(m,&port,&dev);
Rect box;
GetMovieNaturalBoundsRect(m,&box);
MacOffsetRect (&box, -box.left, -box.top);
SetMovieBox (m, &box);
int width=box.right;
int height=box.bottom;
GWorldPtr movieGWorld;
void* pixels=malloc(width*height*4);
NewGWorldFromPtr(&movieGWorld,k32BGRAPixelFormat,&box,0,0,0,(Ptr)pixels,width*4);
SetMovieGWorld (m, (CGrafPtr)movieGWorld, nil);
if (port && !dev)
{
pixels=port->portPixMap[0]->baseAddr;
DisposeGWorld(port);
free(pixels);
}
}
void MyMoviePrePrerollCompleteProc(Movie theMovie, OSErr prerollErr,
void *refcon)
{
Fixed rate=GetMoviePreferredRate(theMovie);
//PrerollMovie(theMovie,0,rate);
SetMovieRate(theMovie,rate);
StartMovie(theMovie);
}
OSErr MyMovieDrawingCompleteProc(Movie theMovie, long refCon)
{
CGrafPtr port;
GDHandle dev;
GetMovieGWorld(theMovie,&port,&dev);
char* pixels=port->portPixMap[0]->baseAddr;
int pixels_width=port->portPixMap[0]->bounds.right;
int pixels_height=port->portPixMap[0]->bounds.bottom;
image = (unsigned char *) pixels;
width = pixels_width;
height = pixels_height;
userDisplayFunc0();
return noErr;
}
bool LoadMovieFromPath(Movie* m, const char* thePath)
{
char fullpath[255];
strcpy(fullpath,thePath);
c2pstr(fullpath);
short theFile = 0;
FSSpec sfFile;
FSMakeFSSpec (0, 0L, (ConstStr255Param)fullpath, &sfFile);
int err=OpenMovieFile (&sfFile, &theFile, fsRdPerm);
if (err!=noErr)
return false;
err=NewMovieFromFile (m, theFile, nil, nil, newMovieActive,
nil);
CloseMovieFile (theFile);
if (err!=noErr)
return false;
UpdateMovieGWorld(*m);
MyMoviePrePrerollCompleteProc(*m,0,0);
return true;
}
bool LoadMovieFromURL(Movie* m, const char* url)
{
OSStatus error = memFullErr;
if (CFURLRef urlRef = CFURLCreateWithBytes(NULL, (const UInt8 *)url, strlen(url), kCFStringEncodingUTF8, NULL)) {
Handle dataRef;
OSType dataRefType;
error = QTNewDataReferenceFromCFURL(urlRef, 0, &dataRef, &dataRefType);
if (error == noErr)
error = NewMovieFromDataRef(m, newMovieActive | newMovieAsyncOK, NULL, dataRef, dataRefType);
CFRelease(urlRef);
}
//SetMovieDrawingCompleteProc(*m, movieDrawingCallWhenChanged,
// MyMovieDrawingCompleteProc, 0 /*refCon*/);//,
/*SetMoviePlayHints(*m, hintsAllowDynamicResize,
hintsAllowDynamicResize);*/
Fixed rate = GetMoviePreferredRate(*m);
error=PrePrerollMovie(*m, 0, GetMoviePreferredRate(*m),
NewMoviePrePrerollCompleteProc(MyMoviePrePrerollCompleteProc), //,
(void *)0L);
UpdateMovieGWorld(*m);
return true;
}
void idle0()
{
if(!IsMovieDone(theMovie))
{
Rect r;
GetMovieNaturalBoundsRect(theMovie,&r);
if (r.right!=box.right || r.bottom!=box.bottom)
{
box.right=r.right;
box.bottom=r.bottom;
UpdateMovieGWorld(theMovie);
}
MoviesTask (theMovie, 0);
CGrafPtr port;
GDHandle dev;
GetMovieGWorld(theMovie,&port,&dev);
char* pixels=port->portPixMap[0]->baseAddr;
int pixels_width=port->portPixMap[0]->bounds.right;
int pixels_height=port->portPixMap[0]->bounds.bottom;
image = (unsigned char *) pixels;
width = pixels_width;
height = pixels_height;
userDisplayFunc0();
Sleep(1);
}
}
void initTexture()
{
loadPPMImage(); // read image first.
glGenTextures(1, &textureUnit);
glBindTexture(GL_TEXTURE_2D, textureUnit);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,image);
glBindTexture(GL_TEXTURE_2D, 0);
}
// just leave one main function here then add glvu
int main()
{
OSErr err;
err = InitializeQTML(0);//
err = EnterMovies ();
// check ver
long version;
OSErr result;
result = Gestalt(gestaltQuickTime,&version);
if ((result == noErr) && (version >= 0x05020000))
{
/* we have version 5.0.2 or later */
}
else
return 0;
// get the movie from url or file path
const char* url="rtsp://141.161.16.105:554/igp/isip2of5011206.mov";
if (!LoadMovieFromURL(&theMovie,url))
return 0;
//SetMovieDrawingCompleteProc(theMovie,movieDrawingCallWhenChanged, MyMovieDrawingCompleteProc, 0/*refCon*/);
Rect box2;
GetMovieNaturalBoundsRect(theMovie,&box);
GetMovieBox(theMovie, &box2);
SetMovieRate(theMovie, 0);
float timeScale = GetMovieTimeScale(theMovie);
DWORD bias=GetTickCount();
glvu.Init("Quicktime Basic Example",
GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA,
50,50,512,512);
GLenum erra = glewInit();
if (GLEW_OK != erra)
{
/* Problem: glewInit failed, something is seriously wrong. */
///fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
//...
}
//glEnable(GL_LIGHTING);
//glEnable(GL_LIGHT0);
//glEnable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH_TEST);
initTexture();
glutDisplayFunc(userDisplayFunc0);
glutIdleFunc(idle0);
Vec3f ModelMin(-1,-1,-1), ModelMax(1,1,1);
Vec3f LookAtCntr( ModelMin+ModelMax ); LookAtCntr*=0.5;
Vec3f mintoCtr( LookAtCntr - ModelMin );
Vec3f Up(0,1,0);
Vec3f Eye(LookAtCntr - 3*(mintoCtr - Up * (mintoCtr * Up) ));
float Yfov = 45;
float Aspect = 1; // WIDTH OVER HEIGHT
float Near = 0.1f; // NEAR PLANE DISTANCE RELATIVE TO MODEL DIAGONAL LENGTH
float Far = 10.0f; // FAR PLANE DISTANCE (ALSO RELATIVE)
glvu.SetAllCams(ModelMin,ModelMax, Eye,LookAtCntr,Up, Yfov,Aspect, Near,Far);
//--------------------------------------------------------------------------
// (3) start the viewer event loop.
//--------------------------------------------------------------------------
glutMainLoop();
return 0;
}
you can see I use exactly same code, but at here the function:
error=PrePrerollMovie(*m, 0, GetMoviePreferredRate(*m),NewMoviePrePrerollCompleteProc(MyMoviePrePrerollCompleteProc), //,(void *)0L);
<< never return -1 error.
<< beside, this example cannot make "http" working because of buffer conflict but
<< that is another issue.
I check the qt plugin code, looks nothing can affect the PrePrerollMovie function,
So, why rtsp cannot work with osg?
There is some setting in loadURL like: newMovieIdleImportOK and newMovieActive | newMovieAsyncOK, but even I change it still doesn't work.
Since I am not familiar with quicktime API, it really confused me.
Thanks for any help.
Hui
More information about the osg-users
mailing list