Video decoding using MMF DevVideo API

Login to reply to this topic.
Thu, 2007-11-01 01:19
Joined: 2007-06-15
Forum posts: 4

Hi all,

Does anyone have experience with using the DevVideo APIs for decoding? I have to decode an H.263 stream and for various reasons I can't use any of the higher level utility functions, so I have dropped down to the DevVideo level. Unfortunately, I can't work out how to make it go. I can find and initialise the decoder OK, and writing the samples to the decoder seems to work - but whenever I ask for a picture back it always returns NULL.

The code below shows how I'm attacking the decoder at the moment. Note that all memory management & error handling has been omitted for the sake of clarity. Also note that the comments refer to what *I think* is happening - not what *actually is* going on.

/*
* Client will call InitDecoderL() once, and then feed the decoder buffers by
* calling DecodeFrame() once for each frame to be decoded.
*/
class Ch263Decoder : private MMMFDevVideoPlayObserver
{
  private:
    CMMFDevVideoPlay* iDevVideo;
    THwDeviceId       iDevice;
   
  public:
    void InitDecoderL()
    {
      // Create a client interface to the DevVideo subsystem
      iDevVideo = CMMFDevVideoPlay::NewL(*this);
     
      // Locate a codec
      RArray<TUid> decoders;
      iDevVideo->FindDecodersL(_L8("video/h263-2000"), 0, decoders, EFalse);
     
      // If we get to here, we have at least one matching decoder - select it
      iDevice = iDevVideo->SelectDecoderL( decoders[0] );
     
      // Set the decoder device's input format - with any luck we're telling it
      // we want to feed it complete H.263 frames, unencumbered by any extra
      // encapsulation.
      CCompressedVideoFormat* inputFormat =
        CCompressedVideoFormat::NewL(_L8("video/h263-2000"));       
      iDevVideo->SetInputFormatL(iDevice, *inputFormat, EDuCodedPicture,
        EDuElementaryStream, ETrue);
       
      // Query the device for its valid output formats
      RArray<TUncompressedVideoFormat> outputFormats;
      iDevVideo->GetOutputFormatListL(iDevice, outputFormats);
           
      // Now we need to select an output format - we want YUV 4:2:0. Our
      // SelectOutputFormatL utility function will find the one we're after or
      // leave with KErrNotFound.
      const TUncompressedVideoFormat& outputFormat =
        SelectOutputFormatL(outputFormats);
      iDevVideo->SetOutputFormatL(outputFormat);
     
      // Tell the decoder about the frame size, etc. by giving it a header.
      TVideoPictureHeader header = {0};
      header.iProfile = 0;
      header.iLevel   = 20;
      header.iVersion = -1;
      header.iSizeInMemory.iWidth  = 176;
      header.iSizeInMemory.iHeight = 144;
      header.iDisplayedRect.SetRect(TPoint(0,0),TSize(176,144));
     
      iDevVideo->ConfigureDecoderL(header);

      // If we get to here we should have (hopefully) told the decoder
      // everything it needs to know. Let's try getting it to initialize and
      // see what happens. Continued in the MdvpoInitComplete() callback.
      iDevVideo->Initialize();     
    };
   
  private:
    virtual void MdvpoInitComplete(TInt aError)
    {
      if( aError == KErrNone )
      {
        // The codec was sucessfully initialised - start 'er up.
        iDevVideo->Start();
      }
    };
   
  public:
    void DecodeFrame(TInt aFrameNumber, const TDesC8& aFrame)
    {
      // Fetch an input buffer from the decoder
      TVideoInputBuffer* buffer = iDevVideo->GetBufferL(aFrame.Size());
     
      // Fill out the input buffer with the data we want to decode
      buffer->iOptions = TVideoInputBuffer::ESequenceNumber;
      buffer->aFrameNumber;
      buffer->iData.Copy(aFrame);
     
      // Write the input buffer to the decoder (also releases the input buffer
      // to be re-used)
      iDevVideo->WriteCodedBufferL(buffer);
      buffer = NULL;
     
      // fetch the nect decoded picture back from the decoder
      // ** this ALWAYS returns NULL for me **
      TVideoPicture* picture = iDevVideo->NextPictureL();
      if( picture != NULL )
      {
        // do whatever we need to with the decoded frame....
        iDevVideo->ReturnPicture(picture);
        picture = NULL;
      }
    };
};

If anyone has tips or suggestions - or even some example code to share - I'd be most grateful.

regards,

Trent Clarke

  • Login to reply to this topic.