Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes
nsMovieSoundRequest Class Reference
Inheritance diagram for nsMovieSoundRequest:
Inheritance graph
[legend]
Collaboration diagram for nsMovieSoundRequest:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsMovieSoundRequest ()
virtual ~nsMovieSoundRequest ()
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSISTREAMLOADEROBSERVER
NS_DECL_NSITIMERCALLBACK
nsresult 
Init (nsISound *aSound, nsIURL *aURL)
virtual nsresult PlaySound ()
NS_DECL_ISUPPORTS NS_IMETHOD Notify (nsITimer *timer)=0
void notify (in nsITimer timer)
void onStreamComplete (in nsIStreamLoader loader, in nsISupports ctxt, in nsresult status, in unsigned long resultLength,[const, array, size_is(resultLength)] in octet result)

Static Public Member Functions

static nsSoundRequestGetFromISupports (nsISupports *inSupports)

Protected Member Functions

OSType GetFileFormat (const char *inData, long inDataSize, const nsACString &contentType)
OSErr ImportMovie (Handle inDataHandle, long inDataSize, const nsACString &contentType)
PRBool HaveQuickTime ()
void DisposeMovieData ()
PRBool IsAnyMoviePlaying ()
OSErr TaskActiveMovies (PRBool *outAllMoviesDone)
nsresult Cleanup ()

Static Protected Member Functions

static PRBool TaskOneMovie (Movie inMovie)

Protected Attributes

Movie mMovie
Handle mDataHandle
nsVoidArray mMovies
nsCOMPtr< nsISoundmSound
nsCOMPtr< nsITimermTimer

Detailed Description

Definition at line 136 of file nsSound.cpp.


Constructor & Destructor Documentation

Definition at line 702 of file nsSound.cpp.

: mMovie(nsnull)
, mDataHandle(nsnull)
{
#ifdef SOUND_DEBUG
  printf("%%%%%%%% Made nsMovieSoundRequest\n");
#endif
}

Definition at line 711 of file nsSound.cpp.

{
#ifdef SOUND_DEBUG
  printf("%%%%%%%% Deleted nsMovieSoundRequest\n");
#endif
  DisposeMovieData();
}

Here is the call graph for this function:


Member Function Documentation

nsresult nsSoundRequest::Cleanup ( void  ) [protected, inherited]

Definition at line 485 of file nsSound.cpp.

{
  nsresult rv = NS_OK;
  
#ifdef SOUND_DEBUG
  printf("Sound playback done\n");
#endif
  
  // kill the timer
  if (mTimer) {
    mTimer->Cancel();
    mTimer = nsnull;
  }
  
  // remove from parent array. Use a deathGrip to ensure that it's OK
  // to clear mSound.
  nsCOMPtr<nsISupports>   deathGrip(this);
  if (mSound.get())
  {
    nsSound*    macSound = NS_REINTERPRET_CAST(nsSound*, mSound.get());
    rv = macSound->RemoveRequest(NS_STATIC_CAST(nsITimerCallback*, this));
    mSound = nsnull;
  }
  
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1019 of file nsSound.cpp.

{
  for (PRInt32 i = 0; i < mMovies.Count(); i ++)
  {
    Movie   thisMovie = (Movie)mMovies.ElementAt(i);
    ::DisposeMovie(thisMovie);
  }
  
  mMovies.Clear();
  
  if (mMovie) {
    ::DisposeMovie(mMovie);
    mMovie = nsnull;
  }

  if (mDataHandle) {
    ::DisposeHandle(mDataHandle);
    mDataHandle = nsnull;
  } 
}

Here is the caller graph for this function:

OSType nsMovieSoundRequest::GetFileFormat ( const char *  inData,
long  inDataSize,
const nsACString &  contentType 
) [protected]

Definition at line 790 of file nsSound.cpp.

{
  OSType    fileFormat = kQTFileTypeMovie;    // Default to just treating it like a movie.
                                              // Hopefully QuickTime will be able to import it.
  
  if (inDataSize >= 16)
  {
    OSType firstFourBytes = PR_ntohl(*(OSType *)inData);

    // look for WAVE
    if (firstFourBytes == 'RIFF')
    {
      const char* dataPtr = inData + 8; // skip RIFF and length bytes  

      if (PR_ntohl(*(OSType *)dataPtr) == 'WAVE')
        return kQTFileTypeWave;
    }

    // look for AIFF
    if (firstFourBytes == 'FORM')
    {
      const char* dataPtr = inData + 8; // skip FORM and length bytes
      OSType bytesEightThroughEleven = PR_ntohl(*(OSType *)dataPtr);

      if (bytesEightThroughEleven == 'AIFF')
        return kQTFileTypeAIFF;

      if (bytesEightThroughEleven == 'AIFC')
        return kQTFileTypeAIFC;
    }
  }

  if (inDataSize >= 4)
  {
    OSType firstFourBytes = PR_ntohl(*(OSType *)inData);

    // look for midi
    if (firstFourBytes == 'MThd')
      return kQTFileTypeMIDI;

    // look for µLaw/Next-Sun file format (.au)
    if (firstFourBytes == '.snd')
      return kQTFileTypeMuLaw;
  }

  // MP3 files have a complex format that is not easily sniffed. Just go by
  // MIME type.
  if (contentType.Equals("audio/mpeg")    ||
      contentType.Equals("audio/mp3")     ||
      contentType.Equals("audio/mpeg3")   ||
      contentType.Equals("audio/x-mpeg3") ||
      contentType.Equals("audio/x-mp3")   ||
      contentType.Equals("audio/x-mpeg3"))
  {
    fileFormat = 'MP3 ';      // not sure why there is no enum for this
  }

  return fileFormat;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsSoundRequest * nsSoundRequest::GetFromISupports ( nsISupports *  inSupports) [static, inherited]

Definition at line 472 of file nsSound.cpp.

{
  if (!inSupports) return nsnull;
  
  // test to see if this is really a nsSoundRequest by trying a QI
  nsCOMPtr<nsITimerCallback>  timerCallback = do_QueryInterface(inSupports);
  if (!timerCallback) return nsnull;
  
  return NS_REINTERPRET_CAST(nsSoundRequest*, inSupports);
}

Here is the call graph for this function:

Definition at line 1110 of file nsSound.cpp.

{
  long  gestResult;
  OSErr err = Gestalt (gestaltQuickTime, &gestResult);
  return (err == noErr) && ((long)EnterMovies != kUnresolvedCFragSymbolAddress);
}

Here is the caller graph for this function:

OSErr nsMovieSoundRequest::ImportMovie ( Handle  inDataHandle,
long  inDataSize,
const nsACString &  contentType 
) [protected]

Definition at line 937 of file nsSound.cpp.

{
  GWorldPtr               moviePort = nsMoviePortOwner::GetSingletonMoviePort();
  Handle                  dataRef = nil;
  OSErr                   err = noErr;
  OSType                  fileFormat;
  
  if (!moviePort)
    return memFullErr;
  
  {
    StHandleLocker  locker(inDataHandle);
    fileFormat = GetFileFormat(*inDataHandle, inDataSize, contentType);
  }

  err = ::PtrToHand(&inDataHandle, &dataRef, sizeof(Handle));
  if (err != noErr)
    return err;

  {
    MovieImportComponent  miComponent = ::OpenDefaultComponent(MovieImportType, fileFormat);
    Track                 targetTrack = nil;
    TimeValue             addedDuration = 0;
    long                  outFlags = 0;
    ComponentResult       compErr = noErr;

    // set the port to our singleton GWorld before creating
    // the movie. This will ensure that the movie uses this port, and
    // not one of our (transient) windows.
    StGWorldPortSetter    gWorldSetter(moviePort);

    if (!miComponent) {
      err = paramErr;
      goto bail;
    }
    
    NS_ASSERTION(mMovie == nsnull, "nsMovieSoundRequest already has movie");
    mMovie = ::NewMovie(0);
    if (!mMovie) {
      err = ::GetMoviesError();
      goto bail;
    }

    compErr = ::MovieImportDataRef(miComponent,
                                dataRef,
                                HandleDataHandlerSubType,
                                mMovie,
                                nil,
                                &targetTrack,
                                nil,
                                &addedDuration,
                                movieImportCreateTrack,
                                &outFlags);

    if (compErr != noErr) {
      ::DisposeMovie(mMovie);
      mMovie = nil;
      err = compErr;
      goto bail;
    }

    // ensure that the track never draws on screen, otherwise we might be
    // suspecptible to spoofing attacks
    {
      Rect   movieRect = {0};
      ::SetMovieBox(mMovie, &movieRect);
    }
    
    ::GoToEndOfMovie(mMovie);   // simplifies the logic in PlaySound()
        
  bail:
    if (miComponent)
      ::CloseComponent(miComponent);
  }

  if (dataRef)
    ::DisposeHandle(dataRef);
  
  return err;
}

Here is the call graph for this function:

nsresult nsMovieSoundRequest::Init ( nsISound aSound,
nsIURL aURL 
)

Definition at line 721 of file nsSound.cpp.

{
  NS_ENSURE_ARG(aURL && aSound);

  mSound = aSound;
  
  // if quicktime is not installed, we can't do anything
  if (!HaveQuickTime())
    return NS_ERROR_NOT_IMPLEMENTED;

#ifdef SOUND_DEBUG
  printf("%%%%%%%% Playing nsSound\n");
#endif
  NS_ASSERTION(mMovie == nsnull, "nsSound being played twice");
  
  nsCOMPtr<nsIStreamLoader> streamLoader;
  return NS_NewStreamLoader(getter_AddRefs(streamLoader), aURL, NS_STATIC_CAST(nsIStreamLoaderObserver*, this));
}

Here is the call graph for this function:

Definition at line 1094 of file nsSound.cpp.

{
  if (!::IsMovieDone(mMovie))
    return PR_TRUE;
  
  for (PRInt32 i = 0; i < mMovies.Count(); i ++)
  {
    Movie   thisMovie = (Movie)mMovies.ElementAt(i);
    if (!::IsMovieDone(thisMovie))
      return PR_TRUE;
  }
    
  return PR_FALSE;
}
void nsITimerCallback::notify ( in nsITimer  timer) [inherited]
Parameters:
aTimerthe timer which has expired
NS_DECL_ISUPPORTS NS_IMETHOD nsSoundRequest::Notify ( nsITimer timer) [pure virtual, inherited]
void nsIStreamLoaderObserver::onStreamComplete ( in nsIStreamLoader  loader,
in nsISupports  ctxt,
in nsresult  status,
in unsigned long  resultLength,
[const, array, size_is(resultLength)] in octet  result 
) [inherited]

Implements nsSoundRequest.

Definition at line 851 of file nsSound.cpp.

{
  nsresult rv;

  // we'll have a timer already if the sound is still playing from a previous
  // request. In that case, we clone the movie into a new one, so we can play it
  // again from the start.
  if (!mTimer)
  {  
    mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);    // release previous timer, if any
    if (NS_FAILED(rv)) {
      Cleanup();
      return rv;
    }
    
    const PRInt32   kMovieTimerInterval = 250;      // 250 milliseconds
    rv = mTimer->InitWithCallback(NS_STATIC_CAST(nsITimerCallback*, this), kMovieTimerInterval,
                                  nsITimer::TYPE_REPEATING_PRECISE);
    if (NS_FAILED(rv)) {
      Cleanup();
      return rv;
    }
  }
  
  Movie   movieToPlay = mMovie;
  
  if (!::IsMovieDone(mMovie))     // if the current movie is still playing, clone it
  {
    Movie   newMovie = ::NewMovie(0);
    if (!newMovie) return NS_ERROR_FAILURE;
    
    // note that this copies refs, not all the data. So it should be fast
    OSErr err = ::InsertMovieSegment(mMovie, newMovie, 0, ::GetMovieDuration(mMovie), 0);
    if (err != noErr)
    {
      ::DisposeMovie(newMovie);
      return NS_ERROR_FAILURE;
    }
    
    // append it to the array
    PRBool  appended = mMovies.AppendElement((void *)newMovie);
    if (!appended) 
    {
      ::DisposeMovie(newMovie);
      return NS_ERROR_FAILURE;
    }

    movieToPlay = newMovie;
  }
  
  ::SetMovieVolume(movieToPlay, kFullVolume);
  ::GoToBeginningOfMovie(movieToPlay);
  ::StartMovie(movieToPlay);
  ::MoviesTask(movieToPlay, 0);
  
#ifdef SOUND_DEBUG
  printf("Starting movie playback\n");
#endif
  return NS_OK;
}

Here is the call graph for this function:

OSErr nsMovieSoundRequest::TaskActiveMovies ( PRBool outAllMoviesDone) [protected]

Definition at line 1062 of file nsSound.cpp.

{
  PRBool    allMoviesDone = PR_FALSE;

  allMoviesDone = TaskOneMovie(mMovie);

  PRInt32 curIndex = 0;

  while (curIndex < mMovies.Count())
  {
    Movie   thisMovie     = (Movie)mMovies.ElementAt(curIndex);
    PRBool  thisMovieDone = TaskOneMovie(thisMovie);
    
    if (thisMovieDone)    // remove finished movies from the array
    {
      mMovies.RemoveElementAt(curIndex);
      ::DisposeMovie(thisMovie);
      // curIndex doesn't change
    }
    else
    {
      curIndex ++;
    } 
    allMoviesDone &= thisMovieDone;
  }
  
  *outAllMoviesDone = allMoviesDone;
  return noErr;  
}

Here is the call graph for this function:

PRBool nsMovieSoundRequest::TaskOneMovie ( Movie  inMovie) [static, protected]

Definition at line 1042 of file nsSound.cpp.

{
  PRBool    movieDone = PR_FALSE;
  
  ComponentResult status = ::GetMovieStatus(inMovie, nil);
  NS_ASSERTION(status == noErr, "Movie bad");
  if (status != noErr) {
    ::StopMovie(inMovie);
    movieDone = PR_TRUE;
  }

  movieDone |= ::IsMovieDone(inMovie);
  
  if (!movieDone)
    ::MoviesTask(inMovie, 0);

  return movieDone;
}

Here is the caller graph for this function:


Member Data Documentation

Definition at line 171 of file nsSound.cpp.

Movie nsMovieSoundRequest::mMovie [protected]

Definition at line 170 of file nsSound.cpp.

Definition at line 174 of file nsSound.cpp.

nsCOMPtr<nsISound> nsSoundRequest::mSound [protected, inherited]

Definition at line 98 of file nsSound.cpp.

nsCOMPtr<nsITimer> nsSoundRequest::mTimer [protected, inherited]

Definition at line 99 of file nsSound.cpp.


The documentation for this class was generated from the following file: