Bug 512398 - fix liboggplay update (rev f4087c5ac148) which accidentally removed liboggplay's os2_semaphore.*. r=doublec
authorChris Pearce <chris@pearce.org.nz>
Mon, 31 Aug 2009 14:08:39 +1200
changeset 32100 fb6d235b9efb55e597d61f44e28b4eed39f2c245
parent 32099 8c409bffb344cda4a8118812861c4f72c58b8e01
child 32101 d87974838fa93755a402a456cecd15b255bb441b
child 32145 ad16a3878f78081d84fda09ee2b8eb5f4859da6e
push id8845
push usercpearce@mozilla.com
push dateMon, 31 Aug 2009 02:09:40 +0000
treeherderautoland@fb6d235b9efb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdoublec
bugs512398
milestone1.9.3a1pre
Bug 512398 - fix liboggplay update (rev f4087c5ac148) which accidentally removed liboggplay's os2_semaphore.*. r=doublec
content/media/ogg/nsOggDecoder.cpp
content/media/test/manifest.js
media/libfishsound/src/libfishsound/fishsound_vorbis.c
media/liboggplay/README
media/liboggplay/README_MOZILLA
media/liboggplay/aspect_ratio.patch
media/liboggplay/bug481921.patch
media/liboggplay/bug487519.patch
media/liboggplay/bug488951.patch
media/liboggplay/bug488951_yuv_fix.patch
media/liboggplay/bug488951_yuv_fix_2.patch
media/liboggplay/bug492436.patch
media/liboggplay/bug493140.patch
media/liboggplay/bug493224.patch
media/liboggplay/bug493678.patch
media/liboggplay/bug495129a.patch
media/liboggplay/bug495129b.patch
media/liboggplay/bug496529.patch
media/liboggplay/bug498815.patch
media/liboggplay/bug498824.patch
media/liboggplay/bug499519.patch
media/liboggplay/bug500311.patch
media/liboggplay/include/oggplay/config_win32.h
media/liboggplay/include/oggplay/oggplay.h
media/liboggplay/include/oggplay/oggplay_callback_info.h
media/liboggplay/include/oggplay/oggplay_enums.h
media/liboggplay/include/oggplay/oggplay_query.h
media/liboggplay/include/oggplay/oggplay_reader.h
media/liboggplay/include/oggplay/oggplay_seek.h
media/liboggplay/include/oggplay/oggplay_tools.h
media/liboggplay/oggplay_os2.patch
media/liboggplay/seek_to_key_frame.patch
media/liboggplay/src/liboggplay/config.h
media/liboggplay/src/liboggplay/cpu.c
media/liboggplay/src/liboggplay/oggplay.c
media/liboggplay/src/liboggplay/oggplay_buffer.c
media/liboggplay/src/liboggplay/oggplay_callback.c
media/liboggplay/src/liboggplay/oggplay_callback.h
media/liboggplay/src/liboggplay/oggplay_callback_info.c
media/liboggplay/src/liboggplay/oggplay_data.c
media/liboggplay/src/liboggplay/oggplay_data.h
media/liboggplay/src/liboggplay/oggplay_file_reader.c
media/liboggplay/src/liboggplay/oggplay_file_reader.h
media/liboggplay/src/liboggplay/oggplay_private.h
media/liboggplay/src/liboggplay/oggplay_query.c
media/liboggplay/src/liboggplay/oggplay_seek.c
media/liboggplay/src/liboggplay/oggplay_tcp_reader.c
media/liboggplay/src/liboggplay/oggplay_tcp_reader.h
media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
media/liboggplay/src/liboggplay/std_semaphore.h
media/liboggplay/src/liboggplay/x86/oggplay_yuv2rgb_x86.c
media/liboggplay/src/liboggplay/x86/yuv2rgb_x86_vs.h
media/liboggplay/trac466.patch
media/liboggplay/update.sh
--- a/content/media/ogg/nsOggDecoder.cpp
+++ b/content/media/ogg/nsOggDecoder.cpp
@@ -287,24 +287,25 @@ public:
   PRBool HasAudio()
   {
     NS_ASSERTION(mState > DECODER_STATE_DECODING_METADATA, "HasAudio() called during invalid state");
     //  NS_ASSERTION(PR_InMonitor(mDecoder->GetMonitor()), "HasAudio() called without acquiring decoder monitor");
     return mAudioTrack != -1;
   }
 
   // Decode one frame of data, returning the OggPlay error code. Must
-  // be called only when the current state > DECODING_METADATA. The decode 
-  // monitor MUST NOT be locked during this call since it can take a long
-  // time. liboggplay internally handles locking.
-  // Any return value apart from those below is mean decoding cannot continue.
+  // be called only when the current state > DECODING_METADATA. You must
+  // pass the locked decode monitor to this call. liboggplay internally
+  // handles its own locking. If liboggplay reaches end of file, we will
+  // transition the state machine to COMPLETED state. Any return value
+  // apart from those below is mean decoding cannot continue.
   // E_OGGPLAY_CONTINUE       = One frame decoded and put in buffer list
   // E_OGGPLAY_USER_INTERRUPT = One frame decoded, buffer list is now full
   // E_OGGPLAY_TIMEOUT        = No frames decoded, timed out
-  OggPlayErrorCode DecodeFrame();
+  OggPlayErrorCode DecodeFrame(nsAutoMonitor& aMonitor);
 
   // Handle any errors returned by liboggplay when decoding a frame.
   // Since this function can change the decoding state it must be called
   // with the decoder lock held.
   void HandleDecodeErrors(OggPlayErrorCode r);
 
   // Returns the next decoded frame of data. The caller is responsible
   // for freeing the memory returned. This function must be called
@@ -722,19 +723,28 @@ nsOggDecodeStateMachine::nsOggDecodeStat
 nsOggDecodeStateMachine::~nsOggDecodeStateMachine()
 {
   while (!mDecodedFrames.IsEmpty()) {
     delete mDecodedFrames.Pop();
   }
   oggplay_close(mPlayer);
 }
 
-OggPlayErrorCode nsOggDecodeStateMachine::DecodeFrame()
+OggPlayErrorCode nsOggDecodeStateMachine::DecodeFrame(nsAutoMonitor& aMonitor)
 {
+  NS_ASSERTION(mState != DECODER_STATE_COMPLETED &&
+               mState != DECODER_STATE_SHUTDOWN,
+               "Don't call DecodeFrame() after reaching EOF!");
+  aMonitor.Exit();
   OggPlayErrorCode r = oggplay_step_decoding(mPlayer);
+  aMonitor.Enter();
+  if (r == E_OGGPLAY_OK) {
+    LOG(PR_LOG_DEBUG, ("Changed state to COMPLETED"));
+    mState = DECODER_STATE_COMPLETED;
+  }  
   return r;
 }
 
 void nsOggDecodeStateMachine::HandleDecodeErrors(OggPlayErrorCode aErrorCode)
 {
   PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mDecoder->GetMonitor());
 
   if (aErrorCode != E_OGGPLAY_TIMEOUT &&
@@ -1327,34 +1337,37 @@ void nsOggDecodeStateMachine::DecodeToFr
   float audioTime = 0;
   nsTArray<float> audioData;
   do {
     if (frame) {
       audioData.AppendElements(frame->mAudioData);
       audioTime += frame->mAudioData.Length() /
         (float)mAudioRate / (float)mAudioChannels;
     }
-    do {
-      aMonitor.Exit();
-      r = DecodeFrame();
-      aMonitor.Enter();
-    } while (mState != DECODER_STATE_SHUTDOWN && r == E_OGGPLAY_TIMEOUT);
+    r = E_OGGPLAY_TIMEOUT;
+    while (mState != DECODER_STATE_SHUTDOWN &&
+           mState != DECODER_STATE_COMPLETED &&
+           r == E_OGGPLAY_TIMEOUT)
+    {
+      r = DecodeFrame(aMonitor);
+    }
 
     HandleDecodeErrors(r);
 
     if (mState == DECODER_STATE_SHUTDOWN)
       break;
 
     FrameData* nextFrame = NextFrame();
     if (!nextFrame)
       break;
 
     delete frame;
     frame = nextFrame;
-  } while (frame->mDecodedFrameTime < target);
+  } while (frame->mDecodedFrameTime < target &&
+           mState != DECODER_STATE_COMPLETED);
 
   if (mState == DECODER_STATE_SHUTDOWN) {
     delete frame;
     return;
   }
 
   NS_ASSERTION(frame != nsnull, "No frame after decode!");
   if (frame) {
@@ -1422,19 +1435,17 @@ nsresult nsOggDecodeStateMachine::Run()
     case DECODER_STATE_DECODING_METADATA:
       {
         mon.Exit();
         LoadOggHeaders(reader);
         mon.Enter();
       
         OggPlayErrorCode r = E_OGGPLAY_TIMEOUT;
         while (mState != DECODER_STATE_SHUTDOWN && r == E_OGGPLAY_TIMEOUT) {
-          mon.Exit();
-          r = DecodeFrame();
-          mon.Enter();
+          r = DecodeFrame(mon);
         }
 
         HandleDecodeErrors(r);
 
         if (mState == DECODER_STATE_SHUTDOWN)
           continue;
 
         mLastFrameTime = 0;
@@ -1618,41 +1629,41 @@ nsresult nsOggDecodeStateMachine::Run()
           // mSeekTime should not have changed. While we seek, mPlayState
           // should always be PLAY_STATE_SEEKING and no-one will call
           // nsOggDecoderStateMachine::Seek.
           NS_ASSERTION(seekTime == mSeekTime, "No-one should have changed mSeekTime");
           if (mState == DECODER_STATE_SHUTDOWN) {
             continue;
           }
 
-          OggPlayErrorCode r;
-          // Now try to decode another frame to see if we're at the end.
-          do {
-            mon.Exit();
-            r = DecodeFrame();
-            mon.Enter();
-          } while (mState != DECODER_STATE_SHUTDOWN && r == E_OGGPLAY_TIMEOUT);
+          OggPlayErrorCode r = E_OGGPLAY_TIMEOUT;
+          // If possible decode a few more frames, so that we don't need to
+          // wait for the step decode thread to start up before we can resume
+          // playback. This makes playback start faster after seeking.
+          while (mState != DECODER_STATE_SHUTDOWN &&
+                 mState != DECODER_STATE_COMPLETED &&
+                 r == E_OGGPLAY_TIMEOUT)
+          {
+            r = DecodeFrame(mon);
+          }
           HandleDecodeErrors(r);
           if (mState == DECODER_STATE_SHUTDOWN)
             continue;
           QueueDecodedFrames();
         }
 
-        // Change state to DECODING now. SeekingStopped will call
-        // nsOggDecodeStateMachine::Seek to reset our state to SEEKING
-        // if we need to seek again.
-        LOG(PR_LOG_DEBUG, ("Changed state from SEEKING (to %f) to DECODING", seekTime));
-        mState = DECODER_STATE_DECODING;
+        // SeekingStopped will call nsOggDecodeStateMachine::Seek to reset
+        // our state to SEEKING if we need to seek again.
         nsCOMPtr<nsIRunnable> stopEvent;
-        if (mDecodedFrames.GetCount() > 1) {
+        if (mState == DECODER_STATE_COMPLETED) {
+          stopEvent = NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStoppedAtEnd);
+        } else {
           stopEvent = NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStopped);
+          LOG(PR_LOG_DEBUG, ("Changed state from SEEKING (to %f) to DECODING", seekTime));
           mState = DECODER_STATE_DECODING;
-        } else {
-          stopEvent = NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStoppedAtEnd);
-          mState = DECODER_STATE_COMPLETED;
         }
         mon.NotifyAll();
 
         mon.Exit();
         NS_DispatchToMainThread(stopEvent, NS_DISPATCH_SYNC);        
         mon.Enter();
       }
       break;
@@ -1725,29 +1736,32 @@ nsresult nsOggDecodeStateMachine::Run()
           // After the drain call the audio stream is unusable. Close it so that
           // next time audio is used a new stream is created. The StopPlayback
           // call also resets the playing flag so audio is restarted correctly.
           StopPlayback();
 
           if (mState != DECODER_STATE_COMPLETED)
             continue;
         }
+        
+        if (mDecoder->GetState() == nsOggDecoder::PLAY_STATE_PLAYING) {
+          // We were playing, we need to move the current time to the end of
+          // media, and send an 'ended' event.
+          mCurrentFrameTime += mCallbackPeriod;
+          if (mDuration >= 0) {
+            mCurrentFrameTime = PR_MAX(mCurrentFrameTime, mDuration / 1000.0);
+          }
 
-        // Set the right current time
-        mCurrentFrameTime += mCallbackPeriod;
-        if (mDuration >= 0) {
-          mCurrentFrameTime = PR_MAX(mCurrentFrameTime, mDuration / 1000.0);
+          mon.Exit();
+          nsCOMPtr<nsIRunnable> event =
+            NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, PlaybackEnded);
+          NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
+          mon.Enter();
         }
 
-        mon.Exit();
-        nsCOMPtr<nsIRunnable> event =
-          NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, PlaybackEnded);
-        NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
-        mon.Enter();
-
         while (mState == DECODER_STATE_COMPLETED) {
           mon.Wait();
         }
       }
       break;
     }
   }
 
@@ -1776,18 +1790,18 @@ void nsOggDecodeStateMachine::LoadOggHea
         int aspectd, aspectn;
         // this can return E_OGGPLAY_UNINITIALIZED if the video has
         // no aspect ratio data. We assume 1.0 in that case.
         OggPlayErrorCode r =
           oggplay_get_video_aspect_ratio(mPlayer, i, &aspectd, &aspectn);
         mAspectRatio = r == E_OGGPLAY_OK && aspectd > 0 ?
             float(aspectn)/float(aspectd) : 1.0;
 
-        int y_width;
-        int y_height;
+        int y_width = 0;
+        int y_height = 0;
         oggplay_get_video_y_size(mPlayer, i, &y_width, &y_height);
         mDecoder->SetRGBData(y_width, y_height, mFramerate, mAspectRatio, nsnull);
       }
       else if (mAudioTrack == -1 && oggplay_get_track_type(mPlayer, i) == OGGZ_CONTENT_VORBIS) {
         mAudioTrack = i;
         oggplay_set_offset(mPlayer, i, OGGPLAY_AUDIO_OFFSET);
         oggplay_get_audio_samplerate(mPlayer, i, &mAudioRate);
         oggplay_get_audio_channels(mPlayer, i, &mAudioChannels);
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -1,25 +1,28 @@
 // In each list of tests below, test file types that are not supported should
 // be ignored. To make sure tests respect that, we include a file of type
 // "bogus/duh" in each list.
 
 // These are small test files, good for just seeing if something loads.
+// Used in test_load.html
 var gSmallTests = [
   { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
   { name:"320x240.ogv", type:"video/ogg", width:320, height:240 },
   { name: "bug499519.ogv", type:"video/ogg", duration:0.24 },
   { name: "bug506094.ogv", type:"video/ogg", duration:0 },
-  { name:"bogus.duh", type:"bogus/duh" }
+  { name:"bogus.duh", type:"bogus/duh" },
+  { name: "bug501279.ogg", type:"audio/ogg", duration:0 },
 ];
 
 // These are files that we just want to make sure we can play through.
 // We can also check metadata.
 // Put files of the same type together in this list so if something crashes
 // we have some idea of which backend is responsible.
+// Used in test_playback.html
 var gPlayTests = [
   // 8-bit samples
   { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0 },
   // 8-bit samples, file is truncated
   { name:"r11025_u8_c1_trunc.wav", type:"audio/x-wav", duration:1.8 },
   // file has trailing non-PCM data
   { name:"r11025_s16_c1_trailing.wav", type:"audio/x-wav", duration:1.0 },
   // file with list chunk
@@ -30,30 +33,31 @@ var gPlayTests = [
   { name:"bug482461.ogv", type:"video/ogg", duration:4.24 },
   // With first frame a "duplicate" (empty) frame.
   { name:"bug500311.ogv", type:"video/ogg", duration:1.96 },
   // Small audio file
   { name:"small-shot.ogg", type:"video/ogg" },
   // More audio in file than video.
   { name: "short-video.ogv", type:"video/ogg", duration:1.081 },
 
+  { name: "bug495129.ogv", type:"video/ogg", duration:2.52 },
+  { name: "bug498855-1.ogv", type:"video/ogg", duration:0.2 },
+  { name: "bug498855-2.ogv", type:"video/ogg", duration:0.2 },
+  { name: "bug498855-3.ogv", type:"video/ogg", duration:0.2 },
+  { name: "bug504644.ogv", type:"video/ogg", duration:1.56 },
+
   { name:"bogus.duh", type:"bogus/duh" }
 ];
 
 // These are files that should refuse to play and report an error,
 // without crashing of course.
 // Put files of the same type together in this list so if something crashes
 // we have some idea of which backend is responsible.
+// Used by test_playback_errors.html
 var gErrorTests = [
-  { name: "bug495129.ogv", type:"video/ogg", duration:2.52 },
-  { name: "bug498855-1.ogv", type:"video/ogg", duration:0.2 },
-  { name: "bug498855-2.ogv", type:"video/ogg", duration:0.2 },
-  { name: "bug498855-3.ogv", type:"video/ogg", duration:0.2 },
-  { name: "bug501279.ogg", type:"audio/ogg", duration:0 },
-  { name: "bug504644.ogv", type:"video/ogg", duration:1.56 },
   { name:"bogus.wav", type:"audio/x-wav" },
   { name:"bogus.ogv", type:"video/ogg" },
   { name:"448636.ogv", type:"video/ogg" },
   { name:"bogus.duh", type:"bogus/duh" }
 ];
 
 // These are files that have nontrivial duration and are useful for seeking within.
 var gSeekTests = [
--- a/media/libfishsound/src/libfishsound/fishsound_vorbis.c
+++ b/media/libfishsound/src/libfishsound/fishsound_vorbis.c
@@ -407,16 +407,17 @@ fs_vorbis_enc_init (FishSound * fsound)
 #endif /* ! FS_ENCODE && HAVE_VORBISENC */
 
 static int
 fs_vorbis_reset (FishSound * fsound)
 {
   FishSoundVorbisInfo * fsv = (FishSoundVorbisInfo *)fsound->codec_data;
 
   vorbis_block_init (&fsv->vd, &fsv->vb);
+  fsv->packetno = 0;
 
   return 0;
 }
 
 static FishSound *
 fs_vorbis_init (FishSound * fsound)
 {
   FishSoundVorbisInfo * fsv;
--- a/media/liboggplay/README
+++ b/media/liboggplay/README
@@ -17,18 +17,18 @@ For the core library (liboggplay), you n
   * libogg, libvorbis, libtheora, optionally libspeex -- from http://www.xiph.org/
 
     svn co http://svn.xiph.org/trunk/ogg/ ogg
     svn co http://svn.xiph.org/trunk/vorbis/ vorbis
     svn co http://svn.xiph.org/trunk/theora/ theora
 
   * liboggz and libfishsound -- from svn.annodex.net:
 
-    svn co http://svn.annodex.net/liboggz/trunk liboggz
-    svn co http://svn.annodex.net/libfishsound/trunk libfishsound
+    git clone git://git.xiph.org/liboggz.git
+    git clone git://git.xiph.org/libfishsound.git
 
 Optionally, for Kate stream support, you need
 
   * libkate -- from http://libkate.googlecode.com/
 
 To render Kate streams as video overlays, you need
 
   * libtiger -- from http://libtiger.googlecode.com/
--- a/media/liboggplay/README_MOZILLA
+++ b/media/liboggplay/README_MOZILLA
@@ -1,49 +1,23 @@
 The source from this directory was copied from the liboggplay svn
 source using the update.sh script. The only changes made were those
 applied by update.sh and the addition/upate of Makefile.in files for
 the Mozilla build system.
 
 git://git.xiph.org/liboggplay.git
 
-The git commit ID used was b4a7efa06d46596515071490cb255c3548d90371.
+The git commit ID used was 8640eb3fddc43ad4a5d2cdbcbc62238204e952aa.
 
 The following local patches have been applied:
 
 endian: pick up NSPR's little/big endian defines in oggplay's config.h.
 
 bug481921: fix a crash in oggplay_callback_info_prepare().
 
-trac466: Fix for infinite loop in liboggplay when running decoder on its own thread. Cherry picked from liboggplay git commit e6871f.
-
-bug492436: Fix for that bug cherry picked from liboggplay git commit 4b97ad.
-bug493140: Fix for offsets not being used.
-
 aspect-ratio: Adds oggplay_get_video_aspect_ratio, used for bug 480058.
 
-bug493678.patch: fix for infinite loop in oggplay_step_decode. See bug 493678.
-
-bug493224.patch: Fix for bug 493224.
-
 seek_to_key_frame.patch: Adds oggplay_seek_to_keyframe(), as per bug 463358.
 
-bug488951: Fix for YUV conversion for odd sized frames.  Cherrypicked from
-           upstream commits dabde8, 683f23, and 4d7581.
-
-bug488951_fix_yuv: Additional fixes to YUV conversion that have not been
-                   upstreamed yet.
-
-bug488951_fix_yuv_2: Additional fix to YUV conversion for odd height videos
-                     that has not been upstreamed yet.
-
-bug495129a.patch: Fix from liboggplay commit 6c8e11.
-bug495129b.patch: Fix from liboggplay commit 3602bf.
-
-bug487519.patch: Fix for bug 487519.
-
 oggplay_os2.patch: Bug 448918 - add OS/2 support (this patch should be
                    removed when OS/2 support is added upstream)
 
-bug498815.patch: Fix for bug 498815.
-bug498824.patch: Fix for bug 498824.
-bug500311.patch: Fix crash during decoder initialization.
-
+bug496529.patch: Bug 496529.
--- a/media/liboggplay/aspect_ratio.patch
+++ b/media/liboggplay/aspect_ratio.patch
@@ -1,35 +1,35 @@
 diff --git a/media/liboggplay/include/oggplay/oggplay.h b/media/liboggplay/include/oggplay/oggplay.h
 --- a/media/liboggplay/include/oggplay/oggplay.h
 +++ b/media/liboggplay/include/oggplay/oggplay.h
-@@ -110,16 +110,19 @@ oggplay_get_audio_channels(OggPlay *me, 
- 
- OggPlayErrorCode
- oggplay_get_audio_samplerate(OggPlay *me, int track, int *samplerate); 
- 
+@@ -226,16 +226,19 @@ oggplay_get_audio_samplerate(OggPlay *me
+  * @retval E_OGGPLAY_BAD_TRACK the given track number does not exists
+  * @retval E_OGGPLAY_WRONG_TRACK_TYPE the given track is not an audio track
+  * @retval E_OGGPLAY_UNINITIALISED the OggPlay handle is uninitalised.
+  */
  OggPlayErrorCode
  oggplay_get_video_fps(OggPlay *me, int track, int* fps_denom, int* fps_num);
  
  OggPlayErrorCode
 +oggplay_get_video_aspect_ratio(OggPlay *me, int track, int* aspect_denom, int* aspect_num);
 +
 +OggPlayErrorCode
- oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert);
+ oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert, int swap_rgb);
  
  OggPlayErrorCode
  oggplay_get_kate_category(OggPlay *me, int track, const char** category);
  
  OggPlayErrorCode
  oggplay_get_kate_language(OggPlay *me, int track, const char** language);
  
 diff --git a/media/liboggplay/src/liboggplay/oggplay.c b/media/liboggplay/src/liboggplay/oggplay.c
 --- a/media/liboggplay/src/liboggplay/oggplay.c
 +++ b/media/liboggplay/src/liboggplay/oggplay.c
-@@ -280,16 +280,45 @@ oggplay_get_video_fps(OggPlay *me, int t
+@@ -301,16 +301,45 @@ oggplay_get_video_fps(OggPlay *me, int t
  
    (*fps_denom) = decode->video_info.fps_denominator;
    (*fps_num) = decode->video_info.fps_numerator;
  
    return E_OGGPLAY_OK;
  }
  
  OggPlayErrorCode
@@ -57,16 +57,16 @@ diff --git a/media/liboggplay/src/libogg
 +
 +  (*aspect_denom) = decode->video_info.aspect_denominator;
 +  (*aspect_num) = decode->video_info.aspect_numerator;
 +
 +  return E_OGGPLAY_OK;
 +}
 +
 +OggPlayErrorCode
- oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert) {
+ oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert, int swap_rgb) {
    OggPlayTheoraDecode *decode;
  
    if (me == NULL) {
      return E_OGGPLAY_BAD_OGGPLAY;
    }
  
    if (track < 0 || track >= me->num_tracks) {
--- a/media/liboggplay/bug481921.patch
+++ b/media/liboggplay/bug481921.patch
@@ -1,12 +1,12 @@
 diff --git a/media/liboggplay/src/liboggplay/oggplay_callback_info.c b/media/liboggplay/src/liboggplay/oggplay_callback_info.c
 --- a/media/liboggplay/src/liboggplay/oggplay_callback_info.c
 +++ b/media/liboggplay/src/liboggplay/oggplay_callback_info.c
-@@ -133,21 +133,23 @@ oggplay_callback_info_prepare(OggPlay *m
+@@ -185,21 +185,23 @@ oggplay_callback_info_prepare(OggPlay *m
  
      track_info->available_records = count;
      track_info->required_records = 0;
  
      track_info->data_type = track->decoded_type;
   
      count = 0;
      for (p = q; p != NULL; p = p->next) {
deleted file mode 100644
--- a/media/liboggplay/bug487519.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay_callback.c b/media/liboggplay/src/liboggplay/oggplay_callback.c
-index 428faee..344599a 100644
---- a/media/liboggplay/src/liboggplay/oggplay_callback.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_callback.c
-@@ -388,7 +388,13 @@ oggplay_callback_audio (OGGZ * oggz, ogg_packet * op, long serialno,
- 
-   fish_sound_prepare_truncation (decoder->sound_handle, op->granulepos,
-                                                                 op->e_o_s);
--  fish_sound_decode (decoder->sound_handle, op->packet, op->bytes);
-+  if (fish_sound_decode (decoder->sound_handle, op->packet, op->bytes) != 0) {
-+    // Unrecoverable error, disable track
-+    op->e_o_s = 1;
-+    common->active = 0;
-+    common->player->active_tracks--;
-+    return OGGZ_ERR_HOLE_IN_DATA;
-+  }
- 
-   if (decoder->sound_info.channels == 0) {
-     fish_sound_command(decoder->sound_handle, FISH_SOUND_GET_INFO,
deleted file mode 100644
--- a/media/liboggplay/bug488951.patch
+++ /dev/null
@@ -1,564 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
---- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
-@@ -42,76 +42,55 @@
-  */
- 
- #include "oggplay_private.h"
- #include "oggplay_yuv2rgb_template.h"
- 
- /* cpu extension detection */
- #include "cpu.c"
- 
--/* although we use cpu runtime detection, we still need these
-- * macros as there's no way e.g. we could compile a x86 asm code 
-- * on a ppc machine and vica-versa
-+/**
-+ * yuv_convert_fptr type is a function pointer type for
-+ * the various yuv-rgb converters
-  */
--#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
--#include "oggplay_yuv2rgb_x86.c"
--#elif defined(__ppc__) || defined(__ppc64__)
--//altivec intristics only working with -maltivec gcc flag, 
--//but we want runtime altivec detection, hence this has to be
--//fixed!
--//#include "oggplay_yuv2rgb_altivec.c"
--#endif
-+typedef void (*yuv_convert_fptr) (const OggPlayYUVChannels *yuv, 
-+					OggPlayRGBChannels *rgb);
- 
--static int yuv_initialized;
--static ogg_uint32_t cpu_features;
-+/* it is useless to determine each YUV conversion run
-+ * the cpu type/featurs, thus we save the conversion function
-+ * pointers
-+ */
-+static struct OggPlayYUVConverters {
-+	yuv_convert_fptr yuv2rgba; /**< YUV420 to RGBA */
-+	yuv_convert_fptr yuv2bgra; /**< YUV420 to BGRA */
-+	yuv_convert_fptr yuv2argb; /**< YUV420 to ARGB */
-+} yuv_conv = {NULL, NULL, NULL};
- 
- /**
-  * vanilla implementation of YUV-to-RGB conversion.
-  *
-  *  - using table-lookups instead of multiplication
-  *  - avoid CLAMPing by incorporating 
-  *
-  */
- 
--#define CLAMP(v)    ((v) > 255 ? 255 : (v) < 0 ? 0 : (v))
--
- #define prec 15 
- static const int CoY	= (int)(1.164 * (1 << prec) + 0.5);
- static const int CoRV	= (int)(1.596 * (1 << prec) + 0.5);
- static const int CoGU	= (int)(0.391 * (1 << prec) + 0.5);
- static const int CoGV	= (int)(0.813 * (1 << prec) + 0.5);
- static const int CoBU	= (int)(2.018 * (1 << prec) + 0.5);
- 
--static int CoefsGU[256];
-+static int CoefsGU[256] = {0};
- static int CoefsGV[256]; 
- static int CoefsBU[256]; 
- static int CoefsRV[256];
- static int CoefsY[256];
- 
--/**
-- * Initialize the lookup-table for vanilla yuv to rgb conversion
-- * and the cpu_features global.
-- */
--static void
--init_yuv_converters()
--{
--	int i;
--
--	for(i = 0; i < 256; ++i)
--	{
--		CoefsGU[i] = -CoGU * (i - 128);
--		CoefsGV[i] = -CoGV * (i - 128);
--		CoefsBU[i] = CoBU * (i - 128);
--		CoefsRV[i] = CoRV * (i - 128);
--		CoefsY[i]  = CoY * (i - 16) + (prec/2);
--	}
--
--	cpu_features = oc_cpu_flags_get();
--	yuv_initialized = 1;
--}
-+#define CLAMP(v)    ((v) > 255 ? 255 : (v) < 0 ? 0 : (v))
- 
- #define VANILLA_YUV2RGB_PIXEL(y, ruv, guv, buv)	\
- r = (CoefsY[y] + ruv) >> prec;	\
- g = (CoefsY[y] + guv) >> prec;	\
- b = (CoefsY[y] + buv) >> prec;	\
- 
- #define VANILLA_RGBA_OUT(out, r, g, b) \
- out[0] = CLAMP(r); \
-@@ -132,105 +111,155 @@ out[2] = CLAMP(g); \
- out[3] = CLAMP(b);
- 
- #define VANILLA_ABGR_OUT(out, r, g, b) \
- out[0] = 255;	   \
- out[1] = CLAMP(b); \
- out[2] = CLAMP(g); \
- out[3] = CLAMP(r);
- 
--/* yuv420p -> */
- #define LOOKUP_COEFFS int ruv = CoefsRV[*pv]; 			\
- 		      int guv = CoefsGU[*pu] + CoefsGV[*pv]; 	\
- 		      int buv = CoefsBU[*pu]; 			\
-                       int r, g, b;
- 
-+/* yuv420p -> */
- #define CONVERT(OUTPUT_FUNC) LOOKUP_COEFFS				 \
--			     VANILLA_YUV2RGB_PIXEL(py[0], ruv, guv, buv);\
--			     OUTPUT_FUNC(dst, r, g, b);			 \
--			     VANILLA_YUV2RGB_PIXEL(py[1], ruv, guv, buv);\
--			     OUTPUT_FUNC((dst+4), r, g, b);
-+			     VANILLA_YUV2RGB_PIXEL(py[0], ruv, guv, buv) \
-+			     OUTPUT_FUNC(dst, r, g, b)  \
-+			     VANILLA_YUV2RGB_PIXEL(py[1], ruv, guv, buv) \
-+			     OUTPUT_FUNC((dst+4), r, g, b)
- 
- #define CLEANUP
- 
--YUV_CONVERT(yuv420_to_rgba_vanilla, CONVERT(VANILLA_RGBA_OUT), 2, 8, 2, 1)
--YUV_CONVERT(yuv420_to_bgra_vanilla, CONVERT(VANILLA_BGRA_OUT), 2, 8, 2, 1)
--YUV_CONVERT(yuv420_to_abgr_vanilla, CONVERT(VANILLA_ABGR_OUT), 2, 8, 2, 1)
--YUV_CONVERT(yuv420_to_argb_vanilla, CONVERT(VANILLA_ARGB_OUT), 2, 8, 2, 1)
-+YUV_CONVERT(yuv420_to_rgba_vanilla, CONVERT(VANILLA_RGBA_OUT), VANILLA_RGBA_OUT, 2, 8, 2, 1)
-+YUV_CONVERT(yuv420_to_bgra_vanilla, CONVERT(VANILLA_BGRA_OUT), VANILLA_BGRA_OUT, 2, 8, 2, 1)
-+YUV_CONVERT(yuv420_to_abgr_vanilla, CONVERT(VANILLA_ABGR_OUT), VANILLA_ABGR_OUT, 2, 8, 2, 1)
-+YUV_CONVERT(yuv420_to_argb_vanilla, CONVERT(VANILLA_ARGB_OUT), VANILLA_ARGB_OUT, 2, 8, 2, 1)
- 
- #undef CONVERT
- #undef CLEANUP
- 
-+/* although we use cpu runtime detection, we still need these
-+ * macros as there's no way e.g. we could compile a x86 asm code 
-+ * on a ppc machine and vica-versa
-+ */
-+#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
-+#include "x86/oggplay_yuv2rgb_x86.c"
-+#elif defined(__ppc__) || defined(__ppc64__)
-+//altivec intristics only working with -maltivec gcc flag, 
-+//but we want runtime altivec detection, hence this has to be
-+//fixed!
-+//#include "oggplay_yuv2rgb_altivec.c"
-+#endif
-+
-+
-+/**
-+ * Initialize the lookup-table for vanilla yuv to rgb conversion.
-+ */
-+static void
-+init_vanilla_coeffs (void)
-+{
-+	int i;
-+
-+	for(i = 0; i < 256; ++i)
-+	{
-+		CoefsGU[i] = -CoGU * (i - 128);
-+		CoefsGV[i] = -CoGV * (i - 128);
-+		CoefsBU[i] = CoBU * (i - 128);
-+		CoefsRV[i] = CoRV * (i - 128);
-+		CoefsY[i]  = CoY * (i - 16) + (prec/2);
-+	}
-+}
-+
-+/**
-+ * Initialize the function pointers in yuv_conv.
-+ *
-+ * Initialize the function pointers in yuv_conv, based on the
-+ * the available CPU extensions.
-+ */
-+static void
-+init_yuv_converters(void)
-+{
-+	ogg_uint32_t features = 0;
-+
-+	if ( yuv_conv.yuv2rgba == NULL )
-+	{
-+		init_vanilla_coeffs ();
-+		features = oc_cpu_flags_get(); 		
-+#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
-+#if defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16 
-+		if (features & OC_CPU_X86_SSE2) 
-+		{
-+			yuv_conv.yuv2rgba = yuv420_to_rgba_sse2;
-+			yuv_conv.yuv2bgra = yuv420_to_bgra_sse2;
-+			yuv_conv.yuv2argb = yuv420_to_argb_sse2;
-+			return;
-+		}
-+		else
-+#endif /* ATTRIBUTE_ALIGNED_MAX */
-+		if (features & OC_CPU_X86_MMXEXT)	
-+		{
-+			yuv_conv.yuv2rgba = yuv420_to_rgba_sse;
-+			yuv_conv.yuv2bgra = yuv420_to_bgra_sse;
-+			yuv_conv.yuv2argb = yuv420_to_argb_sse;
-+			return;
-+		}
-+		else if (features & OC_CPU_X86_MMX)
-+		{   
-+			yuv_conv.yuv2rgba = yuv420_to_rgba_mmx;
-+			yuv_conv.yuv2bgra = yuv420_to_bgra_mmx;
-+			yuv_conv.yuv2argb = yuv420_to_argb_mmx;
-+			return;
-+		}
-+#elif defined(__ppc__) || defined(__ppc64__)
-+		if (features & OC_CPU_PPC_ALTIVEC)
-+		{
-+			yuv_conv.yuv2rgba = yuv420_to_abgr_vanilla;
-+			yuv_conv.yuv2bgra = yuv420_to_argb_vanilla;
-+			yuv_conv.yuv2argb = yuv420_to_bgra_vanilla;
-+			return;
-+		}
-+#endif		
-+		/*
-+     * no CPU extension was found... using vanilla converter, with respect
-+     * to the endianness of the host
-+     */
-+#if WORDS_BIGENDIAN || IS_BIG_ENDIAN 
-+		yuv_conv.yuv2rgba = yuv420_to_abgr_vanilla;
-+		yuv_conv.yuv2bgra = yuv420_to_argb_vanilla;
-+		yuv_conv.yuv2argb = yuv420_to_bgra_vanilla;
-+#else
-+		yuv_conv.yuv2rgba = yuv420_to_rgba_vanilla;
-+		yuv_conv.yuv2bgra = yuv420_to_bgra_vanilla;
-+		yuv_conv.yuv2argb = yuv420_to_argb_vanilla;
-+#endif
-+	}
-+}
-+
-+
- void
- oggplay_yuv2rgba(const OggPlayYUVChannels* yuv, OggPlayRGBChannels* rgb)
- {
--	if (!yuv_initialized)
-+	if (yuv_conv.yuv2rgba == NULL)
- 		init_yuv_converters();
- 
--#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
--#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
--	if (yuv->y_width % 16 == 0 && cpu_features & OC_CPU_X86_SSE2)
--		return yuv420_to_rgba_sse2(yuv, rgb);
--#endif
--	if (yuv->y_width % 8 == 0 && cpu_features & OC_CPU_X86_MMX)
--		return yuv420_to_rgba_mmx(yuv, rgb);
--#elif defined(__ppc__) || defined(__ppc64__)
--	if (yuv->y_width % 16 == 0 && yuv->y_height % 2 == 0 && cpu_features & OC_CPU_PPC_ALTIVEC)
--		return yuv420_to_abgr_vanilla(yuv, rgb);
--#endif
--
--#if WORDS_BIGENDIAN || IS_BIG_ENDIAN 
--	return yuv420_to_abgr_vanilla(yuv, rgb);
--#else
--	return yuv420_to_rgba_vanilla(yuv, rgb);
--#endif
-+	yuv_conv.yuv2rgba(yuv, rgb);
- }
- 
- void 
- oggplay_yuv2bgra(const OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb)
- {
--	if (!yuv_initialized)
-+	if (yuv_conv.yuv2bgra == NULL)
- 		init_yuv_converters();
- 
--#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
--#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
--	if (yuv->y_width % 16 == 0 && cpu_features & OC_CPU_X86_SSE2)
--		return yuv420_to_bgra_sse2(yuv, rgb);
--#endif
--	if (yuv->y_width % 8 == 0 && cpu_features & OC_CPU_X86_MMX)
--		return yuv420_to_bgra_mmx(yuv, rgb);
--#elif defined(__ppc__) || defined(__ppc64__)
--	if (yuv->y_width % 16 == 0 && yuv->y_height % 2 == 0 && cpu_features & OC_CPU_PPC_ALTIVEC)
--		return yuv420_to_argb_vanilla(yuv, rgb);
--#endif
--
--#if WORDS_BIGENDIAN || IS_BIG_ENDIAN 
--	return yuv420_to_argb_vanilla(yuv, rgb);
--#else
--	return yuv420_to_bgra_vanilla(yuv, rgb);
--#endif
-+	yuv_conv.yuv2bgra(yuv, rgb);
- }
- 
- void 
- oggplay_yuv2argb(const OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb)
- {
--	if (!yuv_initialized)
-+	if (yuv_conv.yuv2argb == NULL)
- 		init_yuv_converters();
- 
--#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
--#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
--	if (yuv->y_width % 16 == 0 && cpu_features & OC_CPU_X86_SSE2)
--		return yuv420_to_argb_sse2(yuv, rgb);
--#endif
--	if (yuv->y_width % 8 == 0 && cpu_features & OC_CPU_X86_MMX)
--		return yuv420_to_argb_mmx(yuv, rgb);
--#elif defined(__ppc__) || defined(__ppc64__)
--	if (yuv->y_width % 16 == 0 && yuv->y_height % 2 == 0 && cpu_features & OC_CPU_PPC_ALTIVEC)
--		return yuv420_to_bgra_vanilla(yuv, rgb);
--#endif
--
--#if WORDS_BIGENDIAN || IS_BIG_ENDIAN 
--	return yuv420_to_bgra_vanilla(yuv, rgb);
--#else
--	return yuv420_to_argb_vanilla(yuv, rgb);
--#endif
-+	yuv_conv.yuv2argb(yuv, rgb);
- }
- 
-diff --git a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
---- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
-+++ b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
-@@ -8,55 +8,80 @@
- #define restrict __restrict__
- #endif
- #endif
- 
- /**
-  * Template for YUV to RGB conversion
-  *
-  * @param FUNC function name
-- * @param CONVERT a macro that defines 
-+ * @param CONVERT a macro that defines the actual conversion function
-+ * @param VANILLA_OUT 
-  * @param NUM_PIXELS number of pixels processed in one iteration
-  * @param OUT_SHIFT number of pixels to shift after one iteration in rgb data stream
-  * @param Y_SHIFT number of pixels to shift after one iteration in Y data stream
-  * @param UV_SHIFT
-  */
--#define YUV_CONVERT(FUNC, CONVERT, NUM_PIXELS, OUT_SHIFT, Y_SHIFT, UV_SHIFT)\
-+#define YUV_CONVERT(FUNC, CONVERT, VANILLA_OUT, NUM_PIXELS, OUT_SHIFT, Y_SHIFT, UV_SHIFT)\
- static void                                                     \
- (FUNC)(const OggPlayYUVChannels* yuv, OggPlayRGBChannels* rgb)  \
- {                                                               \
--	int             i,j, w, h;                              \
-+	int             i,j, w, h, r;                           \
- 	unsigned char*  restrict ptry;                          \
- 	unsigned char*  restrict ptru;                          \
- 	unsigned char*  restrict ptrv;                          \
- 	unsigned char*  restrict ptro;                          \
- 	unsigned char   *dst, *py, *pu, *pv;                    \
- 								\
- 	ptro = rgb->ptro;                                       \
- 	ptry = yuv->ptry;                                       \
- 	ptru = yuv->ptru;                                       \
- 	ptrv = yuv->ptrv;                                       \
- 								\
--	w = yuv->y_width/NUM_PIXELS;                            \
-+	w = yuv->y_width / NUM_PIXELS;                          \
- 	h = yuv->y_height;                                      \
-+	r = yuv->y_width % NUM_PIXELS;				\
- 	for (i = 0; i < h; ++i)                                 \
- 	{                                                       \
- 		py  = ptry;                                     \
- 		pu  = ptru;                                     \
- 		pv  = ptrv;                                     \
- 		dst = ptro;                                     \
- 		for (j = 0; j < w; ++j,                         \
- 				dst += OUT_SHIFT,               \
- 				py += Y_SHIFT,                  \
- 				pu += UV_SHIFT,                 \
- 				pv += UV_SHIFT)                 \
- 		{                                               \
- 			/* use the given conversion function */ \
- 			CONVERT                                 \
- 		}                                               \
-+		/*						\
-+		 * the video frame is not the multiple of NUM_PIXELS, \
-+		 * thus we have to deal with remaning pixels using 	\
-+		 * vanilla implementation.				\
-+		 */						\
-+		if (r) { 					\
-+			for 					\
-+			( 					\
-+			  j=(yuv->y_width-r); j < yuv->y_width; \
-+			  ++j, 					\
-+			  dst += 4,				\
-+			  py += 1 				\
-+			) 					\
-+			{ 					\
-+				LOOKUP_COEFFS			\
-+				VANILLA_YUV2RGB_PIXEL(py[0], ruv, guv, buv) \
-+				VANILLA_OUT(dst, r, g, b)	\
-+				if (!(j%2)) { 			\
-+					pu += 1; pv += 1;	\
-+				} 				\
-+			}					\
-+		} 						\
-+								\
- 		ptro += rgb->rgb_width * 4;                     \
- 		ptry += yuv->y_width;                           \
- 								\
- 		if (i & 0x1)                                    \
- 		{                                               \
- 			ptru += yuv->uv_width;                  \
- 			ptrv += yuv->uv_width;                  \
- 		}                                               \
-diff --git a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_x86.c b/media/liboggplay/src/liboggplay/x86/oggplay_yuv2rgb_x86.c
-rename from media/liboggplay/src/liboggplay/oggplay_yuv2rgb_x86.c
-rename to media/liboggplay/src/liboggplay/x86/oggplay_yuv2rgb_x86.c
---- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_x86.c
-+++ b/media/liboggplay/src/liboggplay/x86/oggplay_yuv2rgb_x86.c
-@@ -28,16 +28,19 @@
-    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- 
- /**
-  * YUV to RGB conversion using x86 CPU extensions
-  */
-+#include "oggplay_private.h"
-+#include "oggplay_yuv2rgb_template.h"
-+#include "cpu.h"
- 
- #if defined(_MSC_VER)
- #include "yuv2rgb_x86_vs.h" 
- #elif defined(__GNUC__)
- #include "yuv2rgb_x86.h" 
- #endif
- 
- typedef union
-@@ -78,59 +81,72 @@ static const simd_t simd_table[9] = {
- 	{{ALFA, ALFA}}
- };
- 
- /**
-  *  the conversion functions using MMX instructions 
-  */
- 
- /* template for the MMX conversion functions */
--#define YUV_CONVERT_MMX(FUNC, CONVERT) YUV_CONVERT(FUNC, CONVERT, 8, 32, 8, 4)
-+#define YUV_CONVERT_MMX(FUNC, CONVERT, CONV_BY_PIXEL) YUV_CONVERT(FUNC, CONVERT, CONV_BY_PIXEL, 8, 32, 8, 4)
-+
- #define CLEANUP emms()
- #define OUT_RGBA_32 OUTPUT_RGBA_32(movq, mm, 8, 16, 24)
- #define OUT_ARGB_32 OUTPUT_ARGB_32(movq, mm, 8, 16, 24)
- #define OUT_BGRA_32 OUTPUT_BGRA_32(movq, mm, 8, 16, 24)
- #define MOVNTQ MMX_MOVNTQ
- 
- /* yuv420 -> */
- #define CONVERT(OUTPUT_FUNC) LOAD_YUV_PLANAR_2(movq, mm) \
--			     YUV_2_RGB(movq, mm) 	\
--			     OUTPUT_FUNC
-+                             YUV_2_RGB(movq, mm) 	\
-+                             OUTPUT_FUNC
- 
--YUV_CONVERT_MMX(yuv420_to_rgba_mmx, CONVERT(OUT_RGBA_32))
--YUV_CONVERT_MMX(yuv420_to_bgra_mmx, CONVERT(OUT_BGRA_32)) 
--YUV_CONVERT_MMX(yuv420_to_argb_mmx, CONVERT(OUT_ARGB_32)) 
-+YUV_CONVERT_MMX(yuv420_to_rgba_mmx, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT)
-+YUV_CONVERT_MMX(yuv420_to_bgra_mmx, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT) 
-+YUV_CONVERT_MMX(yuv420_to_argb_mmx, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT) 
-+
-+#undef MOVNTQ
-+
-+
-+/* template for the SSE conversion functions */
-+#define MOVNTQ SSE_MOVNTQ
-+
-+YUV_CONVERT_MMX(yuv420_to_rgba_sse, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT)
-+YUV_CONVERT_MMX(yuv420_to_bgra_sse, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT)
-+YUV_CONVERT_MMX(yuv420_to_argb_sse, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT)
-+
- #undef CONVERT
--
- #undef CLEANUP
- #undef OUT_RGBA_32
- #undef OUT_ARGB_32
- #undef OUT_BGRA_32
- #undef MOVNTQ
- 
-+
- /**
-  *  the conversion functions using SSE2 instructions 
-  */
- 
- /* template for the SSE2 conversion functions */
--#define YUV_CONVERT_SSE2(FUNC, CONVERT) YUV_CONVERT(FUNC, CONVERT, 16, 64, 16, 8)
-+#define YUV_CONVERT_SSE2(FUNC, CONVERT, CONV_BY_PIX) YUV_CONVERT(FUNC, CONVERT, CONV_BY_PIX, 16, 64, 16, 8)
-+
- #define OUT_RGBA_32 OUTPUT_RGBA_32(movdqa, xmm, 16, 32, 48)
- #define OUT_ARGB_32 OUTPUT_ARGB_32(movdqa, xmm, 16, 32, 48)
- #define OUT_BGRA_32 OUTPUT_BGRA_32(movdqa, xmm, 16, 32, 48)
- #define MOVNTQ SSE2_MOVNTQ
- #define CLEANUP
- 
- /* yuv420 -> */
- #define CONVERT(OUTPUT_FUNC) LOAD_YUV_PLANAR_2(movdqu, xmm) \
--       			     YUV_2_RGB(movdqa, xmm)	\
--			     OUTPUT_FUNC
-+				YUV_2_RGB(movdqa, xmm)	\
-+				OUTPUT_FUNC
- 
--YUV_CONVERT_SSE2(yuv420_to_rgba_sse2, CONVERT(OUT_RGBA_32))
--YUV_CONVERT_SSE2(yuv420_to_bgra_sse2, CONVERT(OUT_BGRA_32))
--YUV_CONVERT_SSE2(yuv420_to_argb_sse2, CONVERT(OUT_ARGB_32)) 
-+YUV_CONVERT_SSE2(yuv420_to_rgba_sse2, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT)
-+YUV_CONVERT_SSE2(yuv420_to_bgra_sse2, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT)
-+YUV_CONVERT_SSE2(yuv420_to_argb_sse2, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT)
-+
- #undef CONVERT
--
- #undef OUT_RGBA_32
- #undef OUT_ARGB_32
- #undef OUT_BGRA_32
- #undef MOVNTQ
--#undef CLEANUP 
-+#undef CLEANUP
- 
-diff --git a/media/liboggplay/src/liboggplay/yuv2rgb_x86.h b/media/liboggplay/src/liboggplay/x86/yuv2rgb_x86.h
-rename from media/liboggplay/src/liboggplay/yuv2rgb_x86.h
-rename to media/liboggplay/src/liboggplay/x86/yuv2rgb_x86.h
---- a/media/liboggplay/src/liboggplay/yuv2rgb_x86.h
-+++ b/media/liboggplay/src/liboggplay/x86/yuv2rgb_x86.h
-@@ -3,17 +3,18 @@
- 
- # ifdef ATTRIBUTE_ALIGNED_MAX
- #define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
- # else
- #define ATTR_ALIGN(align)
- # endif
- 
- #define emms() __asm__ __volatile__ ( "emms;" );
--#define MMX_MOVNTQ "movntq"
-+#define MMX_MOVNTQ "movq"
-+#define SSE_MOVNTQ "movntq"
- #define SSE2_MOVNTQ "movdqu"
- 
- #define YUV_2_RGB(mov_instr, reg_type) \
- 	__asm__ __volatile__ (		\
- 			"punpcklbw %%"#reg_type"4, %%"#reg_type"0;" 	/* mm0 = u3 u2 u1 u0 */\
- 			"punpcklbw %%"#reg_type"4, %%"#reg_type"1;"	/* mm1 = v3 v2 v1 v0 */\
- 			"psubsw (%0), %%"#reg_type"0;"			/* u -= 128 */\
- 			"psubsw (%0), %%"#reg_type"1;"			/* v -= 128 */\
-diff --git a/media/liboggplay/src/liboggplay/yuv2rgb_x86_vs.h b/media/liboggplay/src/liboggplay/x86/yuv2rgb_x86_vs.h
-rename from media/liboggplay/src/liboggplay/yuv2rgb_x86_vs.h
-rename to media/liboggplay/src/liboggplay/x86/yuv2rgb_x86_vs.h
---- a/media/liboggplay/src/liboggplay/yuv2rgb_x86_vs.h
-+++ b/media/liboggplay/src/liboggplay/x86/yuv2rgb_x86_vs.h
-@@ -1,15 +1,16 @@
- #ifndef __OGGPLAY_YUV2RGB_VS_H__
- #define __OGGPLAY_YUV2RGB_VS_H__
- 
- #define ATTR_ALIGN(_align) __declspec(align(_align))
- 
- #define emms() __asm emms
--#define MMX_MOVNTQ movntq
-+#define MMX_MOVNTQ movq
-+#define SSE_MOVNTQ movntq
- #define SSE2_MOVNTQ movdqu
- 
- #define LOAD_YUV_PLANAR_2(mov_instr, reg_type)		\
- 	__asm {								\
- 		__asm mov	eax, py					\
- 		__asm mov	edx, pu					\
- 		__asm mov_instr	reg_type##6, [eax]			\
- 		__asm mov_instr	reg_type##0, [edx]			\
deleted file mode 100644
--- a/media/liboggplay/bug488951_yuv_fix.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
---- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
-+++ b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
-@@ -55,28 +55,38 @@ static void                             
- 			CONVERT                                 \
- 		}                                               \
- 		/*						\
- 		 * the video frame is not the multiple of NUM_PIXELS, \
- 		 * thus we have to deal with remaning pixels using 	\
- 		 * vanilla implementation.				\
- 		 */						\
- 		if (r) { 					\
-+			/* if there's only 1 remaining pixel to process  \
-+			   and the luma width is odd, the for loop above \
-+			   has already advanced pu and pv too far. */    \
-+			if (r==1 && yuv->y_width&1) {           \
-+				pu -= 1; pv -= 1;               \
-+			}                                       \
- 			for 					\
- 			( 					\
- 			  j=(yuv->y_width-r); j < yuv->y_width; \
- 			  ++j, 					\
- 			  dst += 4,				\
- 			  py += 1 				\
- 			) 					\
- 			{ 					\
- 				LOOKUP_COEFFS			\
- 				VANILLA_YUV2RGB_PIXEL(py[0], ruv, guv, buv) \
- 				VANILLA_OUT(dst, r, g, b)	\
--				if (!(j%2)) { 			\
-+				/* advance chroma ptrs every second sample, except \
-+				   when the luma width is odd, in which case the   \
-+				   chroma samples are truncated and we must reuse  \
-+				   the previous chroma sample */                   \
-+				if (j%2 && !(j+1==yuv->y_width-1 && yuv->y_width&1)) { \
- 					pu += 1; pv += 1;	\
- 				} 				\
- 			}					\
- 		} 						\
- 								\
- 		ptro += rgb->rgb_width * 4;                     \
- 		ptry += yuv->y_width;                           \
- 								\
deleted file mode 100644
--- a/media/liboggplay/bug488951_yuv_fix_2.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
---- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
-+++ b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
-@@ -85,17 +85,17 @@ static void                             
- 					pu += 1; pv += 1;	\
- 				} 				\
- 			}					\
- 		} 						\
- 								\
- 		ptro += rgb->rgb_width * 4;                     \
- 		ptry += yuv->y_width;                           \
- 								\
--		if (i & 0x1)                                    \
-+		if (i & 0x1 && !(i+1==h-1 && h&1))              \
- 		{                                               \
- 			ptru += yuv->uv_width;                  \
- 			ptrv += yuv->uv_width;                  \
- 		}                                               \
- 	}                                                       \
- 	CLEANUP                                                 \
- }  
- 
deleted file mode 100644
--- a/media/liboggplay/bug492436.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-diff --git a/media/liboggplay/include/oggplay/oggplay_enums.h b/media/liboggplay/include/oggplay/oggplay_enums.h
-index aff0e51..ffb7cb4 100644
---- a/media/liboggplay/include/oggplay/oggplay_enums.h
-+++ b/media/liboggplay/include/oggplay/oggplay_enums.h
-@@ -64,6 +64,9 @@ typedef enum OggPlayErrorCode {
-   E_OGGPLAY_NO_KATE_SUPPORT   = -19,
-   E_OGGPLAY_NO_TIGER_SUPPORT  = -20,
-   E_OGGPLAY_OUT_OF_MEMORY     = -21,
-+  E_OGGPLAY_TYPE_OVERFLOW     = -22,  /**< Integer overflow detected */
-+  
-+  E_OGGPLAY_TRACK_IS_UNKNOWN  = -23,  /**< The selected track's content type is UNKNOWN */
-   E_OGGPLAY_NOTCHICKENPAYBACK = -777
- } OggPlayErrorCode;
- 
-diff --git a/media/liboggplay/src/liboggplay/oggplay_callback.c b/media/liboggplay/src/liboggplay/oggplay_callback.c
-index 05cf363..593691f 100644
---- a/media/liboggplay/src/liboggplay/oggplay_callback.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_callback.c
-@@ -508,6 +508,7 @@ OggPlayCallbackFunctions callbacks[] = {
-   {NULL, NULL, NULL, sizeof(OggPlayDecode)}, /* CELT */
-   {oggplay_init_kate, oggplay_callback_kate, oggplay_shutdown_kate,
-         sizeof(OggPlayKateDecode)},          /* KATE */
-+  {NULL, NULL, NULL, sizeof(OggPlayDecode)}, /* DIRAC */
-   {NULL, NULL, NULL, sizeof(OggPlayDecode)}  /* UNKNOWN */
- };
- 
-diff --git a/media/liboggplay/src/liboggplay/oggplay_query.c b/media/liboggplay/src/liboggplay/oggplay_query.c
-index 2a69beb..6344ec8 100644
---- a/media/liboggplay/src/liboggplay/oggplay_query.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_query.c
-@@ -131,6 +131,10 @@ oggplay_set_track_active(OggPlay *me, int track_num) {
-     return E_OGGPLAY_TRACK_IS_SKELETON;
-   }
- 
-+  if (me->decode_data[track_num]->content_type == OGGZ_CONTENT_UNKNOWN) {
-+    return E_OGGPLAY_TRACK_IS_UNKNOWN;
-+  }
-+
-   if ((p = me->decode_data[track_num]->final_granulepos) != -1) {
-     if (p * me->decode_data[track_num]->granuleperiod > me->target) {
-       return E_OGGPLAY_TRACK_IS_OVER;
-@@ -179,6 +183,10 @@ oggplay_set_track_inactive(OggPlay *me, int track_num) {
-     return E_OGGPLAY_TRACK_IS_SKELETON;
-   }
- 
-+  if (me->decode_data[track_num]->content_type == OGGZ_CONTENT_UNKNOWN) {
-+    return E_OGGPLAY_TRACK_IS_UNKNOWN;
-+  }
-+
-   if (me->decode_data[track_num]->active == 1) {
-     me->decode_data[track_num]->active = 0;
- 
deleted file mode 100644
--- a/media/liboggplay/bug493140.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay_callback.c b/media/liboggplay/src/liboggplay/oggplay_callback.c
-index 593691f..7683b80 100644
---- a/media/liboggplay/src/liboggplay/oggplay_callback.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_callback.c
-@@ -107,6 +107,11 @@ oggplay_callback_theora (OGGZ * oggz, ogg_packet * op, long serialno,
-     decoder->uv_width = decoder->uv_stride = decoder->video_info.frame_width / 2;
-     decoder->uv_height = decoder->video_info.frame_height / 2;
-     if (--(decoder->remaining_header_packets) == 0) {
-+      /* Ensure the offsets do not push the viewable area outside of the decoded frame. */
-+      if (((decoder->video_info.height - decoder->video_info.offset_y)<decoder->video_info.frame_height)||
-+          ((decoder->video_info.width - decoder->video_info.offset_x)<decoder->video_info.frame_width))
-+          return -1;
-+          
-       theora_decode_init(&(decoder->video_handle), &(decoder->video_info));
-     }
-     return 0;
-diff --git a/media/liboggplay/src/liboggplay/oggplay_data.c b/media/liboggplay/src/liboggplay/oggplay_data.c
-index 57a9458..c519d59 100644
---- a/media/liboggplay/src/liboggplay/oggplay_data.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_data.c
-@@ -323,6 +323,7 @@ oggplay_data_handle_theora_frame (OggPlayTheoraDecode *decode,
- 
-   int                   size = sizeof (OggPlayVideoRecord);
-   int                   i;
-+  int                   uv_offset;
-   unsigned char       * p;
-   unsigned char       * q;
-   unsigned char       * p2;
-@@ -359,17 +360,20 @@ oggplay_data_handle_theora_frame (OggPlayTheoraDecode *decode,
-    * a row-by-row copy (stride may be negative)
-    */
-   p = data->y;
--  q = buffer->y;
-+  q = buffer->y + (decode->video_info.offset_x&~1)+buffer->y_stride*(decode->video_info.offset_y&~1);
-   for (i = 0; i < decode->y_height; i++) {
-     memcpy(p, q, decode->y_width);
-     p += decode->y_width;
-     q += buffer->y_stride;
-   }
- 
-+  uv_offset = (decode->video_info.offset_x/(decode->y_width/decode->uv_width)) + 
-+              (buffer->uv_stride) *(decode->video_info.offset_y/(decode->y_height/decode->uv_height));
-+
-   p = data->u;
--  q = buffer->u;
-+  q = buffer->u + uv_offset;
-   p2 = data->v;
--  q2 = buffer->v;
-+  q2 = buffer->v + uv_offset;
-   for (i = 0; i < decode->uv_height; i++) {
-     memcpy(p, q, decode->uv_width);
-     memcpy(p2, q2, decode->uv_width);
deleted file mode 100644
--- a/media/liboggplay/bug493224.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-diff --git a/src/liboggplay/oggplay_callback.c b/src/liboggplay/oggplay_callback.c
-index f3e2339..39380e7 100644
---- a/src/liboggplay/oggplay_callback.c
-+++ b/src/liboggplay/oggplay_callback.c
-@@ -109,6 +109,15 @@ oggplay_callback_theora (OGGZ * oggz, ogg_packet * op, long serialno,
-   int                     musec;
- #endif
- 
-+  if ( (granulepos > 0) && (common->last_granulepos > granulepos)) {
-+    /* 
-+     * the granule position is not monotonically increasing,
-+     * something wrong with the page!
-+     * skipping this page..... 
-+     */
-+    return 0;
-+  }
-+
-   /*
-    * always decode headers
-    */
-@@ -174,10 +183,19 @@ oggplay_callback_theora (OGGZ * oggz, ogg_packet * op, long serialno,
- #endif
- 
-   if (granulepos != -1) {
-+    /* 
-+     * save last granule position in order to be able to validate
-+     * that it's monotonically increasing
-+     */
-+    common->last_granulepos = granulepos;
-+
-+    /* calculate the frame number */
-     granuleshift = oggz_get_granuleshift(oggz, serialno);
-     frame = (granulepos >> granuleshift);
-     frame += (granulepos & ((1 << granuleshift) - 1));
--    common->current_loc = frame * common->granuleperiod;
-+    
-+    /* calculate the current location in the stream */
-+    common->current_loc = frame * common->granuleperiod;    
-   } else {
-     common->current_loc = -1;
-   }
-diff --git a/src/liboggplay/oggplay_private.h b/src/liboggplay/oggplay_private.h
-index fb73f1d..1455c68 100644
---- a/src/liboggplay/oggplay_private.h
-+++ b/src/liboggplay/oggplay_private.h
-@@ -142,22 +142,22 @@ struct _OggPlayCallbackInfo {
-  *                              track
-  */
- typedef struct {
--  long                  serialno;
--  int                   content_type;
--  const char          * content_type_name;
--  OggPlayDataType       decoded_type;
--  ogg_int64_t           granuleperiod;
--  ogg_int64_t           last_granulepos;
--  ogg_int64_t           offset;
--  ogg_int64_t           current_loc;
--  int                   active;
--  ogg_int64_t           final_granulepos;
--  struct _OggPlay     * player;
--  OggPlayDataHeader   * data_list;
--  OggPlayDataHeader   * end_of_data_list;
--  OggPlayDataHeader   * untimed_data_list;
--  OggPlayStreamInfo     stream_info;
--  int                   preroll;
-+  long                  serialno;           /**< identifies the logical bit stream */
-+  int                   content_type;       
-+  const char          * content_type_name;  
-+  OggPlayDataType       decoded_type;       /**< type of the track @see OggPlayDataType */
-+  ogg_int64_t           granuleperiod;      
-+  ogg_int64_t           last_granulepos;    /**< last seen granule position */
-+  ogg_int64_t           offset;             /**<  */
-+  ogg_int64_t           current_loc;        /**< current location in the stream (in ) */
-+  int                   active;             /**< indicates whether the track is active or not */
-+  ogg_int64_t           final_granulepos;   /**<  */
-+  struct _OggPlay     * player;             /**< reference to the OggPlay handle */
-+  OggPlayDataHeader   * data_list;          
-+  OggPlayDataHeader   * end_of_data_list;   
-+  OggPlayDataHeader   * untimed_data_list;  
-+  OggPlayStreamInfo     stream_info;        /**< @see OggPlayStreamInfo */
-+  int                   preroll;            /**< num. of past content packets to take into account when decoding the current Ogg page */
- } OggPlayDecode;
- 
- typedef struct {
-@@ -190,6 +190,9 @@ typedef struct {
-   int             granuleshift;
- } OggPlayCmmlDecode;
- 
-+/**
-+ * OggPlaySkeletonDecode
-+ */
- typedef struct {
-   OggPlayDecode   decoder;
-   ogg_int64_t     presentation_time;
-diff --git a/src/liboggplay/oggplay_seek.c b/src/liboggplay/oggplay_seek.c
-index e74c136..ef150b8 100644
---- a/src/liboggplay/oggplay_seek.c
-+++ b/src/liboggplay/oggplay_seek.c
-@@ -133,6 +133,7 @@ oggplay_seek_cleanup(OggPlay* me, ogg_int64_t milliseconds)
-     track->data_list = track->end_of_data_list = NULL;
-     track->untimed_data_list = NULL;
-     track->current_loc = -1;
-+    track->last_granulepos = -1;
-     track->stream_info = OGGPLAY_STREAM_JUST_SEEKED;
-   }
- 
deleted file mode 100644
--- a/media/liboggplay/bug493678.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay_callback.c b/media/liboggplay/src/liboggplay/oggplay_callback.c
-index 7683b80..ad127a0 100644
---- a/media/liboggplay/src/liboggplay/oggplay_callback.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_callback.c
-@@ -536,7 +536,7 @@ oggplay_initialise_decoder(OggPlay *me, int content_type, int serialno) {
-   decoder->content_type = content_type;
-   decoder->content_type_name =
-           oggz_stream_get_content_type (me->oggz, serialno);
--  decoder->active = 1;
-+  decoder->active = 0;
-   decoder->final_granulepos = -1;
-   decoder->player = me;
-   decoder->decoded_type = OGGPLAY_TYPE_UNKNOWN;
deleted file mode 100644
--- a/media/liboggplay/bug495129a.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-commit 6c8e110015c829e04d8f5fb2ac53b23f468d58ed
-Author: Viktor Gal <viktor.gal@maeth.com>
-Date:   Thu May 28 10:02:27 2009 +1000
-
-    Fix for ticket 475: fix NULL pointer dereference in oggplay_seek_cleanup function.
-    The fix proposed by Chris Double in annodex trac could cause another
-    NULL pointer dereference, in case of not enough memory for allocating new buffer.
-
-diff --git a/src/liboggplay/oggplay_seek.c b/src/liboggplay/oggplay_seek.c
-index ef150b8..7d7073d 100644
---- a/src/liboggplay/oggplay_seek.c
-+++ b/src/liboggplay/oggplay_seek.c
-@@ -104,6 +104,9 @@ oggplay_seek_cleanup(OggPlay* me, ogg_int64_t milliseconds)
-   /*
-    * store the old buffer in it next.
-    */
-+  if (me->buffer == NULL)
-+    return;
-+  
-   trash->old_buffer = (OggPlayBuffer *)me->buffer;
- 
-   /*
deleted file mode 100644
--- a/media/liboggplay/bug495129b.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-commit 3602bf643830c63f499928623f47ae9635a8db51
-Author: Viktor Gal <viktor.gal@maeth.com>
-Date:   Tue Apr 14 17:20:24 2009 +1000
-
-    Fix for Mozilla 481933.
-    
-    WARNING:
-    You will need the patch of 38b6dffb5ec8b32119704bd048d722a281d9fd79
-    in oggz repository, otherwise you won't be able to play back chopped Ogg content!
-
-diff --git a/src/liboggplay/oggplay.c b/src/liboggplay/oggplay.c
-index 3296fea..0b03a3a 100644
---- a/src/liboggplay/oggplay.c
-+++ b/src/liboggplay/oggplay.c
-@@ -687,6 +687,8 @@ read_more_data:
-       }
- 
-       return E_OGGPLAY_OK;
-+    } else if (r == OGGZ_ERR_HOLE_IN_DATA) {
-+      return E_OGGPLAY_BAD_INPUT;
-     }
- 
-   }
--- a/media/liboggplay/bug496529.patch
+++ b/media/liboggplay/bug496529.patch
@@ -1,22 +1,22 @@
 diff --git a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
 --- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
 +++ b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
-@@ -181,17 +181,17 @@ init_yuv_converters(void)
- {
- 	ogg_uint32_t features = 0;
- 
- 	if ( yuv_conv.yuv2rgba == NULL )
- 	{
- 		init_vanilla_coeffs ();
- 		features = oc_cpu_flags_get(); 		
- #if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
+@@ -174,17 +174,17 @@ YUV_CONVERT(yuv444_to_argb_vanilla, CONV
+  * macros as there's no way e.g. we could compile a x86 asm code 
+  * on a ppc machine and vica-versa
+  */
+ #if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64)
+ #if !defined(_M_AMD64)
+ #define ENABLE_MMX
+ #endif
+ #include "x86/oggplay_yuv2rgb_x86.c"
 -#if defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16 
 +#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
- 		if (features & OC_CPU_X86_SSE2) 
- 		{
- 			yuv_conv.yuv2rgba = yuv420_to_rgba_sse2;
- 			yuv_conv.yuv2bgra = yuv420_to_bgra_sse2;
- 			yuv_conv.yuv2argb = yuv420_to_argb_sse2;
- 			return;
- 		}
- 		else
+ #define ENABLE_SSE2
+ #endif
+ #elif defined(__ppc__) || defined(__ppc64__)
+ #define ENABLE_ALTIVEC
+ //altivec intristics only working with -maltivec gcc flag, 
+ //but we want runtime altivec detection, hence this has to be
+ //fixed!
+ //#include "oggplay_yuv2rgb_altivec.c"
deleted file mode 100644
--- a/media/liboggplay/bug498815.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay_callback.c b/media/liboggplay/src/liboggplay/oggplay_callback.c
-index 8706014..bd45123 100644
---- a/media/liboggplay/src/liboggplay/oggplay_callback.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_callback.c
-@@ -701,8 +701,8 @@ oggplay_callback_predetected (OGGZ *oggz, ogg_packet *op, long serialno,
-    * call appropriate callback
-    */
-   if (callbacks[content_type].callback != NULL) {
--    callbacks[content_type].callback(oggz, op, serialno,
--                                          me->decode_data[me->num_tracks - 1]);
-+    return callbacks[content_type].callback(oggz, op, serialno,
-+                                            me->decode_data[me->num_tracks - 1]);
-   }
- 
-   return 0;
deleted file mode 100644
--- a/media/liboggplay/bug498824.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay_callback.c b/media/liboggplay/src/liboggplay/oggplay_callback.c
-index b046618..5f4ab31 100644
---- a/media/liboggplay/src/liboggplay/oggplay_callback.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_callback.c
-@@ -642,15 +642,15 @@ oggplay_callback_predetected (OGGZ *oggz, ogg_packet *op, long serialno,
-    */
-   for (i = 0; i < me->num_tracks; i++) {
-     if (serialno == me->decode_data[i]->serialno) {
--
-+      int ret = 0;
-       me->all_tracks_initialised = 1;
- 
-       /*
-        * call appropriate callback
-        */
-       if (callbacks[content_type].callback != NULL) {
--        callbacks[content_type].callback(oggz, op, serialno,
--                                          me->decode_data[i]);
-+        ret = callbacks[content_type].callback(oggz, op, serialno,
-+                                               me->decode_data[i]);
-       }
- 
-       /*
-@@ -668,7 +668,7 @@ oggplay_callback_predetected (OGGZ *oggz, ogg_packet *op, long serialno,
-        */
-       oggz_set_read_callback (me->oggz, -1, NULL, NULL);
- 
--      return 0;
-+      return ret < 0 ? OGGZ_ERR_HOLE_IN_DATA : ret;
-     }
-   }
- 
deleted file mode 100644
--- a/media/liboggplay/bug499519.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay_callback.c b/media/liboggplay/src/liboggplay/oggplay_callback.c
---- a/media/liboggplay/src/liboggplay/oggplay_callback.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_callback.c
-@@ -115,6 +115,15 @@
-     decoder->y_height = decoder->video_info.frame_height;
-     decoder->uv_width = decoder->uv_stride = decoder->video_info.frame_width / 2;
-     decoder->uv_height = decoder->video_info.frame_height / 2;
-+  
-+    if (decoder->y_width == 0 ||
-+        decoder->y_height == 0 || 
-+        decoder->uv_width == 0 ||
-+        decoder->uv_height == 0) {
-+      decoder->decoder.active = 0;
-+      return 0;
-+    }
-+    
-     if (--(decoder->remaining_header_packets) == 0) {
-       /* Ensure the offsets do not push the viewable area outside of the decoded frame. */
-       if (((decoder->video_info.height - decoder->video_info.offset_y)<decoder->video_info.frame_height)||
-diff --git a/media/liboggplay/src/liboggplay/oggplay_data.c b/media/liboggplay/src/liboggplay/oggplay_data.c
---- a/media/liboggplay/src/liboggplay/oggplay_data.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_data.c
-@@ -317,6 +317,23 @@
- 
- }
- 
-+static int
-+get_uv_offset(OggPlayTheoraDecode *decode, yuv_buffer *buffer)
-+{
-+  int xo=0, yo = 0;
-+  if (decode->y_width != 0 &&
-+      decode->uv_width != 0 &&
-+      decode->y_width/decode->uv_width != 0) {
-+    xo = (decode->video_info.offset_x/(decode->y_width/decode->uv_width));
-+  }
-+  if (decode->y_height != 0 &&
-+      decode->uv_height != 0 &&
-+      decode->y_height/decode->uv_height != 0) {
-+    yo = (buffer->uv_stride)*(decode->video_info.offset_y/(decode->y_height/decode->uv_height));
-+  }
-+  return xo + yo;
-+}
-+
- void
- oggplay_data_handle_theora_frame (OggPlayTheoraDecode *decode,
-                                     yuv_buffer *buffer) {
-@@ -367,8 +384,7 @@
-     q += buffer->y_stride;
-   }
- 
--  uv_offset = (decode->video_info.offset_x/(decode->y_width/decode->uv_width)) + 
--              (buffer->uv_stride) *(decode->video_info.offset_y/(decode->y_height/decode->uv_height));
-+  uv_offset = get_uv_offset(decode, buffer);
- 
-   p = data->u;
-   q = buffer->u + uv_offset;
deleted file mode 100644
--- a/media/liboggplay/bug500311.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay.c b/media/liboggplay/src/liboggplay/oggplay.c
---- a/media/liboggplay/src/liboggplay/oggplay.c
-+++ b/media/liboggplay/src/liboggplay/oggplay.c
-@@ -129,16 +129,17 @@ oggplay_initialise(OggPlay *me, int bloc
-   }
- 
-   /*
-    * set all the tracks to inactive
-    */
-   for (i = 0; i < me->num_tracks; i++) {
-     me->decode_data[i]->active = 0;
-   }
-+  me->active_tracks = 0;
- 
-   /*
-    * if the buffer was set up before initialisation, prepare it now
-    */
-   if (me->buffer != NULL) {
-     oggplay_buffer_prepare(me);
-   }
- 
-@@ -693,18 +694,18 @@ read_more_data:
-     /* end-of-file */
-     if (r == 0) {
-       num_records = oggplay_callback_info_prepare(me, &info);
-      /*
-        * set all of the tracks to inactive
-        */
-       for (i = 0; i < me->num_tracks; i++) {
-         me->decode_data[i]->active = 0;
--        me->active_tracks = 0;
-       }
-+      me->active_tracks = 0;
- 
-       if (info != NULL) {
-         me->callback (me, num_records, info, me->callback_user_ptr);
-         oggplay_callback_info_destroy(me, info);
-       }
- 
-       /*
-        * ensure all tracks have their final data packet set to end_of_stream
-diff --git a/media/liboggplay/src/liboggplay/oggplay_callback.c b/media/liboggplay/src/liboggplay/oggplay_callback.c
---- a/media/liboggplay/src/liboggplay/oggplay_callback.c
-+++ b/media/liboggplay/src/liboggplay/oggplay_callback.c
-@@ -54,16 +54,17 @@ oggplay_init_theora(void *user_data) {
-   theora_info_init(&(decoder->video_info));
-   theora_comment_init(&(decoder->video_comment));
-   decoder->remaining_header_packets = 3;
-   decoder->granulepos_seen = 0;
-   decoder->frame_delta = 0;
-   decoder->y_width = 0;
-   decoder->convert_to_rgb = 0;
-   decoder->decoder.decoded_type = OGGPLAY_YUV_VIDEO;
-+  decoder->decoder.player->active_tracks++;
- }
- 
- void
- oggplay_shutdown_theora(void *user_data) {
- 
-   OggPlayTheoraDecode   * decoder = (OggPlayTheoraDecode *)user_data;
- 
-   if (decoder->remaining_header_packets == 0) {
-@@ -366,16 +367,17 @@ oggplay_init_audio (void * user_data) {
- 
-   decoder->sound_info.channels = 0;
-   fish_sound_set_interleave(decoder->sound_handle, 1);
-   fish_sound_set_decoded_float_ilv(decoder->sound_handle,
-                                       oggplay_fish_sound_callback_floats,
-                                       (void *)decoder);
- 
-   decoder->decoder.decoded_type = OGGPLAY_FLOATS_AUDIO;
-+  decoder->decoder.player->active_tracks++;
- }
- 
- void
- oggplay_shutdown_audio(void *user_data) {
- 
-   OggPlayAudioDecode   * decoder = (OggPlayAudioDecode *)user_data;
- 
-   fish_sound_delete(decoder->sound_handle);
-@@ -566,17 +568,17 @@ oggplay_initialise_decoder(OggPlay *me, 
- 
-   if (decoder == NULL)
-     return NULL;
- 
-   decoder->serialno = serialno;
-   decoder->content_type = content_type;
-   decoder->content_type_name =
-           oggz_stream_get_content_type (me->oggz, serialno);
--  decoder->active = 0;
-+  decoder->active = 1;
-   decoder->final_granulepos = -1;
-   decoder->player = me;
-   decoder->decoded_type = OGGPLAY_TYPE_UNKNOWN;
- 
-   /*
-    * set the StreamInfo to unitialised until we get some real data in
-    */
-   decoder->stream_info = OGGPLAY_STREAM_UNINITIALISED;
--- a/media/liboggplay/include/oggplay/config_win32.h
+++ b/media/liboggplay/include/oggplay/config_win32.h
@@ -51,17 +51,17 @@
 
 /* Define to the version of this package. */
 #define PACKAGE_VERSION ""
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Version number of package */
-#define VERSION "0.0.1.svn"
+#define VERSION "0.2.0"
 
 /* Request Winsock 2.2 */
 #define HAVE_WINSOCK2 1
 
 /* Make sure inline is treated properly */ 
 #define inline __inline
 
 /* snprintf portability */
@@ -70,9 +70,9 @@
 /* Define to 1 if your processor stores words with the most significant byte
    first (like Motorola and SPARC, unlike Intel and VAX). */
 /* #undef WORDS_BIGENDIAN */
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* #undef const */
 
 /* Maximum supported data alignment */
-/* #undef ATTRIBUTE_ALIGNED_MAX */
\ No newline at end of file
+#define ATTRIBUTE_ALIGNED_MAX 16
--- a/media/liboggplay/include/oggplay/oggplay.h
+++ b/media/liboggplay/include/oggplay/oggplay.h
@@ -25,152 +25,332 @@
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
- * oggplay.h
+/** @file
  * 
+ * The liboggplay C API.
+ *
+ * @authors
  * Shane Stephens <shane.stephens@annodex.net>
  * Michael Martin
+ * Viktor Gal
  */
-
+ 
 #ifndef __OGGPLAY_H__
 #define __OGGPLAY_H__
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #include <oggplay/oggplay_enums.h>
 #include <oggplay/oggplay_reader.h>
+ 
+/**
+ * This is returned by oggplay_open_with_reader() or oggplay_new_with_reader().
+ */
+typedef struct _OggPlay OggPlay;
 
-typedef struct _OggPlay OggPlay;
+/**
+ * A structure for storing the decoded frames for the various streams in the 
+ * Ogg container.
+ */
 typedef struct _OggPlayCallbackInfo OggPlayCallbackInfo;
-typedef int (OggPlayDataCallback)(OggPlay *player, int num_records,
-                OggPlayCallbackInfo **records, void *user);
+
+/**
+ * This is the signature of a callback which you must provide for OggPlay
+ * to call whenever there's any unpresented decoded frame available.
+ * 
+ * @see oggplay_step_decoding
+ * @param player The OggPlay handle
+ * @param num_records size of the OggPlayCallbackInfo array
+ * @param records array of OggPlayCallbackInfo
+ * @param user A generic pointer for the data the user provided earlier.
+ * @returns 0 to continue, non-zero to instruct OggPlay to stop.
+ *
+ */
+typedef int (OggPlayDataCallback) (OggPlay *player, int num_records, 
+                                   OggPlayCallbackInfo **records, void *user);
 
 #include <oggplay/oggplay_query.h>
 #include <oggplay/oggplay_callback_info.h>
 #include <oggplay/oggplay_tools.h>
 #include <oggplay/oggplay_seek.h>
 
 /**
  * Create an OggPlay handle associated with the given reader.
- * The functions creates a new OggPlay handle and associates with
- * the given OggPlayReader and initialises the buffer.
  * 
+ * This functions creates a new OggPlay handle associated with 
+ * the OggPlayReader and it calls oggplay_initialise to 
+ * read the header packets of the Ogg container. 
  *
  * @param reader an OggPlayReader handle associated with the Ogg content
  * @return A new OggPlay handle
  * @retval NULL in case of error.
  */
 OggPlay *
 oggplay_open_with_reader(OggPlayReader *reader);
 
 /**
  * Create a new OggPlay handle associated with the given reader.
  *
- * \param reader OggPlayReader handle associated with the Ogg content
- * \return A new OggPlay handle
- * \retval NULL in case of error.
+ * @param reader OggPlayReader handle associated with the Ogg content
+ * @return A new OggPlay handle
+ * @retval NULL in case of error.
  */
 OggPlay *
 oggplay_new_with_reader(OggPlayReader *reader);
 
+
+/**
+ * Initialise the OggPlay handle.
+ * 
+ * This function creates an Oggz handle and sets it's OggzIO*
+ * functions to the OggPlayReader's io_* functions. Moreover
+ * it reads the Ogg container's content until it hasn't got 
+ * all the streams' headers.
+ *
+ * @param me OggPlay handle
+ * @param block passed as the second argument to the OggPlayReader's initialise 
+ * function. E.g. in case of OggPlayTCPReader block == 0 sets the socket to non-blocking
+ * mode.
+ * @retval E_OGGPLAY_OK on success
+ * @retval E_OGGPLAY_OGGZ_UNHAPPY something went wrong while calling oggz_io_set_* functions.
+ * @retval E_OGGPLAY_BAD_INPUT got EOF or OGGZ_ERR_HOLE_IN_DATA occured.
+ * @retval E_OGGPLAY_OUT_OF_MEMORY ran out of memory
+ * @retval E_OGGPLAY_BAD_OGGPLAY invalid OggPlay handle. 
+ */
 OggPlayErrorCode
 oggplay_initialise(OggPlay *me, int block);
 
-OggPlayErrorCode
-oggplay_set_source(OggPlay *OS, char *source);
-
+/**
+ * Sets a user defined OggPlayDataCallback function for the OggPlay handle.
+ *
+ * @param me OggPlay handle.
+ * @param callback A custom callback function.
+ * @param user Arbitrary data one wishes to pass to the callback function.
+ * @retval E_OGGPLAY_OK on success 
+ * @retval E_OGGPLAY_BUFFER_MODE We are running in buffer mode, i.e. oggplay_use_buffer 
+ * has been called earlier.
+ * @retval E_OGGPLAY_BAD_OGGPLAY Invalid OggPlay handle.
+ */
 OggPlayErrorCode
 oggplay_set_data_callback(OggPlay *me, OggPlayDataCallback callback, 
-                            void *user);
+                          void *user);
+
 
 OggPlayErrorCode
 oggplay_set_callback_num_frames(OggPlay *me, int stream, int frames);
 
 OggPlayErrorCode
 oggplay_set_callback_period(OggPlay *me, int stream, int milliseconds);
 
 OggPlayErrorCode
 oggplay_set_offset(OggPlay *me, int track, ogg_int64_t offset);
 
+/**
+ * Get the given video track's Y-plane's width and height.
+ * 
+ * @param me OggPlay handle
+ * @param track the track number of the video track
+ * @param y_width the width of the Y-plane
+ * @param y_height the height of the Y-plane
+ * @retval E_OGGPLAY_OK on success.
+ * @retval E_OGGPLAY_BAD_OGGPLAY invalid OggPlay handle
+ * @retval E_OGGPLAY_BAD_TRACK the given track number does not exists
+ * @retval E_OGGPLAY_WRONG_TRACK_TYPE the given track is not an audio track
+ * @retval E_OGGPLAY_UNINITIALISED the OggPlay handle is uninitalised.
+ */
 OggPlayErrorCode
 oggplay_get_video_y_size(OggPlay *me, int track, int *y_width, int *y_height);
 
+/**
+ * Get the given video track's UV-plane's width and height.
+ * 
+ * @param me OggPlay handle
+ * @param track the track number of the video track
+ * @param uv_width the width of the UV-plane
+ * @param uv_height the height of the UV-plane
+ * @retval E_OGGPLAY_OK on success.
+ * @retval E_OGGPLAY_BAD_OGGPLAY invalid OggPlay handle
+ * @retval E_OGGPLAY_BAD_TRACK the given track number does not exists
+ * @retval E_OGGPLAY_WRONG_TRACK_TYPE the given track is not an audio track
+ * @retval E_OGGPLAY_UNINITIALISED the OggPlay handle is uninitalised.
+ */
 OggPlayErrorCode
 oggplay_get_video_uv_size(OggPlay *me, int track, int *uv_width, int *uv_height);
 
+/**
+ * Get the number of channels of the audio track.
+ * 
+ * @param me OggPlay handle
+ * @param track the track number of the audio track
+ * @param channels the number of channels of the given audio track.
+ * @retval E_OGGPLAY_OK on success.
+ * @retval E_OGGPLAY_BAD_OGGPLAY invalid OggPlay handle
+ * @retval E_OGGPLAY_BAD_TRACK the given track number does not exists
+ * @retval E_OGGPLAY_WRONG_TRACK_TYPE the given track is not an audio track
+ * @retval E_OGGPLAY_UNINITIALISED the OggPlay handle is uninitalised.
+ */
 OggPlayErrorCode
 oggplay_get_audio_channels(OggPlay *me, int track, int *channels);
 
+/**
+ * Get the sample rate of the of the audio track
+ * 
+ * @param me OggPlay handle
+ * @param track the track number of the audio track
+ * @param samplerate the sample rate of the audio track.
+ * @retval E_OGGPLAY_OK on success.
+ * @retval E_OGGPLAY_BAD_OGGPLAY invalid OggPlay handle
+ * @retval E_OGGPLAY_BAD_TRACK the given track number does not exists
+ * @retval E_OGGPLAY_WRONG_TRACK_TYPE the given track is not an audio track
+ * @retval E_OGGPLAY_UNINITIALISED the OggPlay handle is uninitalised.
+ */
 OggPlayErrorCode
 oggplay_get_audio_samplerate(OggPlay *me, int track, int *samplerate); 
 
+/**
+ * Get the frame-per-second value the of a given video track.
+ * 
+ * @param me OggPlay handle
+ * @param track the track number of the audio track
+ * @param fps_denom the denumerator of the FPS
+ * @param fps_num the numerator of the FPS
+ * @retval E_OGGPLAY_OK on success.
+ * @retval E_OGGPLAY_BAD_OGGPLAY invalid OggPlay handle
+ * @retval E_OGGPLAY_BAD_TRACK the given track number does not exists
+ * @retval E_OGGPLAY_WRONG_TRACK_TYPE the given track is not an audio track
+ * @retval E_OGGPLAY_UNINITIALISED the OggPlay handle is uninitalised.
+ */
 OggPlayErrorCode
 oggplay_get_video_fps(OggPlay *me, int track, int* fps_denom, int* fps_num);
 
 OggPlayErrorCode
 oggplay_get_video_aspect_ratio(OggPlay *me, int track, int* aspect_denom, int* aspect_num);
 
 OggPlayErrorCode
-oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert);
+oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert, int swap_rgb);
 
 OggPlayErrorCode
 oggplay_get_kate_category(OggPlay *me, int track, const char** category);
 
 OggPlayErrorCode
 oggplay_get_kate_language(OggPlay *me, int track, const char** language);
 
 OggPlayErrorCode
-oggplay_set_kate_tiger_rendering(OggPlay *me, int track, int use_tiger);
+oggplay_set_kate_tiger_rendering(OggPlay *me, int track, int use_tiger, int swap_rgb, int default_width, int default_height);
 
 OggPlayErrorCode
 oggplay_overlay_kate_track_on_video(OggPlay *me, int kate_track, int video_track);
 
 OggPlayErrorCode
 oggplay_start_decoding(OggPlay *me);
 
+/**
+ * Decode the streams in the Ogg container until we find data that hasn't
+ * been presented, yet.
+ * 
+ * Whenever there is data that hasn't been presented the OggPlayDataCallback
+ * function will be called.
+ * 
+ * @param me OggPlay handle
+ * @retval E_OGGPLAY_OK reached the end of the stream or shutdown detected
+ * @retval E_OGGPLAY_CONTINUE successfully decoded the frames.
+ * @retval E_OGGPLAY_BAD_INPUT OGGZ_ERR_HOLE_IN_DATA occured while decoding
+ * @retval E_OGGPLAY_UNINITIALISED the OggPlayDataCallback of the OggPlay handle is not set.
+ * @retval E_OGGPLAY_USER_INTERRUPT user interrupted the decoding
+ * @retval E_OGGPLAY_OUT_OF_MEMORY ran out of memory while decoding
+ */
 OggPlayErrorCode
 oggplay_step_decoding(OggPlay *me);
 
+/**
+ * Use the built-in OggPlayBuffer for buffering the decoded frames
+ * 
+ * The built-in OggPlayBuffer implements a simple lock-free FIFO for 
+ * storing the decoded frames.
+ * 
+ * It tries to set the OggPlay handle's OggPlayDataCallback function to it's
+ * own implementation (oggplay_buffer_callback). Thus it will fail if
+ * a user already set OggPlayDataCallback of the OggPlay handle
+ * with oggplay_set_data_callback.
+ * 
+ * One can retrive the next record in the queue by 
+ * calling oggplay_buffer_retrieve_next.
+ * 
+ * @param player the OggPlay handle
+ * @param size The size of the buffer, i.e. the number of records it can store
+ * @retval E_OGGPLAY_OK on succsess
+ * @retval E_OGGPLAY_BAD_OGGPLAY The supplied OggPlay handle is not valid
+ * @retval E_OGGPLAY_CALLBACK_MODE The given OggPlay handle's OggPlayDataCallback 
+ * function is already set, i.e. running in callback-mode.
+ * @retval E_OGGPLAY_OUT_OF_MEMORY Ran out of memory while trying to allocate memory for the buffer.
+ */
 OggPlayErrorCode
 oggplay_use_buffer(OggPlay *player, int size);
 
+/**
+ * Retrive the next element in the buffer.
+ *
+ * @param player OggPlay handle
+ * @return array of OggPlayCallbackInfo - one per track.
+ * @retval NULL if there was no available.
+ */
 OggPlayCallbackInfo **
 oggplay_buffer_retrieve_next(OggPlay *player);
 
+/**
+ * Release the given buffer item.
+ *
+ * After retrieving and processing one buffer item, in order
+ * to remove the given item from the queue and release the 
+ * memory allocated by the buffer item one needs to call this 
+ * function.
+ * 
+ * @param player OggPlay handle
+ * @param track_info OggPlayCallbackInfo array to release.
+ * @retval E_OGGPLAY_OK on success.
+ * @retval E_OGGPLAY_BAD_OGGPLAY invalid OggPlay handle.
+ */
 OggPlayErrorCode
 oggplay_buffer_release(OggPlay *player, OggPlayCallbackInfo **track_info);
 
 void
 oggplay_prepare_for_close(OggPlay *me);
 
 /**
- * @brief Destroys the OggPlay handle along with the associated OggPlayReader
+ * Destroys the OggPlay handle along with the associated OggPlayReader
  * and clears out the buffer and shuts down the callback function. 
  *
  * @param player an OggPlay handle
  * @retval E_OGGPLAY_OK on success 
  */
 OggPlayErrorCode
 oggplay_close(OggPlay *player);
 
 int
 oggplay_get_available(OggPlay *player);
 
+/**
+ * Get the duration of the Ogg content.
+ * 
+ * @param player OggPlay handle.
+ * @return The duration of the content in milliseconds.
+ * @retval E_OGGPLAY_BAD_OGGPLAY invalid OggPlay handle
+ */
 ogg_int64_t
 oggplay_get_duration(OggPlay * player);
 
 int
 oggplay_media_finished_retrieving(OggPlay * player);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif
+#endif /* __OGGPLAY_H__ */
--- a/media/liboggplay/include/oggplay/oggplay_callback_info.h
+++ b/media/liboggplay/include/oggplay/oggplay_callback_info.h
@@ -25,75 +25,149 @@
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
+/** @file
  * oggplay_callback_info.h
  * 
+ * @authors
  * Shane Stephens <shane.stephens@annodex.net>
+ * Michael Martin
+ * Viktor Gal
  */
 
 #ifndef __OGGPLAY_CALLBACK_INFO__
 #define __OGGPLAY_CALLBACK_INFO__
 
+/** structure for storing a YUV video frame */
 typedef struct {
-  unsigned char   * y;
-  unsigned char   * u;
-  unsigned char   * v;
+  unsigned char   * y; /**< Y-plane */
+  unsigned char   * u; /**< U-plane*/
+  unsigned char   * v; /**< V-plane */
 } OggPlayVideoData;
 
+/** structure for storing a video frame in RGB fromat */
 typedef struct {
-  unsigned char   * rgba; /* may be NULL if no alpha */
-  unsigned char   * rgb; /* may be NULL if alpha */
-  size_t          width; /* in pixels */
-  size_t          height; /* in pixels */
-  size_t          stride; /* in bytes */
+  unsigned char   * rgba; /**< may be NULL if no alpha */
+  unsigned char   * rgb;  /**< may be NULL if alpha */
+  size_t          width;  /**< width in pixels */
+  size_t          height; /**< height in pixels */
+  size_t          stride; /**< stride */
 } OggPlayOverlayData;
 
+/** Type for representing audio data */
 typedef void * OggPlayAudioData;
 
+/** Type for representing text data */
 typedef char OggPlayTextData;
 
 struct _OggPlayDataHeader;
+/** Header for the various data formats */
 typedef struct _OggPlayDataHeader OggPlayDataHeader;
 
+/**
+ * Get the data type of the given OggPlayCallbackInfo.
+ * 
+ * @param info 
+ * @returns The data type of the given OggPlayCallbackInfo
+ * @see OggPlayDataType
+ */
 OggPlayDataType
 oggplay_callback_info_get_type(OggPlayCallbackInfo *info);
+
 int
 oggplay_callback_info_get_available(OggPlayCallbackInfo *info);
+
+
 int
 oggplay_callback_info_get_required(OggPlayCallbackInfo *info);
+
+/**
+ * Get the array of records stored in the OggPlayCallbackInfo
+ * 
+ * @param info
+ * @returns array of records 
+ * @retval NULL if the supplied OggPlayCallbackInfo is a NULL pointer
+ */
 OggPlayDataHeader **
 oggplay_callback_info_get_headers(OggPlayCallbackInfo *info);
 
+/**
+ * Get the size of the given record.
+ * 
+ * @param header
+ * @returns The number of samples in the record.
+ */
 ogg_int64_t
 oggplay_callback_info_get_record_size(OggPlayDataHeader *header);
 
+/**
+ * Extract the video frame from the supplied record.
+ *
+ * @param header 
+ * @returns the video frame
+ * @retval NULL if the supplied OggPlayCallbackInfo is a NULL pointer
+ */
 OggPlayVideoData *
 oggplay_callback_info_get_video_data(OggPlayDataHeader *header);
 
+/**
+ * Extract the overlay data from the supplied record.
+ * 
+ * @param header
+ * @returns OggPlayOverlayData
+ * @retval NULL if the supplied OggPlayCallbackInfo is a NULL pointer
+ */
 OggPlayOverlayData *
 oggplay_callback_info_get_overlay_data(OggPlayDataHeader *header);
 
+/**
+ * Extract the audio data from the supplied record.
+ *
+ * @param header
+ * @returns OggPlayAudioData.
+ * @retval NULL if the supplied OggPlayCallbackInfo is a NULL pointer
+ */
 OggPlayAudioData *
 oggplay_callback_info_get_audio_data(OggPlayDataHeader *header);
 
+/**
+ * Extract the text data from the supplied record.
+ *
+ * @param header
+ * @returns OggPlayTextData 
+ * @retval NULL if the supplied OggPlayCallbackInfo is a NULL pointer
+ */
 OggPlayTextData *
 oggplay_callback_info_get_text_data(OggPlayDataHeader *header);
 
+/**
+ * Get the state of the stream.
+ *
+ * @param info
+ * @returns State of the given stream.
+ * @see OggPlayStreamInfo
+ */
 OggPlayStreamInfo
 oggplay_callback_info_get_stream_info(OggPlayCallbackInfo *info);
 
+
 void
 oggplay_callback_info_lock_item(OggPlayDataHeader *header);
 
 void
 oggplay_callback_info_unlock_item(OggPlayDataHeader *header);
 
+/**
+ * Get the presentation time of the given record.
+ *  
+ * @param header
+ * @returns presentation time of the given frame in milliseconds.
+ */
 long
 oggplay_callback_info_get_presentation_time(OggPlayDataHeader *header);
 
 #endif
--- a/media/liboggplay/include/oggplay/oggplay_enums.h
+++ b/media/liboggplay/include/oggplay/oggplay_enums.h
@@ -25,68 +25,79 @@
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
- * oggplay_enums.h
+/** @file
+ * General constants used by liboggplay
  * 
+ * @authors 
  * Shane Stephens <shane.stephens@annodex.net>
  * Michael Martin
+ * Viktor Gal
  */
-
+ 
 #ifndef __OGGPLAY_ENUMS_H__
 #define __OGGPLAY_ENUMS_H__
 
+/**
+ * Definitions of error return values.
+ */
 typedef enum OggPlayErrorCode {
-  E_OGGPLAY_CONTINUE          = 1,
-  E_OGGPLAY_OK                = 0,
-  E_OGGPLAY_BAD_OGGPLAY       = -1,
-  E_OGGPLAY_BAD_READER        = -2,
-  E_OGGPLAY_BAD_INPUT         = -3,
-  E_OGGPLAY_NO_SUCH_CHUNK     = -4,
-  E_OGGPLAY_BAD_TRACK         = -5,
-  E_OGGPLAY_TRACK_IS_SKELETON = -6,
-  E_OGGPLAY_OGGZ_UNHAPPY      = -7,
-  E_OGGPLAY_END_OF_FILE       = -8,
-  E_OGGPLAY_TRACK_IS_OVER     = -9,
-  E_OGGPLAY_BAD_CALLBACK_INFO = -10,
-  E_OGGPLAY_WRONG_TRACK_TYPE  = -11,
-  E_OGGPLAY_UNINITIALISED     = -12,
-  E_OGGPLAY_CALLBACK_MODE     = -13,
-  E_OGGPLAY_BUFFER_MODE       = -14,
-  E_OGGPLAY_USER_INTERRUPT    = -15,
-  E_OGGPLAY_SOCKET_ERROR      = -16,
-  E_OGGPLAY_TIMEOUT           = -17,
-  E_OGGPLAY_CANT_SEEK         = -18,
-  E_OGGPLAY_NO_KATE_SUPPORT   = -19,
-  E_OGGPLAY_NO_TIGER_SUPPORT  = -20,
-  E_OGGPLAY_OUT_OF_MEMORY     = -21,
-  E_OGGPLAY_TYPE_OVERFLOW     = -22,  /**< Integer overflow detected */
-  
-  E_OGGPLAY_TRACK_IS_UNKNOWN  = -23,  /**< The selected track's content type is UNKNOWN */
-  E_OGGPLAY_NOTCHICKENPAYBACK = -777
+  E_OGGPLAY_CONTINUE            = 1,
+  E_OGGPLAY_OK                  = 0,    /**< No error */
+  E_OGGPLAY_BAD_OGGPLAY         = -1,   /**< supplied oggplay is not a valid OggPlay */
+  E_OGGPLAY_BAD_READER          = -2,   /**< OggPlayReader is invalid */
+  E_OGGPLAY_BAD_INPUT           = -3,   /**< Error in the input */
+  E_OGGPLAY_NO_SUCH_CHUNK       = -4,
+  E_OGGPLAY_BAD_TRACK           = -5,   /**< The requested track number does not exists */
+  E_OGGPLAY_TRACK_IS_SKELETON   = -6,   /**< Trying to activate a Skeleton track */
+  E_OGGPLAY_OGGZ_UNHAPPY        = -7,   /**< OGGZ error occured */
+  E_OGGPLAY_END_OF_FILE         = -8,   /**< End of file */
+  E_OGGPLAY_TRACK_IS_OVER       = -9,   /**< A given track has ended */
+  E_OGGPLAY_BAD_CALLBACK_INFO   = -10,  /**< Invalid OggPlayCallbackInfo */
+  E_OGGPLAY_WRONG_TRACK_TYPE    = -11,  /**< */
+  E_OGGPLAY_UNINITIALISED       = -12,  /**< The OggPlay handle is not initialised */
+  E_OGGPLAY_CALLBACK_MODE       = -13,  /**< OggPlay is used in callback mode */
+  E_OGGPLAY_BUFFER_MODE         = -14,  /**< OggPlay is used in buffer mode */
+  E_OGGPLAY_USER_INTERRUPT      = -15,  /**< User interrupt received */
+  E_OGGPLAY_SOCKET_ERROR        = -16,  /**< Error while creating socket */
+  E_OGGPLAY_TIMEOUT             = -17,  /**< TCP connection timeouted */
+  E_OGGPLAY_CANT_SEEK           = -18,  /**< Could not performed the requested seek */
+  E_OGGPLAY_NO_KATE_SUPPORT     = -19,  /**< LibKate is not supported */
+  E_OGGPLAY_NO_TIGER_SUPPORT    = -20,  /**< LibTiger is not supported */
+  E_OGGPLAY_OUT_OF_MEMORY       = -21,  /**< Out of memory */
+  E_OGGPLAY_TYPE_OVERFLOW       = -22,  /**< Integer overflow detected */
+  E_OGGPLAY_TRACK_IS_UNKNOWN    = -23,  /**< The selected track's content type is UNKNOWN */
+  E_OGGPLAY_TRACK_UNINITIALISED = -24,  /**< Track is not initialised, i.e. bad headers or haven't seen them */
+  E_OGGPLAY_NOTCHICKENPAYBACK   = -777
 } OggPlayErrorCode;
 
+/**
+ * Definitions of the various record types
+ */
 typedef enum OggPlayDataType {
-  OGGPLAY_INACTIVE      = -1,
-  OGGPLAY_YUV_VIDEO     = 0,
-  OGGPLAY_RGBA_VIDEO    = 1,
-  OGGPLAY_SHORTS_AUDIO  = 1000,
-  OGGPLAY_FLOATS_AUDIO  = 1001,
-  OGGPLAY_CMML          = 2000,
-  OGGPLAY_KATE          = 3000,
-  OGGPLAY_TYPE_UNKNOWN  = 9000 /* higher to be able to add more types without changing value */
+  OGGPLAY_INACTIVE      = -1,   /**< record is inactive */
+  OGGPLAY_YUV_VIDEO     = 0,    /**< record is a YUV format video */
+  OGGPLAY_RGBA_VIDEO    = 1,    /**< record is a video in RGB format */
+  OGGPLAY_SHORTS_AUDIO  = 1000, /**< audio record in short format */
+  OGGPLAY_FLOATS_AUDIO  = 1001, /**< audio record in float format */
+  OGGPLAY_CMML          = 2000, /**< CMML record */
+  OGGPLAY_KATE          = 3000, /**< KATE record */
+  OGGPLAY_TYPE_UNKNOWN  = 9000  /**< content type of the record is unknown */
 } OggPlayDataType;
 
+/**
+ * Definitions of the various states of a stream.
+ */
 typedef enum OggPlayStreamInfo {
-  OGGPLAY_STREAM_UNINITIALISED = 0,
-  OGGPLAY_STREAM_FIRST_DATA = 1,
-  OGGPLAY_STREAM_INITIALISED = 2,
-  OGGPLAY_STREAM_LAST_DATA = 3,
-  OGGPLAY_STREAM_JUST_SEEKED = 4
+  OGGPLAY_STREAM_UNINITIALISED = 0, /**< Stream is not initialised */
+  OGGPLAY_STREAM_FIRST_DATA = 1,    /**< Stream received it's first data frame */
+  OGGPLAY_STREAM_INITIALISED = 2,   /**< Stream is initialised */
+  OGGPLAY_STREAM_LAST_DATA = 3,     /**< Stream received it's last data frame */
+  OGGPLAY_STREAM_JUST_SEEKED = 4    /**< We've just seeked in the stream */
 } OggPlayStreamInfo;
 
 #endif
--- a/media/liboggplay/include/oggplay/oggplay_query.h
+++ b/media/liboggplay/include/oggplay/oggplay_query.h
@@ -25,35 +25,92 @@
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
+/** @file
  * oggplay_query.h
  * 
+ * @authors
  * Shane Stephens <shane.stephens@annodex.net>
+ * Viktor Gal
  */
-
+ 
 #ifndef __OGGPLAY_QUERY_H__
 #define __OGGPLAY_QUERY_H__
 
 #include <oggz/oggz.h>
 
+/**
+ * Get the number of tracks in the Ogg container.
+ *
+ * @param me OggPlay handle
+ * @retval "> 0" number of tracks
+ * @retval E_OGGPLAY_BAD_OGGPLAY the supplied OggPlay 
+ * @retval E_OGGPLAY_BAD_READER 
+ * @retval E_OGGPLAY_UNINITIALISED the is not initialised.
+ */
 int
 oggplay_get_num_tracks (OggPlay * me);
 
+/**
+ * Retrieve the type of a track.
+ * 
+ * @param me OggPlay handle
+ * @param track_num the desired track's number
+ * @retval "> 0" the track's type (see OggzStreamContent)
+ * @retval "< 0" error occured
+ */
 OggzStreamContent
 oggplay_get_track_type (OggPlay * me, int track_num);
 
+/**
+ * Get a track's type name.
+ * 
+ * @param me OggPlay handle
+ * @param track_num the desired track's number
+ * @retval typa name of the track
+ * @retval NULL in case of error.
+ */
 const char *
 oggplay_get_track_typename (OggPlay * me, int track_num);
 
+/**
+ * Set a track active.
+ *
+ * @param me OggPlay handle
+ * @param track_num the desired track's number for activation
+ * @retval E_OGGPLAY_OK on success
+ * @retval E_OGGPLAY_BAD_OGGPLAY the supplied OggPlay is invalid
+ * @retval E_OGGPLAY_BAD_READER the OggPlayReader associated with the Ogg 
+ * container is invalid
+ * @retval E_OGGPLAY_UNINITIALISED the tracks are not initialised
+ * @retval E_OGGPLAY_BAD_TRACK invalid track number
+ * @retval E_OGGPLAY_TRACK_IS_SKELETON the chosen track is a Skeleton track
+ * @retval E_OGGPLAY_TRACK_IS_UNKNOWN the chosen track's content type is unknown
+ * @retval E_OGGPLAY_TRACK_UNINITIALISED the chosen track was not initialised
+ * @retval E_OGGPLAY_TRACK_IS_OVER the track is over.
+ */
 OggPlayErrorCode
 oggplay_set_track_active(OggPlay *me, int track_num);
 
+/**
+ * Inactivate a given track.
+ *
+ * @param me OggPlay handle
+ * @param track_num the desired track's number for inactivation
+ * @retval E_OGGPLAY_OK on success
+ * @retval E_OGGPLAY_BAD_OGGPLAY the supplied OggPlay is invalid
+ * @retval E_OGGPLAY_BAD_READER the OggPlayReader associated with the Ogg 
+ * container is invalid
+ * @retval E_OGGPLAY_UNINITIALISED the tracks are not initialised
+ * @retval E_OGGPLAY_BAD_TRACK invalid track number
+ * @retval E_OGGPLAY_TRACK_IS_SKELETON the chosen track is a Skeleton track
+ * @retval E_OGGPLAY_TRACK_IS_UNKNOWN the chosen track's content type is unknown
+ */
 OggPlayErrorCode
 oggplay_set_track_inactive(OggPlay *me, int track_num);
 
 #endif
--- a/media/liboggplay/include/oggplay/oggplay_reader.h
+++ b/media/liboggplay/include/oggplay/oggplay_reader.h
@@ -25,64 +25,66 @@
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
+/** @file
  * oggplay_reader.h
  * 
+ * @authors
  * Shane Stephens <shane.stephens@annodex.net>
  * Michael Martin
  */
 
 #ifndef __OGGPLAY_READER_H__
 #define __OGGPLAY_READER_H__
 
 #include <stdlib.h>
 #include <oggz/oggz.h>
 #include <ogg/ogg.h>
 
 struct _OggPlayReader;
 
+/** */
 typedef struct _OggPlayReader {
-  OggPlayErrorCode  (*initialise)(struct _OggPlayReader * me, int block);
-  OggPlayErrorCode  (*destroy)(struct _OggPlayReader * me);
-  OggPlayErrorCode  (*seek)(struct _OggPlayReader *me, OGGZ *oggz, 
-                                                    ogg_int64_t milliseconds);
-  int               (*available)(struct _OggPlayReader *me,
-                                              ogg_int64_t current_bytes,
-                                              ogg_int64_t current_time);
-  ogg_int64_t       (*duration)(struct _OggPlayReader *me);
+  OggPlayErrorCode  (*initialise) (struct _OggPlayReader * me, int block);
+  OggPlayErrorCode  (*destroy)    (struct _OggPlayReader * me);
+  OggPlayErrorCode  (*seek)       (struct _OggPlayReader *me, OGGZ *oggz, 
+                                   ogg_int64_t milliseconds);
+  int               (*available)  (struct _OggPlayReader *me,
+                                   ogg_int64_t current_bytes,
+                                   ogg_int64_t current_time);
+  ogg_int64_t       (*duration)   (struct _OggPlayReader *me);
   int               (*finished_retrieving)(struct _OggPlayReader *me);
 
   /* low-level io functions for oggz */
   size_t            (*io_read)(void *user_handle, void *buf, size_t n);
   int               (*io_seek)(void *user_handle, long offset, int whence);
   long              (*io_tell)(void *user_handle);
 } OggPlayReader;
 
 /**
  * Create and initialise an OggPlayReader for a given Ogg file.
  * 
  * @param filename The file to open
  * @return A new OggPlayReader handle
- * @retval NULL on error.
+ * @retval NULL if error occured.
  */
 OggPlayReader *
-oggplay_file_reader_new(char *filename);
+oggplay_file_reader_new(const char *filename);
 
 /**
  * Create and initialise an OggPlayReader for an Ogg content at a given URI. 
  *
  * @param uri The URI to the Ogg file.
  * @param proxy Proxy 
  * @param proxy_port Proxy port.
  * @return A new OggPlayReader handle
  * @retval NULL on error.
  */
 OggPlayReader *
-oggplay_tcp_reader_new(char *uri, char *proxy, int proxy_port);
+oggplay_tcp_reader_new(const char *uri, const char *proxy, int proxy_port);
 
 #endif
--- a/media/liboggplay/include/oggplay/oggplay_seek.h
+++ b/media/liboggplay/include/oggplay/oggplay_seek.h
@@ -25,25 +25,36 @@
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
- * oggplay_enums.h
+/** @file
+ * oggplay_seek.h
  * 
+ * @authors
  * Shane Stephens <shane.stephens@annodex.net>
  */
 
 #ifndef __OGGPLAY_SEEK_H__
 #define __OGGPLAY_SEEK_H__
 
+/**
+ * Seeks to a requested position.
+ * 
+ * @param me OggPlay handle associated with the stream
+ * @param milliseconds
+ * @retval E_OGGPLAY_OK on success
+ * @retval E_OGGPLAY_BAD_OGGPLAY the supplied OggPlay handle was invalid
+ * @retval E_OGGPLAY_CANT_SEEK error occured while trying to seek
+ * @retval E_OGGPLAY_OUT_OF_MEMORY ran out of memory while trying to allocate the new buffer and trash.
+ */
 OggPlayErrorCode
 oggplay_seek(OggPlay *me, ogg_int64_t milliseconds);
 
 /**
  * Seeks to key frame before |milliseconds|.
  */
 OggPlayErrorCode
 oggplay_seek_to_keyframe(OggPlay *me,
--- a/media/liboggplay/include/oggplay/oggplay_tools.h
+++ b/media/liboggplay/include/oggplay/oggplay_tools.h
@@ -25,19 +25,20 @@
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
+/** @file
  * oggplay_tools.h
  * 
+ * @authors
  * Shane Stephens <shane.stephens@annodex.net>
  * Michael Martin
  */
 
 #ifndef __OGGPLAY_TOOLS_H__
 #define __OGGPLAY_TOOLS_H__
 
 #include <ogg/ogg.h>
@@ -48,34 +49,35 @@ extern "C" {
 
 #ifdef WIN32
 #include <time.h>
 #else
 #include <sys/time.h>
 #include <time.h>
 #endif
 
-/* structure holds pointers to y, u, v channels */
+/** structure holds pointers to y, u, v channels */
 typedef struct _OggPlayYUVChannels {
-    unsigned char * ptry;
-    unsigned char * ptru;
-    unsigned char * ptrv;
-    int             y_width;
-    int             y_height;
-    int             uv_width;
-    int             uv_height;
+    unsigned char * ptry;       /**< Y channel */
+    unsigned char * ptru;       /**< U channel */
+    unsigned char * ptrv;       /**< V channel*/
+    int             y_width;    /**< the width of the Y plane */
+    int             y_height;   /**< the height of the Y plane */
+    int             uv_width;   /**< the width of the U/V plane */
+    int             uv_height;  /**< the height of the U/V plane*/
 } OggPlayYUVChannels;
 
-/* structure holds pointers to y, u, v channels */
+/** structure holds pointers to RGB packets */
 typedef struct _OggPlayRGBChannels {
-    unsigned char * ptro;
-    int             rgb_width;
-    int             rgb_height;
+    unsigned char * ptro;         /**< the RGB stream in the requested packaging format */
+    int             rgb_width;    /**< width of the RGB frame */
+    int             rgb_height;   /**< height of the RGB frame */
 } OggPlayRGBChannels;
 
+
 void 
 oggplay_yuv2rgba(const OggPlayYUVChannels *yuv, OggPlayRGBChannels * rgb);
 
 void 
 oggplay_yuv2bgra(const OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb);
 
 void 
 oggplay_yuv2argb(const OggPlayYUVChannels *yuv, OggPlayRGBChannels * rgb);
--- a/media/liboggplay/oggplay_os2.patch
+++ b/media/liboggplay/oggplay_os2.patch
@@ -1,34 +1,34 @@
 diff --git a/media/liboggplay/src/liboggplay/oggplay_private.h b/media/liboggplay/src/liboggplay/oggplay_private.h
 --- a/media/liboggplay/src/liboggplay/oggplay_private.h
 +++ b/media/liboggplay/src/liboggplay/oggplay_private.h
-@@ -62,16 +62,22 @@
- 
- #ifdef WIN32
+@@ -64,16 +64,22 @@
  
  #ifdef HAVE_WINSOCK2
  #include <winsock2.h>
  #else
  #include <winsock.h>
  #endif
-+#endif
-+
+ #endif
+ 
 +#ifdef OS2
 +#define INCL_DOSSEMAPHORES
 +#define INCL_DOSPROCESS
 +#include <os2.h>
- #endif
- 
++#endif
++
  // for Win32 <windows.h> has to be included last
  #include "std_semaphore.h"
  
  /**
   *
   * has_been_presented: 0 until the data has been added as a "required" element,
+  *                     then 1.
+  */
 diff --git a/media/liboggplay/src/liboggplay/oggplay_tools.c b/media/liboggplay/src/liboggplay/oggplay_tools.c
 --- a/media/liboggplay/src/liboggplay/oggplay_tools.c
 +++ b/media/liboggplay/src/liboggplay/oggplay_tools.c
 @@ -53,15 +53,17 @@ oggplay_sys_time_in_ms(void) {
    return (ogg_int64_t)tv.tv_sec * 1000 + (ogg_int64_t)tv.tv_usec / 1000;
  #endif
  }
  
@@ -273,17 +273,17 @@ new file mode 100644
 +int sem_destroy(sem_t *sem);
 +
 +#endif
 +/*****************************************************************************/
 +
 diff --git a/media/liboggplay/src/liboggplay/std_semaphore.h b/media/liboggplay/src/liboggplay/std_semaphore.h
 --- a/media/liboggplay/src/liboggplay/std_semaphore.h
 +++ b/media/liboggplay/src/liboggplay/std_semaphore.h
-@@ -83,16 +83,23 @@ typedef sem_t           semaphore;
+@@ -87,16 +87,23 @@
  typedef sem_t           semaphore;
  #elif defined(WIN32)
  #include <windows.h>
  #define SEM_CREATE(p,s) (!(p = CreateSemaphore(NULL, (long)(s), (long)(s), NULL)))
  #define SEM_SIGNAL(p)   (!ReleaseSemaphore(p, 1, NULL))
  #define SEM_WAIT(p)     WaitForSingleObject(p, INFINITE)
  #define SEM_CLOSE(p)    (!CloseHandle(p))
  typedef HANDLE          semaphore;
--- a/media/liboggplay/seek_to_key_frame.patch
+++ b/media/liboggplay/seek_to_key_frame.patch
@@ -1,17 +1,17 @@
 diff --git a/media/liboggplay/include/oggplay/oggplay_seek.h b/media/liboggplay/include/oggplay/oggplay_seek.h
 --- a/media/liboggplay/include/oggplay/oggplay_seek.h
 +++ b/media/liboggplay/include/oggplay/oggplay_seek.h
-@@ -37,9 +37,20 @@
+@@ -48,9 +48,20 @@
+  * @retval E_OGGPLAY_OK on success
+  * @retval E_OGGPLAY_BAD_OGGPLAY the supplied OggPlay handle was invalid
+  * @retval E_OGGPLAY_CANT_SEEK error occured while trying to seek
+  * @retval E_OGGPLAY_OUT_OF_MEMORY ran out of memory while trying to allocate the new buffer and trash.
   */
- 
- #ifndef __OGGPLAY_SEEK_H__
- #define __OGGPLAY_SEEK_H__
- 
  OggPlayErrorCode
  oggplay_seek(OggPlay *me, ogg_int64_t milliseconds);
  
 +/**
 + * Seeks to key frame before |milliseconds|.
 + */
 +OggPlayErrorCode
 +oggplay_seek_to_keyframe(OggPlay *me,
@@ -20,26 +20,25 @@ diff --git a/media/liboggplay/include/og
 +                         ogg_int64_t milliseconds,
 +                         ogg_int64_t offset_begin,
 +                         ogg_int64_t offset_end);
 +
  #endif
 diff --git a/media/liboggplay/src/liboggplay/oggplay_seek.c b/media/liboggplay/src/liboggplay/oggplay_seek.c
 --- a/media/liboggplay/src/liboggplay/oggplay_seek.c
 +++ b/media/liboggplay/src/liboggplay/oggplay_seek.c
-@@ -73,16 +73,67 @@ oggplay_seek(OggPlay *me, ogg_int64_t mi
+@@ -71,16 +71,64 @@ oggplay_seek(OggPlay *me, ogg_int64_t mi
+       return E_OGGPLAY_CANT_SEEK;
+     }
    }
  
-   oggplay_seek_cleanup(me, milliseconds);
- 
-   return E_OGGPLAY_OK;
- 
+   return oggplay_seek_cleanup(me, milliseconds);
  }
  
-+OggPlayErrorCode
+ OggPlayErrorCode
 +oggplay_seek_to_keyframe(OggPlay *me,
 +                         int* tracks,
 +                         int num_tracks,
 +                         ogg_int64_t milliseconds,
 +                         ogg_int64_t offset_begin,
 +                         ogg_int64_t offset_end)
 +{
 +  long *serial_nos;
@@ -74,22 +73,20 @@ diff --git a/media/liboggplay/src/libogg
 +                                offset_begin,
 +                                offset_end);
 +  oggplay_free(serial_nos);
 +
 +  if (time == -1) {
 +    return E_OGGPLAY_CANT_SEEK;
 +  }
 +
-+  oggplay_seek_cleanup(me, time);
-+
-+  return E_OGGPLAY_OK;
-+
++  return oggplay_seek_cleanup(me, time);
 +}
 +
- void
++OggPlayErrorCode
  oggplay_seek_cleanup(OggPlay* me, ogg_int64_t milliseconds)
  {
  
    OggPlaySeekTrash    * trash;
    OggPlaySeekTrash   ** p;
    OggPlayDataHeader  ** end_of_list_p;
    int                   i;
+ 
--- a/media/liboggplay/src/liboggplay/config.h
+++ b/media/liboggplay/src/liboggplay/config.h
@@ -12,29 +12,29 @@
 
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
 
 /* Define if have libfishsound */
 #define HAVE_FISHSOUND /**/
 
 /* Define if we have GLUT. */
-#define HAVE_GLUT /**/
+/* #undef HAVE_GLUT */
 
 /* Define if have Imlib2 */
 /* #undef HAVE_IMLIB2 */
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #define HAVE_INTTYPES_H 1
 
 /* Define if have libkate */
 /* #undef HAVE_KATE */
 
 /* Define if have libsndfile */
-#define HAVE_LIBSNDFILE1 /**/
+/* #undef HAVE_LIBSNDFILE1 */
 
 /* Define to 1 if you have the <memory.h> header file. */
 #define HAVE_MEMORY_H 1
 
 /* Define if have liboggz */
 #define HAVE_OGGZ /**/
 
 /* Define to 1 if you have the <stdint.h> header file. */
@@ -85,17 +85,17 @@
 
 /* Define to the version of this package. */
 #define PACKAGE_VERSION ""
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Version number of package */
-#define VERSION "0.0.1"
+#define VERSION "0.2.0"
 
 /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
    significant byte first (like Motorola and SPARC, unlike Intel). */
 #if defined AC_APPLE_UNIVERSAL_BUILD
 # if defined __BIG_ENDIAN__
 #  define WORDS_BIGENDIAN 1
 # endif
 #else
--- a/media/liboggplay/src/liboggplay/cpu.c
+++ b/media/liboggplay/src/liboggplay/cpu.c
@@ -1,270 +1,284 @@
-/********************************************************************
- *                                                                  *
- * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
- *                                                                  *
- * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2008                *
- * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
- *                                                                  *
- ********************************************************************
-
- CPU capability detection for x86 processors.
-  Originally written by Rudolf Marek.
-
- function:
-  last mod: $Id$
-
- ********************************************************************/
-
-#include "cpu.h"
-
-/* for detecting AltiVec support */
-# if (defined(__ppc__) || defined(__ppc64__))
-#   if defined(__APPLE__) || defined(__MACOSX__)
-#include <sys/sysctl.h>
-#   else
-#include <signal.h>
-#include <setjmp.h>
-#   endif
-# endif
-
-# if (defined(__ppc__) || defined(__ppc64__)) && !(defined(__APPLE__) || defined(__MACOSX__))
-static jmp_buf jmpbuf;
-
-static void illegal_instruction(int sig)
-{
-        longjmp(jmpbuf, 1);
-}
-# endif
-
-
-# if !defined(_MSC_VER)
-#  if defined(__amd64__)||defined(__x86_64__)
-/*On x86-64, gcc seems to be able to figure out how to save %rbx for us when
-   compiling with -fPIC.*/
-#   define cpuid(_op,_eax,_ebx,_ecx,_edx) \
-  __asm__ __volatile__( \
-   "cpuid\n\t" \
-   :[eax]"=a"(_eax),[ebx]"=b"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \
-   :"a"(_op) \
-   :"cc" \
-  )
-#  else
-/*On x86-32, not so much.*/
-#   define cpuid(_op,_eax,_ebx,_ecx,_edx) \
-  __asm__ __volatile__( \
-   "xchgl %%ebx,%[ebx]\n\t" \
-   "cpuid\n\t" \
-   "xchgl %%ebx,%[ebx]\n\t" \
-   :[eax]"=a"(_eax),[ebx]"=r"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \
-   :"a"(_op) \
-   :"cc" \
-  )
-#  endif
-# else
-/*Why does MSVC need this complicated rigamarole?
-  At this point I honestly do not care.*/
-
-/*Visual C cpuid helper function.
-  For VS2005 we could as well use the _cpuid builtin, but that wouldn't work
-   for VS2003 users, so we do it in inline assembler.*/
-static void oc_cpuid_helper(ogg_uint32_t _cpu_info[4],ogg_uint32_t _op){
-  _asm {
-    mov eax,[_op]
-    mov esi,_cpu_info
-    cpuid
-    mov [esi+0],eax
-    mov [esi+4],ebx
-    mov [esi+8],ecx
-    mov [esi+12],edx
-  }
-}
-
-#  define cpuid(_op,_eax,_ebx,_ecx,_edx) \
-  do{ \
-    ogg_uint32_t cpu_info[4]; \
-    oc_cpuid_helper(cpu_info,_op); \
-    (_eax)=cpu_info[0]; \
-    (_ebx)=cpu_info[1]; \
-    (_ecx)=cpu_info[2]; \
-    (_edx)=cpu_info[3]; \
-  }while(0)
-
-static void oc_detect_cpuid_helper(ogg_uint32_t *_eax,ogg_uint32_t *_ebx){
-  _asm{
-    pushfd
-    pushfd
-    pop eax
-    mov ebx,eax
-    xor eax,200000h
-    push eax
-    popfd
-    pushfd
-    pop eax
-    popfd
-    mov ecx,_eax
-    mov [ecx],eax
-    mov ecx,_ebx
-    mov [ecx],ebx
-  }
-}
-# endif
-
-static ogg_uint32_t oc_parse_intel_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){
-  ogg_uint32_t flags;
-  /*If there isn't even MMX, give up.*/
-  if(!(_edx&0x00800000))return 0;
-  flags=OC_CPU_X86_MMX;
-  if(_edx&0x02000000)flags|=OC_CPU_X86_MMXEXT|OC_CPU_X86_SSE;
-  if(_edx&0x04000000)flags|=OC_CPU_X86_SSE2;
-  if(_ecx&0x00000001)flags|=OC_CPU_X86_PNI;
-  if(_ecx&0x00000100)flags|=OC_CPU_X86_SSSE3;
-  if(_ecx&0x00080000)flags|=OC_CPU_X86_SSE4_1;
-  if(_ecx&0x00100000)flags|=OC_CPU_X86_SSE4_2;
-  return flags;
-}
-
-static ogg_uint32_t oc_parse_amd_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){
-  ogg_uint32_t flags;
-  /*If there isn't even MMX, give up.*/
-  if(!(_edx&0x00800000))return 0;
-  flags=OC_CPU_X86_MMX;
-  if(_edx&0x00400000)flags|=OC_CPU_X86_MMXEXT;
-  if(_edx&0x80000000)flags|=OC_CPU_X86_3DNOW;
-  if(_edx&0x40000000)flags|=OC_CPU_X86_3DNOWEXT;
-  if(_ecx&0x00000040)flags|=OC_CPU_X86_SSE4A;
-  if(_ecx&0x00000800)flags|=OC_CPU_X86_SSE5;
-  return flags;
-}
-
-static ogg_uint32_t oc_cpu_flags_get(void){
-  ogg_uint32_t flags = 0;
-# if defined(__ppc__) || defined(__ppc64__) 
-/* detect AltiVec extension if compiling it for ppc */
-#  if defined(__APPLE__) || defined(__MACOSX__)  || defined(__DARWIN__)
-	int selectors[2] = { CTL_HW, HW_VECTORUNIT };
-	int i_has_altivec = 0;
-	size_t i_length = sizeof( i_has_altivec );
-	int i_error = sysctl( selectors, 2, &i_has_altivec, &i_length, NULL, 0);
-
-	if( i_error == 0 && i_has_altivec != 0 )
-		flags |= OC_CPU_PPC_ALTIVEC;
-#  else
-	void (*handler) (int sig);
-	handler = signal(SIGILL, illegal_instruction);
-	if (setjmp(jmpbuf) == 0) 
-	{
-		__asm__ __volatile__ (
-			"mtspr 256, %0\n\t" 
-			"vand %%v0, %%v0, %%v0" 
-			: : "r"(-1) );
-
-		flags |= OC_CPU_PPC_ALTIVEC;
-	}
-	signal(SIGILL, handler);
-#  endif	
-/* detect x86 CPU extensions */
-# elif defined(i386) || defined(__x86_64__) || defined(_M_IX86)
-  ogg_uint32_t eax;
-  ogg_uint32_t ebx;
-  ogg_uint32_t ecx;
-  ogg_uint32_t edx;
-# if !defined(__amd64__)&&!defined(__x86_64__)
-  /*Not all x86-32 chips support cpuid, so we have to check.*/
-#  if !defined(_MSC_VER)
-  __asm__ __volatile__(
-   "pushfl\n\t"
-   "pushfl\n\t"
-   "popl %[a]\n\t"
-   "movl %[a],%[b]\n\t"
-   "xorl $0x200000,%[a]\n\t"
-   "pushl %[a]\n\t"
-   "popfl\n\t"
-   "pushfl\n\t"
-   "popl %[a]\n\t"
-   "popfl\n\t"
-   :[a]"=r"(eax),[b]"=r"(ebx)
-   :
-   :"cc"
-  );
-#  else
-  oc_detect_cpuid_helper(&eax,&ebx);
-#  endif
-  /*No cpuid.*/
-  if(eax==ebx)return 0;
-# endif
-  cpuid(0,eax,ebx,ecx,edx);
-  /*         l e t n          I e n i          u n e G*/
-  if((ecx==0x6C65746E&&edx==0x49656E69&&ebx==0x756E6547)||
-   /*      6 8 x M          T e n i          u n e G*/
-   (ecx==0x3638784D&&edx==0x54656E69&&ebx==0x756E6547)) {
-    /*Intel, Transmeta (tested with Crusoe TM5800):*/
-    cpuid(1,eax,ebx,ecx,edx);
-    flags=oc_parse_intel_flags(edx,ecx);
-  }
-  /*              D M A c          i t n e          h t u A*/
-  else if((ecx==0x444D4163&&edx==0x69746E65&&ebx==0x68747541)||
-   /*      C S N            y b   e          d o e G*/
-   (ecx==0x43534E20&&edx==0x79622065&&ebx==0x646F6547)){
-    /*AMD, Geode:*/
-    cpuid(0x80000000,eax,ebx,ecx,edx);
-    if(eax<0x80000001)flags=0;
-    else{
-      cpuid(0x80000001,eax,ebx,ecx,edx);
-      flags=oc_parse_amd_flags(edx,ecx);
-    }
-    /*Also check for SSE.*/
-    cpuid(1,eax,ebx,ecx,edx);
-    flags|=oc_parse_intel_flags(edx,ecx);
-  }
-  /*Technically some VIA chips can be configured in the BIOS to return any
-     string here the user wants.
-    There is a special detection method that can be used to identify such
-     processors, but in my opinion, if the user really wants to change it, they
-     deserve what they get.*/
-  /*              s l u a          H r u a          t n e C*/
-  else if(ecx==0x736C7561&&edx==0x48727561&&ebx==0x746E6543){
-    /*VIA:*/
-    /*I only have documentation for the C7 (Esther) and Isaiah (forthcoming)
-       chips (thanks to the engineers from Centaur Technology who provided it).
-      These chips support Intel-like cpuid info.
-      The C3-2 (Nehemiah) cores appear to, as well.*/
-    cpuid(1,eax,ebx,ecx,edx);
-    flags=oc_parse_intel_flags(edx,ecx);
-    cpuid(0x80000000,eax,ebx,ecx,edx);
-    if(eax>=0x80000001){
-      /*The (non-Nehemiah) C3 processors support AMD-like cpuid info.
-        We need to check this even if the Intel test succeeds to pick up 3DNow!
-         support on these processors.
-        Unlike actual AMD processors, we cannot _rely_ on this info, since
-         some cores (e.g., the 693 stepping of the Nehemiah) claim to support
-         this function, yet return edx=0, despite the Intel test indicating
-         MMX support.
-        Therefore the features detected here are strictly added to those
-         detected by the Intel test.*/
-      /*TODO: How about earlier chips?*/
-      cpuid(0x80000001,eax,ebx,ecx,edx);
-      /*Note: As of the C7, this function returns Intel-style extended feature
-         flags, not AMD-style.
-        Currently, this only defines bits 11, 20, and 29 (0x20100800), which
-         do not conflict with any of the AMD flags we inspect.
-        For the remaining bits, Intel tells us, "Do not count on their value",
-         but VIA assures us that they will all be zero (at least on the C7 and
-         Isaiah chips).
-        In the (unlikely) event a future processor uses bits 18, 19, 30, or 31
-         (0xC0C00000) for something else, we will have to add code to detect
-         the model to decide when it is appropriate to inspect them.*/
-      flags|=oc_parse_amd_flags(edx,ecx);
-    }
-  }
-  else{
-    /*Implement me.*/
-    flags=0;
-  }
-# else
-  /* not x86 or ppc */ 
-# endif
-  return flags;
-}
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2008                *
+ * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
+ *                                                                  *
+ ********************************************************************
+
+ CPU capability detection for x86 processors.
+  Originally written by Rudolf Marek.
+
+ function:
+  last mod: $Id$
+
+ ********************************************************************/
+
+#include "cpu.h"
+
+/* for detecting AltiVec support */
+# if (defined(__ppc__) || defined(__ppc64__))
+#   if defined(__APPLE__) || defined(__MACOSX__)
+#include <sys/sysctl.h>
+#   else
+#include <signal.h>
+#include <setjmp.h>
+#   endif
+# endif
+
+# if (defined(__ppc__) || defined(__ppc64__)) && !(defined(__APPLE__) || defined(__MACOSX__))
+static jmp_buf jmpbuf;
+
+static void illegal_instruction(int sig)
+{
+        longjmp(jmpbuf, 1);
+}
+# endif
+
+#if defined(i386) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64)
+# if !defined(_MSC_VER)
+#  if defined(__amd64__)||defined(__x86_64__)
+/*On x86-64, gcc seems to be able to figure out how to save %rbx for us when
+   compiling with -fPIC.*/
+#   define cpuid(_op,_eax,_ebx,_ecx,_edx) \
+  __asm__ __volatile__( \
+   "cpuid\n\t" \
+   :[eax]"=a"(_eax),[ebx]"=b"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \
+   :"a"(_op) \
+   :"cc" \
+  )
+#  else
+/*On x86-32, not so much.*/
+#   define cpuid(_op,_eax,_ebx,_ecx,_edx) \
+  __asm__ __volatile__( \
+   "xchgl %%ebx,%[ebx]\n\t" \
+   "cpuid\n\t" \
+   "xchgl %%ebx,%[ebx]\n\t" \
+   :[eax]"=a"(_eax),[ebx]"=r"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \
+   :"a"(_op) \
+   :"cc" \
+  )
+#  endif
+# else
+#   if defined(_M_IX86) 
+/*Why does MSVC need this complicated rigamarole?
+  At this point I honestly do not care.*/
+
+/*Visual C cpuid helper function.
+  For VS2005 we could as well use the _cpuid builtin, but that wouldn't work
+   for VS2003 users, so we do it in inline assembler.*/
+static void oc_cpuid_helper(ogg_uint32_t _cpu_info[4],ogg_uint32_t _op){
+  _asm {
+    mov eax,[_op]
+    mov esi,_cpu_info
+    cpuid
+    mov [esi+0],eax
+    mov [esi+4],ebx
+    mov [esi+8],ecx
+    mov [esi+12],edx
+  }
+}
+
+#  define cpuid(_op,_eax,_ebx,_ecx,_edx) \
+  do{ \
+    ogg_uint32_t cpu_info[4]; \
+    oc_cpuid_helper(cpu_info,_op); \
+    (_eax)=cpu_info[0]; \
+    (_ebx)=cpu_info[1]; \
+    (_ecx)=cpu_info[2]; \
+    (_edx)=cpu_info[3]; \
+  }while(0)
+
+static void oc_detect_cpuid_helper(ogg_uint32_t *_eax,ogg_uint32_t *_ebx){
+  _asm{
+    pushfd
+    pushfd
+    pop eax
+    mov ebx,eax
+    xor eax,200000h
+    push eax
+    popfd
+    pushfd
+    pop eax
+    popfd
+    mov ecx,_eax
+    mov [ecx],eax
+    mov ecx,_ebx
+    mov [ecx],ebx
+  }
+}
+#   elif defined(_M_AMD64)
+#   include <intrin.h>
+#   define cpuid(_op,_eax,_ebx,_ecx,_edx) \
+	  do{ \
+	    int cpu_info[4]; \
+	    __cpuid(cpu_info,_op); \
+	    (_eax)=cpu_info[0]; \
+	    (_ebx)=cpu_info[1]; \
+	    (_ecx)=cpu_info[2]; \
+	    (_edx)=cpu_info[3]; \
+	  }while(0)
+#   endif
+# endif
+#endif /* x86-only cpuid */
+
+static ogg_uint32_t oc_parse_intel_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){
+  ogg_uint32_t flags;
+  /*If there isn't even MMX, give up.*/
+  if(!(_edx&0x00800000))return 0;
+  flags=OC_CPU_X86_MMX;
+  if(_edx&0x02000000)flags|=OC_CPU_X86_MMXEXT|OC_CPU_X86_SSE;
+  if(_edx&0x04000000)flags|=OC_CPU_X86_SSE2;
+  if(_ecx&0x00000001)flags|=OC_CPU_X86_PNI;
+  if(_ecx&0x00000100)flags|=OC_CPU_X86_SSSE3;
+  if(_ecx&0x00080000)flags|=OC_CPU_X86_SSE4_1;
+  if(_ecx&0x00100000)flags|=OC_CPU_X86_SSE4_2;
+  return flags;
+}
+
+static ogg_uint32_t oc_parse_amd_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){
+  ogg_uint32_t flags;
+  /*If there isn't even MMX, give up.*/
+  if(!(_edx&0x00800000))return 0;
+  flags=OC_CPU_X86_MMX;
+  if(_edx&0x00400000)flags|=OC_CPU_X86_MMXEXT;
+  if(_edx&0x80000000)flags|=OC_CPU_X86_3DNOW;
+  if(_edx&0x40000000)flags|=OC_CPU_X86_3DNOWEXT;
+  if(_ecx&0x00000040)flags|=OC_CPU_X86_SSE4A;
+  if(_ecx&0x00000800)flags|=OC_CPU_X86_SSE5;
+  return flags;
+}
+
+static ogg_uint32_t oc_cpu_flags_get(void){
+  ogg_uint32_t flags = 0;
+# if defined(__ppc__) || defined(__ppc64__) 
+/* detect AltiVec extension if compiling it for ppc */
+#  if defined(__APPLE__) || defined(__MACOSX__)  || defined(__DARWIN__)
+	int selectors[2] = { CTL_HW, HW_VECTORUNIT };
+	int i_has_altivec = 0;
+	size_t i_length = sizeof( i_has_altivec );
+	int i_error = sysctl( selectors, 2, &i_has_altivec, &i_length, NULL, 0);
+
+	if( i_error == 0 && i_has_altivec != 0 )
+		flags |= OC_CPU_PPC_ALTIVEC;
+#  else
+	void (*handler) (int sig);
+	handler = signal(SIGILL, illegal_instruction);
+	if (setjmp(jmpbuf) == 0) 
+	{
+		__asm__ __volatile__ (
+			"mtspr 256, %0\n\t" 
+			"vand %%v0, %%v0, %%v0" 
+			: : "r"(-1) );
+
+		flags |= OC_CPU_PPC_ALTIVEC;
+	}
+	signal(SIGILL, handler);
+#  endif	
+/* detect x86 CPU extensions */
+# elif defined(i386) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64)
+  ogg_uint32_t eax;
+  ogg_uint32_t ebx;
+  ogg_uint32_t ecx;
+  ogg_uint32_t edx;
+# if !defined(__amd64__)&&!defined(__x86_64__)&&!defined(_M_AMD64)
+  /*Not all x86-32 chips support cpuid, so we have to check.*/
+#  if !defined(_MSC_VER)
+  __asm__ __volatile__(
+   "pushfl\n\t"
+   "pushfl\n\t"
+   "popl %[a]\n\t"
+   "movl %[a],%[b]\n\t"
+   "xorl $0x200000,%[a]\n\t"
+   "pushl %[a]\n\t"
+   "popfl\n\t"
+   "pushfl\n\t"
+   "popl %[a]\n\t"
+   "popfl\n\t"
+   :[a]"=r"(eax),[b]"=r"(ebx)
+   :
+   :"cc"
+  );
+#  else
+  oc_detect_cpuid_helper(&eax,&ebx);
+#  endif
+  /*No cpuid.*/
+  if(eax==ebx)return 0;
+# endif
+  cpuid(0,eax,ebx,ecx,edx);
+  /*         l e t n          I e n i          u n e G*/
+  if((ecx==0x6C65746E&&edx==0x49656E69&&ebx==0x756E6547)||
+   /*      6 8 x M          T e n i          u n e G*/
+   (ecx==0x3638784D&&edx==0x54656E69&&ebx==0x756E6547)) {
+    /*Intel, Transmeta (tested with Crusoe TM5800):*/
+    cpuid(1,eax,ebx,ecx,edx);
+    flags=oc_parse_intel_flags(edx,ecx);
+  }
+  /*              D M A c          i t n e          h t u A*/
+  else if((ecx==0x444D4163&&edx==0x69746E65&&ebx==0x68747541)||
+   /*      C S N            y b   e          d o e G*/
+   (ecx==0x43534E20&&edx==0x79622065&&ebx==0x646F6547)){
+    /*AMD, Geode:*/
+    cpuid(0x80000000,eax,ebx,ecx,edx);
+    if(eax<0x80000001)flags=0;
+    else{
+      cpuid(0x80000001,eax,ebx,ecx,edx);
+      flags=oc_parse_amd_flags(edx,ecx);
+    }
+    /*Also check for SSE.*/
+    cpuid(1,eax,ebx,ecx,edx);
+    flags|=oc_parse_intel_flags(edx,ecx);
+  }
+  /*Technically some VIA chips can be configured in the BIOS to return any
+     string here the user wants.
+    There is a special detection method that can be used to identify such
+     processors, but in my opinion, if the user really wants to change it, they
+     deserve what they get.*/
+  /*              s l u a          H r u a          t n e C*/
+  else if(ecx==0x736C7561&&edx==0x48727561&&ebx==0x746E6543){
+    /*VIA:*/
+    /*I only have documentation for the C7 (Esther) and Isaiah (forthcoming)
+       chips (thanks to the engineers from Centaur Technology who provided it).
+      These chips support Intel-like cpuid info.
+      The C3-2 (Nehemiah) cores appear to, as well.*/
+    cpuid(1,eax,ebx,ecx,edx);
+    flags=oc_parse_intel_flags(edx,ecx);
+    cpuid(0x80000000,eax,ebx,ecx,edx);
+    if(eax>=0x80000001){
+      /*The (non-Nehemiah) C3 processors support AMD-like cpuid info.
+        We need to check this even if the Intel test succeeds to pick up 3DNow!
+         support on these processors.
+        Unlike actual AMD processors, we cannot _rely_ on this info, since
+         some cores (e.g., the 693 stepping of the Nehemiah) claim to support
+         this function, yet return edx=0, despite the Intel test indicating
+         MMX support.
+        Therefore the features detected here are strictly added to those
+         detected by the Intel test.*/
+      /*TODO: How about earlier chips?*/
+      cpuid(0x80000001,eax,ebx,ecx,edx);
+      /*Note: As of the C7, this function returns Intel-style extended feature
+         flags, not AMD-style.
+        Currently, this only defines bits 11, 20, and 29 (0x20100800), which
+         do not conflict with any of the AMD flags we inspect.
+        For the remaining bits, Intel tells us, "Do not count on their value",
+         but VIA assures us that they will all be zero (at least on the C7 and
+         Isaiah chips).
+        In the (unlikely) event a future processor uses bits 18, 19, 30, or 31
+         (0xC0C00000) for something else, we will have to add code to detect
+         the model to decide when it is appropriate to inspect them.*/
+      flags|=oc_parse_amd_flags(edx,ecx);
+    }
+  }
+  else{
+    /*Implement me.*/
+    flags=0;
+  }
+# else
+  /* not x86 or ppc */ 
+# endif
+  return flags;
+}
--- a/media/liboggplay/src/liboggplay/oggplay.c
+++ b/media/liboggplay/src/liboggplay/oggplay.c
@@ -79,16 +79,20 @@ oggplay_new_with_reader(OggPlayReader *r
 }
 
 OggPlayErrorCode
 oggplay_initialise(OggPlay *me, int block) {
 
   OggPlayErrorCode  return_val;
   int               i;
 
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_OGGPLAY;
+  }
+  
   return_val = me->reader->initialise(me->reader, block);
 
   if (return_val != E_OGGPLAY_OK) {
     return return_val;
   }
 
   /*
    * this is the cut-off time value below which packets will be ignored.  Initialise it to 0 here.
@@ -113,33 +117,48 @@ oggplay_initialise(OggPlay *me, int bloc
 
   if (oggz_io_set_tell(me->oggz, me->reader->io_tell, me->reader) != 0)
     return E_OGGPLAY_OGGZ_UNHAPPY;
 
   if (oggz_set_read_callback(me->oggz, -1, oggplay_callback_predetected, me))
     return E_OGGPLAY_OGGZ_UNHAPPY;
 
   while (1) {
-
-    if (oggz_read(me->oggz, OGGZ_READ_CHUNK_SIZE) <= 0) {
-      return E_OGGPLAY_BAD_INPUT;
+    i = oggz_read (me->oggz, OGGZ_READ_CHUNK_SIZE);
+    
+    switch (i) {
+      case 0:
+        /* 
+         * EOF reached while processing headers,
+         * possible erroneous file, mark it as such.
+         */
+      case OGGZ_ERR_HOLE_IN_DATA:
+        /* there was a whole in the data */
+        return E_OGGPLAY_BAD_INPUT;
+      
+      case OGGZ_ERR_OUT_OF_MEMORY:
+        /* ran out of memory during decoding! */
+        return E_OGGPLAY_OUT_OF_MEMORY;
+      
+      case OGGZ_ERR_STOP_ERR:
+        /* */
+        return E_OGGPLAY_BAD_OGGPLAY;
     }
 
     if (me->all_tracks_initialised) {
       break;
     }
   }
 
   /*
    * set all the tracks to inactive
    */
   for (i = 0; i < me->num_tracks; i++) {
     me->decode_data[i]->active = 0;
   }
-  me->active_tracks = 0;
 
   /*
    * if the buffer was set up before initialisation, prepare it now
    */
   if (me->buffer != NULL) {
     oggplay_buffer_prepare(me);
   }
 
@@ -148,24 +167,25 @@ oggplay_initialise(OggPlay *me, int bloc
 }
 
 OggPlay *
 oggplay_open_with_reader(OggPlayReader *reader) {
 
   OggPlay *me = NULL;
   int r = E_OGGPLAY_TIMEOUT;
 
-  if ( (me = oggplay_new_with_reader(reader)) == NULL)
+  if ((me = oggplay_new_with_reader(reader)) == NULL)
     return NULL;
 
   while (r == E_OGGPLAY_TIMEOUT) {
     r = oggplay_initialise(me, 0);
   }
 
   if (r != E_OGGPLAY_OK) {
+    
     /* in case of error close the OggPlay handle */
     oggplay_close(me);
 
     return NULL;
   }
 
   return me;
 }
@@ -192,17 +212,17 @@ oggplay_set_data_callback(OggPlay *me, O
 }
 
 /*
  * internal function that doesn't perform error checking.  Used so the buffer
  * can register a callback!
  */
 void
 oggplay_set_data_callback_force(OggPlay *me, OggPlayDataCallback callback,
-                void *user) {
+                                void *user) {
 
   me->callback = callback;
   me->callback_user_ptr = user;
 
 }
 
 
 OggPlayErrorCode
@@ -310,35 +330,36 @@ oggplay_get_video_aspect_ratio(OggPlay *
 
   (*aspect_denom) = decode->video_info.aspect_denominator;
   (*aspect_num) = decode->video_info.aspect_numerator;
 
   return E_OGGPLAY_OK;
 }
 
 OggPlayErrorCode
-oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert) {
+oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert, int swap_rgb) {
   OggPlayTheoraDecode *decode;
 
   if (me == NULL) {
     return E_OGGPLAY_BAD_OGGPLAY;
   }
 
   if (track < 0 || track >= me->num_tracks) {
     return E_OGGPLAY_BAD_TRACK;
   }
 
   if (me->decode_data[track]->content_type != OGGZ_CONTENT_THEORA) {
     return E_OGGPLAY_WRONG_TRACK_TYPE;
   }
 
   decode = (OggPlayTheoraDecode *)(me->decode_data[track]);
 
-  if (decode->convert_to_rgb != convert) {
+  if (decode->convert_to_rgb != convert || decode->swap_rgb != swap_rgb) {
     decode->convert_to_rgb = convert;
+    decode->swap_rgb = swap_rgb;
     me->decode_data[track]->decoded_type = convert ? OGGPLAY_RGBA_VIDEO : OGGPLAY_YUV_VIDEO;
 
     /* flush any records created with previous type */
     oggplay_data_free_list(me->decode_data[track]->data_list);
     me->decode_data[track]->data_list = NULL;
   }
 
   return E_OGGPLAY_OK;
@@ -474,18 +495,18 @@ oggplay_get_kate_category(OggPlay *me, i
 
   if (me->decode_data[track]->content_type != OGGZ_CONTENT_KATE) {
     return E_OGGPLAY_WRONG_TRACK_TYPE;
   }
 
   decode = (OggPlayKateDecode *)(me->decode_data[track]);
 
 #ifdef HAVE_KATE
-  if (decode->init) {
-    (*category) = decode->k.ki->category;
+  if (decode->decoder.initialised) {
+    (*category) = decode->k_state.ki->category;
     return E_OGGPLAY_OK;
   }
   else return E_OGGPLAY_UNINITIALISED;
 #else
   return E_OGGPLAY_NO_KATE_SUPPORT;
 #endif
 }
 
@@ -504,28 +525,28 @@ oggplay_get_kate_language(OggPlay *me, i
 
   if (me->decode_data[track]->content_type != OGGZ_CONTENT_KATE) {
     return E_OGGPLAY_WRONG_TRACK_TYPE;
   }
 
   decode = (OggPlayKateDecode *)(me->decode_data[track]);
 
 #ifdef HAVE_KATE
-  if (decode->init) {
-    (*language) = decode->k.ki->language;
+  if (decode->decoder.initialised) {
+    (*language) = decode->k_state.ki->language;
     return E_OGGPLAY_OK;
   }
   else return E_OGGPLAY_UNINITIALISED;
 #else
   return E_OGGPLAY_NO_KATE_SUPPORT;
 #endif
 }
 
 OggPlayErrorCode
-oggplay_set_kate_tiger_rendering(OggPlay *me, int track, int use_tiger) {
+oggplay_set_kate_tiger_rendering(OggPlay *me, int track, int use_tiger, int swap_rgb, int default_width, int default_height) {
 
   OggPlayKateDecode * decode;
 
   if (me == NULL) {
     return E_OGGPLAY_BAD_OGGPLAY;
   }
 
   if (track < 0 || track >= me->num_tracks) {
@@ -535,18 +556,21 @@ oggplay_set_kate_tiger_rendering(OggPlay
   if (me->decode_data[track]->content_type != OGGZ_CONTENT_KATE) {
     return E_OGGPLAY_WRONG_TRACK_TYPE;
   }
 
   decode = (OggPlayKateDecode *)(me->decode_data[track]);
 
 #ifdef HAVE_KATE
 #ifdef HAVE_TIGER
-  if (decode->init && decode->tr) {
+  if (decode->decoder.initialised && decode->tr) {
     decode->use_tiger = use_tiger;
+    decode->swap_rgb = swap_rgb;
+    decode->default_width = default_width;
+    decode->default_height = default_height;
     decode->decoder.decoded_type = use_tiger ? OGGPLAY_RGBA_VIDEO : OGGPLAY_KATE;
     return E_OGGPLAY_OK;
   }
   else return E_OGGPLAY_UNINITIALISED;
 #else
   return E_OGGPLAY_NO_TIGER_SUPPORT;
 #endif
 #else
@@ -610,23 +634,38 @@ oggplay_step_decoding(OggPlay *me) {
   int                     r;
   int                     i;
   int                     need_data  = 0;
   int                     chunk_count = 0;
 
   if (me == NULL) {
     return E_OGGPLAY_BAD_OGGPLAY;
   }
+  
+  /* 
+   * check whether the OggPlayDataCallback is set for the given
+   * OggPlay handle. If not return with error as there's no callback 
+   * function processing the decoded data.
+   */
+  if (me->callback == NULL) {
+    return E_OGGPLAY_UNINITIALISED;
+  }
 
   /*
    * clean up any trash pointers.  As soon as the current buffer has a
    * frame taken out, we know the old buffer will no longer be used.
    */
 
-  if (me->trash != NULL && me->buffer->last_emptied > -1) {
+  if 
+  (
+    me->trash != NULL 
+    && 
+    (me->buffer == NULL || me->buffer->last_emptied > -1)
+  ) 
+  {
     oggplay_take_out_trash(me, me->trash);
     me->trash = NULL;
   }
 
 read_more_data:
 
   while (1) {
      /*
@@ -686,46 +725,68 @@ read_more_data:
     if (chunk_count > MAX_CHUNK_COUNT) {
       return E_OGGPLAY_TIMEOUT;
     }
 
     chunk_count += 1;
 
     r = oggz_read(me->oggz, OGGZ_READ_CHUNK_SIZE);
 
-    /* end-of-file */
-    if (r == 0) {
-      num_records = oggplay_callback_info_prepare(me, &info);
-     /*
-       * set all of the tracks to inactive
-       */
-      for (i = 0; i < me->num_tracks; i++) {
-        me->decode_data[i]->active = 0;
-      }
-      me->active_tracks = 0;
+    switch (r) {
+      case 0:
+        /* end-of-file */
+        
+        num_records = oggplay_callback_info_prepare(me, &info);
+        /*
+        * set all of the tracks to inactive
+        */
+        for (i = 0; i < me->num_tracks; i++) {
+          me->decode_data[i]->active = 0;
+        }
+        me->active_tracks = 0;
+
+        if (info != NULL) {
+          me->callback (me, num_records, info, me->callback_user_ptr);
+          oggplay_callback_info_destroy(me, info);
+        }
 
-      if (info != NULL) {
-        me->callback (me, num_records, info, me->callback_user_ptr);
-        oggplay_callback_info_destroy(me, info);
-      }
+        /*
+        * ensure all tracks have their final data packet set to end_of_stream
+        * But skip doing this if we're shutting down --- me->buffer may not
+        * be in a safe state.
+        */
+        if (me->buffer != NULL && !me->shutdown) {
+          oggplay_buffer_set_last_data(me, me->buffer);
+        }
+
+        /* we reached the end of the stream */
+        return E_OGGPLAY_OK;
+              
+      case OGGZ_ERR_HOLE_IN_DATA:
+        /* there was a whole in the data */
+        return E_OGGPLAY_BAD_INPUT;
 
-      /*
-       * ensure all tracks have their final data packet set to end_of_stream
-       * But skip doing this if we're shutting down --- me->buffer may not
-       * be in a safe state.
-       */
-      if (me->buffer != NULL && !me->shutdown) {
-        oggplay_buffer_set_last_data(me, me->buffer);
-      }
-
-      return E_OGGPLAY_OK;
-    } else if (r == OGGZ_ERR_HOLE_IN_DATA) {
-      return E_OGGPLAY_BAD_INPUT;
+      case OGGZ_ERR_STOP_ERR:
+        /* 
+         * one of the callback functions requested us to stop.
+         * as this currently happens only when one of the 
+         * OggzReadPacket callback functions does not receive
+         * the user provided data, i.e. the OggPlayDecode struct
+         * for the track mark it as a memory problem, since this
+         * could happen only if something is wrong with the memory,
+         * e.g. some buffer overflow.
+         */
+      
+      case OGGZ_ERR_OUT_OF_MEMORY:
+        /* ran out of memory during decoding! */
+        return E_OGGPLAY_OUT_OF_MEMORY;
+                
+      default:
+        break;
     }
-
   }
   /*
    * prepare a callback
    */
   num_records = oggplay_callback_info_prepare (me, &info);
   if (info != NULL) {
     r = me->callback (me, num_records, info, me->callback_user_ptr);
     oggplay_callback_info_destroy (me, info);
@@ -734,21 +795,31 @@ read_more_data:
   }
 
   /*
    * clean the data lists
    */
   for (i = 0; i < me->num_tracks; i++) {
     oggplay_data_clean_list (me->decode_data[i]);
   }
-
+  
+  /* 
+   * there was an error during info prepare!
+   * abort decoding! 
+   */
+  if (num_records < 0) {
+    return num_records;
+  }
+  
+  /* if we received an shutdown event, dont try to read more data...*/
   if (me->shutdown) {
     return E_OGGPLAY_OK;
   }
-
+  
+  /* we require more data for decoding */
   if (info == NULL) {
     goto read_more_data;
   }
 
   me->target += me->callback_period;
   if (r == -1) {
     return E_OGGPLAY_USER_INTERRUPT;
   }
@@ -779,31 +850,34 @@ oggplay_close(OggPlay *me) {
   if (me == NULL) {
     return E_OGGPLAY_BAD_OGGPLAY;
   }
 
   if (me->reader != NULL) {
     me->reader->destroy(me->reader);
   }
 
-
-  if (me->decode_data) {
+  /* */
+  if (me->decode_data != NULL) {
     for (i = 0; i < me->num_tracks; i++) {
       oggplay_callback_shutdown(me->decode_data[i]);
     }
   }
 
   if (me->oggz)
     oggz_close(me->oggz);
 
   if (me->buffer != NULL) {
     oggplay_buffer_shutdown(me, me->buffer);
   }
 
-  oggplay_free(me->callback_info);
+  if (me->callback_info != NULL) {
+    oggplay_free(me->callback_info);
+  }
+    
   oggplay_free(me->decode_data);
   oggplay_free(me);
 
   return E_OGGPLAY_OK;
 }
 
 /*
  * this function is required to release the frame_sem in the buffer, if
--- a/media/liboggplay/src/liboggplay/oggplay_buffer.c
+++ b/media/liboggplay/src/liboggplay/oggplay_buffer.c
@@ -94,31 +94,44 @@ error:
 
 void
 oggplay_buffer_shutdown(OggPlay *me, volatile OggPlayBuffer *vbuffer) {
 
   int i;
   int j;
 
   OggPlayBuffer *buffer = (OggPlayBuffer *)vbuffer;
-
-  for (i = 0; i < buffer->buffer_size; i++) {
-    if (buffer->buffer_mirror[i] != NULL) {
-      OggPlayCallbackInfo *ti = (OggPlayCallbackInfo *)buffer->buffer_mirror[i];
-      for (j = 0; j < me->num_tracks; j++) {
-        oggplay_free((ti + j)->records);
-      }
-      oggplay_free(ti);
-    }
+  
+  if (buffer == NULL) {
+    return;
   }
 
-  oggplay_free(buffer->buffer_list);
-  oggplay_free(buffer->buffer_mirror);
+  if (buffer->buffer_mirror != NULL) {
+    for (i = 0; i < buffer->buffer_size; i++) {
+      
+      if (buffer->buffer_mirror[i] != NULL) {
+        OggPlayCallbackInfo *ti = (OggPlayCallbackInfo *)buffer->buffer_mirror[i];
+        for (j = 0; j < me->num_tracks; j++) {
+          if ( (ti+j) != NULL) {
+            oggplay_free((ti + j)->records);
+          }
+        }
+        oggplay_free(ti);
+      }
+      
+    }
+    oggplay_free(buffer->buffer_mirror);
+  }
+
+  if (buffer->buffer_list != NULL) 
+    oggplay_free(buffer->buffer_list);
+    
   SEM_CLOSE(buffer->frame_sem);
   oggplay_free(buffer);
+  buffer = NULL;
 }
 
 int
 oggplay_buffer_is_full(volatile OggPlayBuffer *buffer) {
 
   return
   (
     (buffer == NULL) || (
@@ -149,17 +162,17 @@ oggplay_buffer_set_last_data(OggPlay *me
   for (i = 0; i < me->num_tracks; i++) {
     p->stream_info = OGGPLAY_STREAM_LAST_DATA;
     p++;
   }
 }
 
 int
 oggplay_buffer_callback(OggPlay *me, int tracks,
-                 OggPlayCallbackInfo **track_info, void *user) {
+                        OggPlayCallbackInfo **track_info, void *user) {
 
   int                   i;
   int                   j;
   int                   k;
   OggPlayDataHeader  ** headers;
   OggPlayBuffer       * buffer;
   OggPlayCallbackInfo * ptr = track_info[0];
   int                   required;
@@ -194,28 +207,31 @@ oggplay_buffer_callback(OggPlay *me, int
    * check for and clean up empties
    */
   for (k = 0; k < buffer->buffer_size; k++) {
     if
     (
       (buffer->buffer_list[k] == NULL)
       &&
       (buffer->buffer_mirror[k] != NULL)
-    ) {
+    ) 
+    {
       OggPlayCallbackInfo *ti = (OggPlayCallbackInfo *)buffer->buffer_mirror[k];
       for (i = 0; i < tracks; i++) {
         headers = oggplay_callback_info_get_headers(ti + i);
         required = oggplay_callback_info_get_required(ti + i);
         for (j = 0; j < required; j++) {
           oggplay_callback_info_unlock_item(headers[j]);
         }
         /* free these here, because we couldn't free them in
          * oggplay_callback_info_destroy for buffer mode
          */
-        oggplay_free((ti + i)->records);
+        if ((ti + i) != NULL) {
+          oggplay_free((ti + i)->records);
+        }
       }
       oggplay_free(ti);
       buffer->buffer_mirror[k] = NULL;
     }
   }
 
   /*
    * replace the decode_data buffer for the next callback
@@ -249,17 +265,17 @@ oggplay_buffer_callback(OggPlay *me, int
   }
 
   return 0;
 }
 
 OggPlayCallbackInfo **
 oggplay_buffer_retrieve_next(OggPlay *me) {
 
-  OggPlayBuffer         * buffer;
+  OggPlayBuffer         * buffer = NULL;
   int                     next_loc;
   OggPlayCallbackInfo   * next_item;
   OggPlayCallbackInfo  ** return_val;
   int                     i;
 
   if (me == NULL) {
     return NULL;
   }
@@ -275,31 +291,32 @@ oggplay_buffer_retrieve_next(OggPlay *me
   if (buffer->buffer_list[next_loc] == NULL) {
     return NULL;
   }
 
   next_item = (OggPlayCallbackInfo*)buffer->buffer_list[next_loc];
   buffer->last_emptied = next_loc;
 
   return_val = oggplay_calloc(me->num_tracks, sizeof (OggPlayCallbackInfo *));
-  if (return_val == NULL)
+  if (return_val == NULL) {
     return NULL;
-
+  }
+  
   for (i = 0; i < me->num_tracks; i++) {
     return_val[i] = next_item + i;
   }
 
   return return_val;
 
 }
 
 OggPlayErrorCode
 oggplay_buffer_release(OggPlay *me, OggPlayCallbackInfo **track_info) {
 
-  OggPlayBuffer *buffer;
+  OggPlayBuffer *buffer = NULL;
 
   if (me == NULL) {
     return E_OGGPLAY_BAD_OGGPLAY;
   }
 
   if (track_info == NULL) {
     return E_OGGPLAY_OK;
   }
@@ -309,17 +326,19 @@ oggplay_buffer_release(OggPlay *me, OggP
   if (buffer == NULL) {
     return E_OGGPLAY_CALLBACK_MODE;
   }
 
   if (buffer->buffer_list[buffer->last_emptied] == NULL) {
     return E_OGGPLAY_UNINITIALISED;
   }
 
-  oggplay_free(track_info);
+  if (track_info != NULL) {
+    oggplay_free(track_info);
+  }
 
   buffer->buffer_list[buffer->last_emptied] = NULL;
 
   SEM_SIGNAL(buffer->frame_sem);
 
   return E_OGGPLAY_OK;
 
 }
--- a/media/liboggplay/src/liboggplay/oggplay_callback.c
+++ b/media/liboggplay/src/liboggplay/oggplay_callback.c
@@ -41,158 +41,231 @@
 
 #include <stdlib.h>
 #if TIME_THEORA_DECODE
 #include <sys/time.h>
 #endif
 #include <time.h>
 #include <string.h>
 
+#define THEORA_VERSION(maj,min,rev) ((maj<<16)+(min<<8)+rev)
+
 void
 oggplay_init_theora(void *user_data) {
 
   OggPlayTheoraDecode   * decoder     = (OggPlayTheoraDecode *)user_data;
 
+  if (decoder == NULL) {
+    return;
+  }
+  
   theora_info_init(&(decoder->video_info));
   theora_comment_init(&(decoder->video_comment));
-  decoder->remaining_header_packets = 3;
   decoder->granulepos_seen = 0;
   decoder->frame_delta = 0;
   decoder->y_width = 0;
   decoder->convert_to_rgb = 0;
+  decoder->swap_rgb = 0;
   decoder->decoder.decoded_type = OGGPLAY_YUV_VIDEO;
-  decoder->decoder.player->active_tracks++;
 }
 
 void
 oggplay_shutdown_theora(void *user_data) {
-
+  OggPlayDecode         * common;
   OggPlayTheoraDecode   * decoder = (OggPlayTheoraDecode *)user_data;
 
-  if (decoder->remaining_header_packets == 0) {
+  if (decoder == NULL) {
+    return;
+  }
+  
+  if ((common = &(decoder->decoder)) == NULL) {
+    return;
+  }
+  
+  if (common->initialised == 1 && decoder->decoder.num_header_packets == 0) {
     theora_clear(&(decoder->video_handle));
   }
   theora_info_clear(&(decoder->video_info));
   theora_comment_clear(&(decoder->video_comment));
 }
 
 int
 oggplay_callback_theora (OGGZ * oggz, ogg_packet * op, long serialno,
-                void * user_data) {
+                         void * user_data) {
 
   OggPlayTheoraDecode   * decoder     = (OggPlayTheoraDecode *)user_data;
-  OggPlayDecode         * common      = &(decoder->decoder);
+  OggPlayDecode         * common      = NULL;
   ogg_int64_t             granulepos  = oggz_tell_granulepos(oggz);
   yuv_buffer              buffer;
-  int granuleshift;
-  long frame;
-
+  int                     granuleshift;
+  long                    frame;
+  OggPlayErrorCode        ret;
+  
+  /* check whether user_data is valid */
+  if (decoder == NULL) {
+    return OGGZ_STOP_ERR;
+  }
+  
+  if ((common = &(decoder->decoder)) == NULL) {
+    return OGGZ_STOP_ERR;
+  }
+    
 #if TIME_THEORA_DECODE
   struct timeval          tv;
   struct timeval          tv2;
   int                     musec;
 #endif
 
-  if ( (granulepos > 0) && (common->last_granulepos > granulepos)) {
+  if (!common->active) {
+    /*
+     * don't decode other packets
+     */
+    return OGGZ_CONTINUE;
+  }
+  
+  if ((granulepos > 0) && (common->last_granulepos > granulepos)) {
     /* 
      * the granule position is not monotonically increasing,
      * something wrong with the page!
      * skipping this page..... 
      */
-    return 0;
+    return OGGZ_CONTINUE;
   }
-
+  
   /*
    * always decode headers
    */
-  if (theora_packet_isheader(op)) {
-    if (theora_decode_header(&(decoder->video_info), &(decoder->video_comment), op) < 0)
-      return -1;
+  if (theora_packet_isheader(op) &&
+	  common->num_header_packets > 0 &&
+	  common->initialised != -1)
+  {
+    if (theora_decode_header(&(decoder->video_info), &(decoder->video_comment), op) < 0) {
+      common->initialised |= -1;
+      return OGGZ_CONTINUE;
+    }
 
     /*
      * initialise width/stride/height data (this is common to all frames).
      * Use the buffer stride for the width to avoid passing negative stride
      * issues on to the user.
      */
-    decoder->y_width = decoder->y_stride = decoder->video_info.frame_width;
-    decoder->y_height = decoder->video_info.frame_height;
-    decoder->uv_width = decoder->uv_stride = decoder->video_info.frame_width / 2;
-    decoder->uv_height = decoder->video_info.frame_height / 2;
-  
-    if (decoder->y_width == 0 ||
-        decoder->y_height == 0 || 
-        decoder->uv_width == 0 ||
-        decoder->uv_height == 0) {
-      decoder->decoder.active = 0;
-      return 0;
+
+    if (--(common->num_header_packets) == 0) {
+      decoder->y_width = decoder->y_stride = decoder->video_info.frame_width;
+      decoder->y_height = decoder->video_info.frame_height;
+
+      if (decoder->video_info.pixelformat == OC_PF_444) {
+        decoder->uv_width = decoder->uv_stride = decoder->video_info.frame_width;
+        decoder->uv_height = decoder->video_info.frame_height;
+      } else if (decoder->video_info.pixelformat == OC_PF_422) {
+        decoder->uv_width = decoder->uv_stride = decoder->video_info.frame_width / 2;
+        decoder->uv_height = decoder->video_info.frame_height;
+      } else if (decoder->video_info.pixelformat == OC_PF_420) {
+        decoder->uv_width = decoder->uv_stride = decoder->video_info.frame_width / 2;
+        decoder->uv_height = decoder->video_info.frame_height / 2;
+      } else {
+        common->initialised |= -1;
+        return OGGZ_CONTINUE;
+      }
+
+     if (decoder->y_width == 0 ||
+         decoder->y_height == 0 || 
+         decoder->uv_width == 0 ||
+         decoder->uv_height == 0) {
+       /* it's a theora track with one of it's plane's dimension 0
+        * decoding this track is not possible.
+        */
+       common->initialised |= -1;
+       return OGGZ_CONTINUE;
+     }
+
+      /* Ensure the offsets do not push the viewable area outside of the decoded frame. */
+      if 
+      (
+        ((decoder->video_info.height - decoder->video_info.offset_y)<decoder->video_info.frame_height)
+        ||
+        ((decoder->video_info.width - decoder->video_info.offset_x)<decoder->video_info.frame_width)
+      )
+      {
+        common->initialised |= -1;
+        return OGGZ_CONTINUE;
+      }
+      
+      if (theora_decode_init(&(decoder->video_handle), &(decoder->video_info))) {
+        common->initialised |= -1;
+        return OGGZ_CONTINUE;
+      }
+
+      common->initialised |= 1;
     }
-    
-    if (--(decoder->remaining_header_packets) == 0) {
-      /* Ensure the offsets do not push the viewable area outside of the decoded frame. */
-      if (((decoder->video_info.height - decoder->video_info.offset_y)<decoder->video_info.frame_height)||
-          ((decoder->video_info.width - decoder->video_info.offset_x)<decoder->video_info.frame_width))
-          return -1;
-          
-      theora_decode_init(&(decoder->video_handle), &(decoder->video_info));
-    }
-    return 0;
-  }
-  else if (decoder->remaining_header_packets != 0) {
+    return OGGZ_CONTINUE;
+  } else if (common->num_header_packets != 0) {
     /*
      * Invalid Ogg file. Missing headers
      *
      */
     return -1;
   }
-
-  if (!decoder->decoder.active) {
-    /*
-     * don't decode other packets
-     */
-    return 0;
-  }
-
+  
   /*
    * if we get to here then we've passed all the header packets
    */
   if (common->current_loc == -1)
     common->current_loc = 0;
 
   /*
    * Decode the frame
    */
 
 #if TIME_THEORA_DECODE
   gettimeofday(&tv, NULL);
 #endif
 
-  if (theora_decode_packetin(&(decoder->video_handle), op) < 0)
-    return -1;
+  if (theora_decode_packetin(&(decoder->video_handle), op) < 0) {
+    return OGGZ_CONTINUE;
+  }
 
-  if (theora_decode_YUVout(&(decoder->video_handle), &buffer) < 0)
-    return -1;
+  if (theora_decode_YUVout(&(decoder->video_handle), &buffer) < 0) {
+    return OGGZ_CONTINUE;
+  }
 
 #if TIME_THEORA_DECODE
   gettimeofday(&tv2, NULL);
   musec = tv2.tv_usec - tv.tv_usec;
   if (tv2.tv_sec > tv.tv_sec)
     musec += (tv2.tv_sec - tv.tv_sec) * 1000000;
   printf("decode took %dus\n", musec);
 #endif
 
   if (granulepos != -1) {
+    int version = 
+      THEORA_VERSION(decoder->video_info.version_major, 
+                     decoder->video_info.version_minor,
+                     decoder->video_info.version_subminor);
+
     /* 
      * save last granule position in order to be able to validate
      * that it's monotonically increasing
      */
     common->last_granulepos = granulepos;
 
     /* calculate the frame number */
     granuleshift = oggz_get_granuleshift(oggz, serialno);
     frame = (granulepos >> granuleshift);
+    /* From theora bitstream version 3.2.1 onwards, frame granule numbers are
+     * relative to the end of the frame, i.e. frame granule numbers start at 1.
+     * We calcualte the presentation time as frame_number * granule_period,
+     * but that's only correct if frame numbers start at 0 (else it's the end
+     * time), so subtract 1 from the frame number if this is a theora stream
+     * of version 3.2.1 or greater to ensure correct presentation time
+     * calculation.
+     */
+    if (version >= THEORA_VERSION(3,2,1)) {
+      frame--;
+    }
     frame += (granulepos & ((1 << granuleshift) - 1));
     
     /* calculate the current location in the stream */
     common->current_loc = frame * common->granuleperiod;    
   } else {
     common->current_loc = -1;
   }
 
@@ -202,62 +275,102 @@ oggplay_callback_theora (OGGZ * oggz, og
     ||
     (common->current_loc >= common->player->presentation_time)
   )
   {
     /*
      * store the frame,
      * use the buffer stride for the width to avoid passing negative stride
      * issues on to the user.
-     * */
-    oggplay_data_handle_theora_frame(decoder, &buffer);
+     */
+    ret = oggplay_data_handle_theora_frame(decoder, &buffer);
+    if (ret != E_OGGPLAY_CONTINUE) {
+      return OGGZ_ERR_OUT_OF_MEMORY;
+    }
   }
 
   if (op->e_o_s) {
     common->active = 0;
     common->player->active_tracks--;
   }
 
-  return 0;
+  return OGGZ_CONTINUE;
 
 }
 
 void
 oggplay_init_cmml (void * user_data) {
 
   OggPlayCmmlDecode * decoder = (OggPlayCmmlDecode *)user_data;
+  
+  if (decoder == NULL) {
+    return;
+  }
+  
   decoder->decoder.decoded_type = OGGPLAY_CMML;
   decoder->granuleshift = 32; /* default */
 }
 
 int
 oggplay_callback_cmml (OGGZ * oggz, ogg_packet * op, long serialno,
-                void * user_data) {
+                       void * user_data) {
 
   OggPlayCmmlDecode * decoder     = (OggPlayCmmlDecode *)user_data;
-  OggPlayDecode     * common      = &(decoder->decoder);
+  OggPlayDecode     * common      = NULL;
   ogg_int64_t         granulepos  = oggz_tell_granulepos (oggz);
+  OggPlayErrorCode    ret;
+  
+  if (decoder == NULL) {
+    return OGGZ_STOP_ERR;
+  }
+    
+  if ((common = &(decoder->decoder)) == NULL) {
+    return OGGZ_STOP_ERR;
+  }
 
-  if (granulepos == 0) {
-    if (memcmp(op->packet, "CMML\0\0\0\0", 8) == 0) {
-      decoder->granuleshift = op->packet[28];
+  if (common->num_header_packets) {
+    /*
+     * Process the headers of the CMML stream. 
+     */
+     
+    if (common->num_header_packets == 3) {
+      /* The CMML ident header packet */
+      if (memcmp(op->packet, "CMML\0\0\0\0", 8) == 0) {
+        decoder->granuleshift = op->packet[28];
+      } else {
+        /* Missing ident header ... */
+        common->initialised |= -1;
+      }
+    } else if (common->num_header_packets == 2) {
+      /* CMML secondary header, with xml preamble and cmml tag */
+    } else if (common->num_header_packets == 1) {
+      /* CMML secondary header, head tag */
     }
+    
+    if (!(--common->num_header_packets))
+      common->initialised |= 1;
+
   } else {
-
+    /*
+     * Process the CMML stream content.
+     */
+      
     if (decoder->granuleshift > 0) {
       granulepos >>= decoder->granuleshift;
     }
 
     common->current_loc = granulepos * common->granuleperiod;
-    common->last_granulepos = granulepos;
 
-    oggplay_data_handle_cmml_data (&(decoder->decoder), op->packet, op->bytes);
+    ret = oggplay_data_handle_cmml_data (common, op->packet, op->bytes);
+    if (ret != E_OGGPLAY_CONTINUE) {
+      return OGGZ_ERR_OUT_OF_MEMORY;
+    }
   }
 
-  return 0;
+  return OGGZ_CONTINUE;
 
 }
 
 void
 oggplay_init_skel (void * user_data) {
 
   OggPlaySkeletonDecode * decoder = (OggPlaySkeletonDecode *)user_data;
 
@@ -271,20 +384,25 @@ static inline unsigned long extract_int3
 
 static inline ogg_int64_t extract_int64(unsigned char *data) {
   return ((ogg_int64_t)(extract_int32(data))) |
          (((ogg_int64_t)(extract_int32(data + 4))) << 32);
 }
 
 int
 oggplay_callback_skel (OGGZ * oggz, ogg_packet * op, long serialno,
-                void * user_data) {
+                       void * user_data) {
 
   OggPlaySkeletonDecode * decoder = (OggPlaySkeletonDecode *)user_data;
-
+  
+  /* check whether user_input is valid */
+  if (decoder == NULL) {
+    return OGGZ_STOP_ERR;
+  }
+  
   if (strncmp((char *)op->packet, "fishead", 7) == 0) {
     ogg_int64_t pt_num, pt_den, bt_num, bt_den;
 
     pt_num = extract_int64(op->packet + 12);
     pt_den = extract_int64(op->packet + 20);
     bt_num = extract_int64(op->packet + 28);
     bt_den = extract_int64(op->packet + 36);
 
@@ -296,40 +414,52 @@ oggplay_callback_skel (OGGZ * oggz, ogg_
     if (bt_den != 0) {
       decoder->base_time = OGGPLAY_TIME_INT_TO_FP(bt_num) / bt_den;
     } else {
       decoder->base_time = 0;
     }
 
     /* initialise the presentation times in the player to the values recorded in the skeleton */
     decoder->decoder.player->presentation_time = decoder->presentation_time;
+    
+    decoder->decoder.initialised = 1;
+    decoder->decoder.num_header_packets--;
   } else {
     int i;
     long          preroll       = extract_int32(op->packet + 44);
     long          serialno      = extract_int32(op->packet + 12);
+    OggPlay     * player        = decoder->decoder.player; 
     //ogg_int64_t   start_granule = extract_int64(op->packet + 36);
 
-    for (i = 1; i < decoder->decoder.player->num_tracks; i++) {
-      if (decoder->decoder.player->decode_data[i]->serialno == serialno) {
-        decoder->decoder.player->decode_data[i]->preroll = preroll;
+    for (i = 1; i < player->num_tracks; i++) {
+      if (player->decode_data[i]->serialno == serialno) {
+        player->decode_data[i]->preroll = preroll;
         break;
       }
     }
   }
 
-  return 0;
+  return OGGZ_CONTINUE;
 
 }
 
 int
 oggplay_fish_sound_callback_floats(FishSound * fsound, float ** pcm, 
-                                          long frames, void *user_data) {
+                                   long frames, void *user_data) {
+
+  OggPlayAudioDecode  * decoder = (OggPlayAudioDecode *)user_data;
+  OggPlayDecode       * common = NULL;  
 
-  OggPlayAudioDecode *decoder = (OggPlayAudioDecode *)user_data;
-  OggPlayDecode *common = &(decoder->decoder);
+  if (decoder == NULL) {
+    return FISH_SOUND_STOP_ERR;
+  }
+  
+  if ((common = &(decoder->decoder)) == NULL) {
+    return FISH_SOUND_STOP_ERR;
+  }
 
   /*
    * calculate the current location here so that it's only updated when
    * audio data is actually available for processing
    */
   if (common->last_granulepos > 0) {
     common->current_loc = common->last_granulepos * common->granuleperiod;
   } else {
@@ -338,114 +468,161 @@ oggplay_fish_sound_callback_floats(FishS
 
   if
   (
     (common->current_loc == -1)
     ||
     (common->current_loc >= common->player->presentation_time)
   )
   {
-
-
     /*
      * store the frame
      */
-    oggplay_data_handle_audio_data(&(decoder->decoder), (short *)pcm, frames,
-              sizeof(float));
+    oggplay_data_handle_audio_data(common, (short *)pcm, 
+                                   frames, sizeof(float));
 
-      return FISH_SOUND_STOP_ERR;
+    return FISH_SOUND_STOP_ERR;
   }
 
   return FISH_SOUND_CONTINUE;
 }
 
 void
 oggplay_init_audio (void * user_data) {
 
   OggPlayAudioDecode  * decoder = (OggPlayAudioDecode *)user_data;
+  
+  if (decoder == NULL) {
+    return;
+  }
 
   decoder->sound_handle = fish_sound_new(FISH_SOUND_DECODE,
-                                                      &(decoder->sound_info));
+                                         &(decoder->sound_info));
 
+	if (decoder->sound_handle == NULL) {
+    return;
+	}
+		
   decoder->sound_info.channels = 0;
-  fish_sound_set_interleave(decoder->sound_handle, 1);
   fish_sound_set_decoded_float_ilv(decoder->sound_handle,
-                                      oggplay_fish_sound_callback_floats,
-                                      (void *)decoder);
+                                   oggplay_fish_sound_callback_floats,
+                                   (void *)decoder);
 
   decoder->decoder.decoded_type = OGGPLAY_FLOATS_AUDIO;
-  decoder->decoder.player->active_tracks++;
 }
 
 void
 oggplay_shutdown_audio(void *user_data) {
 
   OggPlayAudioDecode   * decoder = (OggPlayAudioDecode *)user_data;
-
+  
+  if (decoder == NULL) {
+    return;
+  }
+  
   fish_sound_delete(decoder->sound_handle);
 
 }
 
 int
 oggplay_callback_audio (OGGZ * oggz, ogg_packet * op, long serialno,
-                void * user_data) {
+                        void * user_data) {
 
   OggPlayAudioDecode   * decoder     = (OggPlayAudioDecode *)user_data;
-  OggPlayDecode        * common      = &(decoder->decoder);
+  OggPlayDecode        * common      = NULL;
   ogg_int64_t            granulepos  = oggz_tell_granulepos(oggz);
+  long                   bytes_read;
 
-  if (granulepos > 0 && (!decoder->decoder.active)) {
-    return 0;
+  /* check user input (user_data) */
+  if (decoder == NULL) {
+    return OGGZ_STOP_ERR;
+  }
+  
+  if ((common = &(decoder->decoder)) == NULL) {
+    return OGGZ_STOP_ERR;
   }
-
+  
+  if (granulepos > 0 && (!common->active)) {
+    return OGGZ_CONTINUE;
+  }
+  
+  if ((granulepos > 0) && (common->last_granulepos > granulepos)) {
+    return OGGZ_CONTINUE;
+  }
+  
+  /* Blindly register that we've processed a header packet. */
+  if (common->num_header_packets) --common->num_header_packets;
+  
   common->last_granulepos = granulepos;
 
-  fish_sound_prepare_truncation (decoder->sound_handle, op->granulepos,
-                                                                op->e_o_s);
-  if (fish_sound_decode (decoder->sound_handle, op->packet, op->bytes) == -1) {
-    // Unrecoverable error, disable track
-    op->e_o_s = 1;
-    common->active = 0;
-    common->player->active_tracks--;
-    return OGGZ_ERR_HOLE_IN_DATA;
+  fish_sound_prepare_truncation (decoder->sound_handle, op->granulepos, 
+                                 op->e_o_s);
+  
+  bytes_read = fish_sound_decode (decoder->sound_handle, op->packet, op->bytes);
+  switch (bytes_read) {
+    case FISH_SOUND_ERR_OUT_OF_MEMORY:
+      /* we ran out of memory... stop decoding. */
+      return OGGZ_ERR_OUT_OF_MEMORY;
+      
+    case FISH_SOUND_ERR_GENERIC:
+    {
+      /* 
+       * error occured while decoding the audio track 
+       * disable the track, but if there are other tracks to decode
+       * contine decoding...
+       */
+      
+      common->active = 0;
+      
+      if (common->player->active_tracks) common->player->active_tracks--;
+      if (common->num_header_packets >= 0) common->initialised |= -1;
+
+      return OGGZ_CONTINUE;
+    }
+    
+    default:
+      /* there was no problem with decoding */
+      if (!common->num_header_packets) common->initialised |= 1;
+      break;
   }
 
   if (decoder->sound_info.channels == 0) {
     fish_sound_command(decoder->sound_handle, FISH_SOUND_GET_INFO,
-                    &(decoder->sound_info), sizeof(FishSoundInfo));
+                       &(decoder->sound_info), sizeof(FishSoundInfo));
   }
 
   if (op->e_o_s) {
     common->active = 0;
     common->player->active_tracks--;
   }
 
-  return 0;
+  return OGGZ_CONTINUE;
 }
 
 void
 oggplay_init_kate(void *user_data) {
 
 #ifdef HAVE_KATE
   int ret;
   OggPlayKateDecode   * decoder     = (OggPlayKateDecode *)user_data;
 
-  decoder->init = 0;
-  ret = kate_high_decode_init(&(decoder->k));
-  if (ret < 0) {
-    /* what to do ? */
+  if (decoder == NULL) {
+    return;
   }
-  else {
-    decoder->init = 1;
-  }
+  
   decoder->decoder.decoded_type = OGGPLAY_KATE;
+  kate_info_init (&(decoder->k_info));
+  kate_comment_init (&(decoder->k_comment));
 
 #ifdef HAVE_TIGER
   decoder->use_tiger = 1;
   decoder->overlay_dest = -1;
+  decoder->swap_rgb = 0;
+  decoder->default_width = -1;
+  decoder->default_height = -1;
 
   ret = tiger_renderer_create(&(decoder->tr));
   if (ret < 0) {
     /* what to do ? */
     decoder->tr = NULL;
   }
   if (decoder->use_tiger) {
     decoder->decoder.decoded_type = OGGPLAY_RGBA_VIDEO;
@@ -455,112 +632,174 @@ oggplay_init_kate(void *user_data) {
 #endif
 }
 
 void
 oggplay_shutdown_kate(void *user_data) {
 
 #ifdef HAVE_KATE
   OggPlayKateDecode   * decoder = (OggPlayKateDecode *)user_data;
-
+  
+  if (decoder == NULL) {
+    return;
+  }
 #ifdef HAVE_TIGER
   if (decoder->tr) {
     tiger_renderer_destroy(decoder->tr);
   }
 #endif
 
-  if (decoder->init) {
-    kate_high_decode_clear(&(decoder->k));
+  if (decoder->decoder.initialised == 1) {
+    kate_clear (&(decoder->k_state));
   }
+  
+  kate_info_clear (&(decoder->k_info));
+  kate_comment_clear (&(decoder->k_comment));
+  
 #endif
 }
 
 int
 oggplay_callback_kate (OGGZ * oggz, ogg_packet * op, long serialno,
-                void * user_data) {
+                       void * user_data) {
 
 #ifdef HAVE_KATE
   OggPlayKateDecode     * decoder     = (OggPlayKateDecode *)user_data;
-  OggPlayDecode         * common      = &(decoder->decoder);
+  OggPlayDecode         * common      = NULL;
   ogg_int64_t             granulepos  = oggz_tell_granulepos(oggz);
   int                     granuleshift;
   ogg_int64_t             base, offset;
   kate_packet kp;
   const kate_event *ev = NULL;
   int ret;
 
-  if (!decoder->init) {
-    return E_OGGPLAY_UNINITIALISED;
+  /*
+   * Basic error checking.
+   */
+  if (decoder == NULL) {
+    return OGGZ_STOP_ERR;
   }
+  
+  if ((common = &(decoder->decoder)) == NULL) {
+    return OGGZ_STOP_ERR;
+  } 
+
+  /*
+   * Stop processing the Ogg packet if the stream is not active.
+   */
+  if (!common->active) {
+    return OGGZ_CONTINUE;
+  }
+  
+  /* create a kate_packet from the received ogg_packet */
+  kate_packet_wrap (&kp, op->bytes, op->packet);
+
+  /* 
+   * Decode the headers of the kate stream.
+   */
+  if (common->num_header_packets) {
+    ret = kate_decode_headerin (&(decoder->k_info), &(decoder->k_comment), &kp);
 
-  kate_packet_wrap(&kp, op->bytes, op->packet);
-  ret = kate_high_decode_packetin(&(decoder->k), &kp, &ev);
+    if (ret == KATE_E_OUT_OF_MEMORY) {
+      return OGGZ_ERR_OUT_OF_MEMORY;
+    }
+    
+    common->initialised |= (ret < 0 ? -1 : ret);
+    common->num_header_packets--;
+        
+    /* if we _successfully_ processed all the headers initialise the decoder */
+    if (!common->num_header_packets && (common->initialised == 1)) {
+      ret = kate_decode_init (&(decoder->k_state), &(decoder->k_info));
+      
+      if (ret == KATE_E_OUT_OF_MEMORY) {
+        return OGGZ_ERR_OUT_OF_MEMORY;
+      } else if (ret < 0) {
+        common->initialised |= -1;
+      }
+    }
+    
+    return OGGZ_CONTINUE;
+  } 
+    
+  /*
+   * Decode the payload of the stream.
+   */
+   
+  ret = kate_decode_packetin (&(decoder->k_state), &kp);
+  if (ret == KATE_E_OUT_OF_MEMORY) {
+    return OGGZ_ERR_OUT_OF_MEMORY;
+  } else if (ret < 0){
+    return OGGZ_CONTINUE;
+  }
+  
+  ret = kate_decode_eventout (&(decoder->k_state), &ev);
   if (ret < 0) {
-    return E_OGGPLAY_BAD_INPUT;
+    return OGGZ_CONTINUE;
   }
-
+  
   if (granulepos != -1) {
     granuleshift = oggz_get_granuleshift(oggz, serialno);
     base = (granulepos >> granuleshift);
     offset = granulepos - (base << granuleshift);
     common->current_loc = (base+offset) * common->granuleperiod;
-    common->last_granulepos = granulepos;
   } else {
     common->current_loc = -1;
   }
 
   if
   (
     (common->current_loc == -1)
     ||
     (common->current_loc >= common->player->presentation_time)
   )
   {
     /*
      * process the data from the packet
      * */
     if (ev) {
-      oggplay_data_handle_kate_data(decoder, ev);
+      if (oggplay_data_handle_kate_data(decoder, ev) != E_OGGPLAY_CONTINUE) {
+        return OGGZ_ERR_OUT_OF_MEMORY;
+      }
     }
   }
 
   if (op->e_o_s) {
     common->active = 0;
   }
 
 #endif
 
-  return 0;
+  return OGGZ_CONTINUE;
 
 }
 
 OggPlayCallbackFunctions callbacks[] = {
   {oggplay_init_theora, oggplay_callback_theora, oggplay_shutdown_theora,
         sizeof(OggPlayTheoraDecode)},        /* THEORA */
   {oggplay_init_audio, oggplay_callback_audio, oggplay_shutdown_audio,
         sizeof(OggPlayAudioDecode)},         /* VORBIS */
   {oggplay_init_audio, oggplay_callback_audio, oggplay_shutdown_audio,
         sizeof(OggPlayAudioDecode)},         /* SPEEX */
   {NULL, NULL, NULL, sizeof(OggPlayDecode)}, /* PCM */
-  {oggplay_init_cmml, oggplay_callback_cmml, NULL, sizeof(OggPlayCmmlDecode)},
+  {oggplay_init_cmml, oggplay_callback_cmml, NULL, sizeof(OggPlayCmmlDecode)}, /* CMML */
   {NULL, NULL, NULL, sizeof(OggPlayDecode)}, /* ANX2 */
   {oggplay_init_skel, oggplay_callback_skel, NULL,
-        sizeof(OggPlaySkeletonDecode)},
+        sizeof(OggPlaySkeletonDecode)},      /* SKELETON */
   {NULL, NULL, NULL, sizeof(OggPlayDecode)}, /* FLAC0 */
   {NULL, NULL, NULL, sizeof(OggPlayDecode)}, /* FLAC */
   {NULL, NULL, NULL, sizeof(OggPlayDecode)}, /* ANXDATA */
   {NULL, NULL, NULL, sizeof(OggPlayDecode)}, /* CELT */
   {oggplay_init_kate, oggplay_callback_kate, oggplay_shutdown_kate,
         sizeof(OggPlayKateDecode)},          /* KATE */
   {NULL, NULL, NULL, sizeof(OggPlayDecode)}, /* DIRAC */
   {NULL, NULL, NULL, sizeof(OggPlayDecode)}  /* UNKNOWN */
 };
 
 OggPlayDecode *
-oggplay_initialise_decoder(OggPlay *me, int content_type, int serialno) {
+oggplay_initialise_decoder(OggPlay *me, int content_type, long serialno) {
 
   ogg_int64_t    num;
   ogg_int64_t    denom;
   OggPlayDecode *decoder = NULL;
 
   if (me == NULL)
     return NULL;
 
@@ -572,27 +811,29 @@ oggplay_initialise_decoder(OggPlay *me, 
   decoder->serialno = serialno;
   decoder->content_type = content_type;
   decoder->content_type_name =
           oggz_stream_get_content_type (me->oggz, serialno);
   decoder->active = 1;
   decoder->final_granulepos = -1;
   decoder->player = me;
   decoder->decoded_type = OGGPLAY_TYPE_UNKNOWN;
+  decoder->num_header_packets = 
+          oggz_stream_get_numheaders (me->oggz, serialno);
 
   /*
    * set the StreamInfo to unitialised until we get some real data in
    */
   decoder->stream_info = OGGPLAY_STREAM_UNINITIALISED;
 
   /*
    * set to -1 until headers decoded
    */
   decoder->current_loc = -1;
-  decoder->last_granulepos = -1;
+  decoder->last_granulepos = 0;
 
   /*
    * the offset is how far advanced or delayed this track is to the "standard"
    * time position.  An offset of 1000, for example, indicates that data for
    * this track arrives 1 second in advance of data for other tracks
    */
   decoder->offset = 0;
 
@@ -601,33 +842,40 @@ oggplay_initialise_decoder(OggPlay *me, 
   /*
    * convert num and denom to a 32.32 fixed point value
    */
   if (num != 0) {
     decoder->granuleperiod = OGGPLAY_TIME_INT_TO_FP(denom) / num;
   } else {
     decoder->granuleperiod = 0;
   }
-
+  
   if (callbacks[content_type].init != NULL) {
     callbacks[content_type].init(decoder);
+    decoder->initialised = 0;
+  } else {
+    decoder->initialised = -1;
   }
 
   oggplay_data_initialise_list(decoder);
 
   return decoder;
 }
 
 
 /*
  * this function needs to be called on each track to clear up allocated memory
  */
 void
 oggplay_callback_shutdown(OggPlayDecode *decoder) {
-
+  
+  if (decoder == NULL) {
+    return;
+  }
+  
   if (callbacks[decoder->content_type].shutdown != NULL) {
     callbacks[decoder->content_type].shutdown(decoder);
   }
 
   oggplay_data_shutdown_list(decoder);
 
   oggplay_free(decoder);
 }
@@ -635,88 +883,117 @@ oggplay_callback_shutdown(OggPlayDecode 
 
 /*
  * this is the callback that is used before all track types have been
  * determined - i.e. at the beginning of an ogg bitstream or at the start
  * of a new chain
  */
 int
 oggplay_callback_predetected (OGGZ *oggz, ogg_packet *op, long serialno,
-                void *user_data) {
+                              void *user_data) {
 
-  OggPlay     * me;
+  OggPlay     * me            = (OggPlay *)user_data;
   int           i;
   int           content_type  = 0;
-
-  me = (OggPlay *)user_data;
+  int           ret           = OGGZ_CONTINUE;
+  short         new_stream    = 1;
+  short         read_more     = 0;
+  ogg_int64_t   granulepos    = oggz_tell_granulepos(oggz);
+  
+  if (me == NULL) {
+    return OGGZ_STOP_ERR;
+  }
+  
   content_type = oggz_stream_get_content (me->oggz, serialno);
-
-  /*
-   * if we encounter a serialno for the second time, then we've reached the
-   * end of the b_o_s packets
-   */
+  
   for (i = 0; i < me->num_tracks; i++) {
     if (serialno == me->decode_data[i]->serialno) {
-      int ret = 0;
-      
       /*
        * call appropriate callback
        */
       if (callbacks[content_type].callback != NULL) {
         ret = callbacks[content_type].callback(oggz, op, serialno,
                                                me->decode_data[i]);
       }
-
-      if 
-      (
-        (op->granulepos >= 0) 
-        ||
-        (op->granulepos == -1 && me->decode_data[i]->last_granulepos != -1)
-      )
-      {
-        /*
-         * set up all the other callbacks
-         */
-        for (i = 0; i < me->num_tracks; i++) {
-          serialno = me->decode_data[i]->serialno;
-          content_type = oggz_stream_get_content (me->oggz, serialno);
-          oggz_set_read_callback(me->oggz, serialno,
-                          callbacks[content_type].callback, me->decode_data[i]);
-        }
-
-        /*
-         * destroy this callback
-         */
-        oggz_set_read_callback (me->oggz, -1, NULL, NULL);
-        me->all_tracks_initialised = 1;
-      }
-
-      return ret < 0 ? OGGZ_ERR_HOLE_IN_DATA : ret;
+      
+      new_stream = 0;
     }
+    
+    /* a track that hasn't got all it's headers, but others are already having
+     * valueable data. A badly multiplexed Ogg file, as the specification
+     * requires that all headers has to be before any data comes.
+     * Instead of marking the whole file as a bad one, try to decode
+     * the streams, which headers are successfully decoded.
+     * and disable the tracks that haven't got enough header info.
+     */
+    if (granulepos && me->decode_data[i]->num_header_packets) {
+      me->decode_data[i]->initialised = -1;
+    }
+    
+    /* 
+     * check whether there is a stream that has not
+     * decoded all it's headers
+     */
+    read_more |= (me->decode_data[i]->num_header_packets && (me->decode_data[i]->initialised != -1));
   }
 
-  me->callback_info = oggplay_realloc (me->callback_info,
-                  sizeof (OggPlayCallbackInfo) * ++me->num_tracks);
-  if (me->callback_info == NULL)
-    return -1;
+  if (new_stream) {
+    /* check for possible overflow ... */
+    if 
+    (
+      (++me->num_tracks <= 0)
+      ||
+      (OGGPLAY_TYPE_MAX(size_t)/(me->num_tracks) < sizeof(OggPlayCallbackInfo))
+      ||
+      (OGGPLAY_TYPE_MAX(size_t)/me->num_tracks < sizeof(long))
+    ) 
+    {
+      return OGGZ_STOP_ERR;
+    }
+  
+    me->callback_info = oggplay_realloc (me->callback_info,
+                    sizeof (OggPlayCallbackInfo) * me->num_tracks);
+    if (me->callback_info == NULL)
+      return OGGZ_ERR_OUT_OF_MEMORY;
 
-  me->decode_data = oggplay_realloc (me->decode_data, sizeof (long) * me->num_tracks);
-  if (me->decode_data == NULL)
-    return -1;
+    me->decode_data = oggplay_realloc (me->decode_data, 
+                                       sizeof (long) * me->num_tracks);
+    if (me->decode_data == NULL)
+      return OGGZ_ERR_OUT_OF_MEMORY;
 
-  me->decode_data[me->num_tracks - 1] = oggplay_initialise_decoder(me,
-                                                      content_type, serialno);
-  if (me->decode_data[me->num_tracks - 1] == NULL)
-    return -1; 
+    me->decode_data[me->num_tracks - 1] = 
+        oggplay_initialise_decoder(me, content_type, serialno);
+    if (me->decode_data[me->num_tracks - 1] == NULL)
+      return OGGZ_ERR_OUT_OF_MEMORY; 
 
-  /*me->decode_data->callback_info = me->callback_info + (me->num_tracks - 1);*/
-
-  /*
-   * call appropriate callback
-   */
-  if (callbacks[content_type].callback != NULL) {
-    return callbacks[content_type].callback(oggz, op, serialno,
-                                            me->decode_data[me->num_tracks - 1]);
+    /*
+     * call appropriate callback
+     */
+    if (callbacks[content_type].callback != NULL) {
+      ret = callbacks[content_type].callback(oggz, op, serialno,
+                                             me->decode_data[me->num_tracks - 1]);
+    }
+  } else if (!read_more) {
+    /* 
+     * all tracks' headers has been processed 
+     * initialisation phase done, process the payloads.
+     */
+    me->all_tracks_initialised = 1;
+    
+    /* set up all the callbacks for the detected streams */
+    for (i = 0; i < me->num_tracks; i++) {
+      serialno = me->decode_data[i]->serialno;
+      content_type = oggz_stream_get_content (me->oggz, serialno);
+      if (oggz_set_read_callback (me->oggz, serialno, 
+                                  callbacks[content_type].callback, 
+                                  me->decode_data[i]) != 0)
+      {
+        return OGGZ_STOP_ERR;
+      }
+    }
+    
+    /* disable the callback for unforeseen streams */
+    oggz_set_read_callback (me->oggz, -1, NULL, NULL);
   }
-
-  return 0;
-
+  
+  /* read the header part of the ogg content in a packet-by-packet manner */
+  return ((ret < 0) ? ret : OGGZ_STOP_OK);
 }
--- a/media/liboggplay/src/liboggplay/oggplay_callback.h
+++ b/media/liboggplay/src/liboggplay/oggplay_callback.h
@@ -52,17 +52,17 @@ oggplay_process_leftover_packet(OggPlay 
  *
  * @param me OggPlay 
  * @param content_type 
  * @param serialno
  * @return A new OggPlayDecode handle
  * @retval NULL in case of error.
  */
 OggPlayDecode *
-oggplay_initialise_decoder(OggPlay *me, int content_type, int serialno);
+oggplay_initialise_decoder(OggPlay *me, int content_type, long serialno);
 
 int
 oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info);
 
 void
 oggplay_callback_info_destroy(OggPlay *me, OggPlayCallbackInfo **info);
 
 void
--- a/media/liboggplay/src/liboggplay/oggplay_callback_info.c
+++ b/media/liboggplay/src/liboggplay/oggplay_callback_info.c
@@ -35,41 +35,54 @@
  * 
  * Shane Stephens <shane.stephens@annodex.net>
  */
 #include "oggplay_private.h"
 #include <stdlib.h>
 
 extern void _print_list(char *name, OggPlayDataHeader *p);
 
+static void
+clear_callback_info (OggPlay *me, OggPlayCallbackInfo ***info) {
+  int i;
+  
+  for (i = 0; i < me->num_tracks; ++i) {
+    if (((*info)[i] != NULL) && ((*info)[i]->records != NULL)) {
+        oggplay_free ((*info)[i]->records);
+    }
+  }
+  oggplay_free (*info);
+  *info = NULL;
+}
+
 int
 oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info) {
 
   int i;
   int tcount = 0;
   
   int         added_required_record   = me->num_tracks;
   ogg_int64_t diff;
   ogg_int64_t latest_first_record     = 0x0LL;
   //ogg_int64_t lpt = 0;
  
   /*
    * allocate the structure for return to the user
    */
   (*info) = oggplay_calloc (me->num_tracks, sizeof (OggPlayCallbackInfo *));
   if ((*info) == NULL)
-    return -1;
-
+    return E_OGGPLAY_OUT_OF_MEMORY;
+  
   /*
    * fill in each active track.  Leave gaps for inactive tracks.
    */
   for (i = 0; i < me->num_tracks; i++) {
     OggPlayDecode       * track = me->decode_data[i];
     OggPlayCallbackInfo * track_info = me->callback_info + i;
-    int                   count = 0;
+    size_t                count = 0;
     OggPlayDataHeader   * p;
     OggPlayDataHeader   * q = NULL;
     
     (*info)[i] = track_info;
 
 #ifdef HAVE_TIGER
     /* not so nice to have this here, but the tiger_renderer needs updating regularly
      * as some items may be animated, so would yield data without the stream actually
@@ -105,17 +118,28 @@ oggplay_callback_info_prepare(OggPlay *m
      * find the first not presented packet of data, count the total number that
      * have not been presented
      */
     for (p = track->data_list; p != NULL; p = p->next) {
       if (!p->has_been_presented) {
         if (q == NULL) {
           q = p;
         }
-        count++;
+        
+        /* check for overflow */
+        if 
+        (
+          oggplay_check_add_overflow (count, 1, &count)
+          == 
+          E_OGGPLAY_TYPE_OVERFLOW
+        )
+        {
+          clear_callback_info (me, info);
+          return E_OGGPLAY_TYPE_OVERFLOW;
+        }
       }
     }
   
     /*
      * tcount is set if any of the tracks have unpresented data
      */
     if (count > 0) {
       tcount = 1;
@@ -139,28 +163,27 @@ oggplay_callback_info_prepare(OggPlay *m
         track_info->stream_info = OGGPLAY_STREAM_LAST_DATA;
       } else {
         track_info->stream_info = track->stream_info;
       }
 
     } else {
       track_info->stream_info = OGGPLAY_STREAM_UNINITIALISED;
     }
-   
+
+    if ((count+1) < count) {
+      clear_callback_info (me, info);
+      return E_OGGPLAY_TYPE_OVERFLOW;
+    }
     /* null-terminate the record list for the python interface */
-    track_info->records = oggplay_calloc ((count + 1), sizeof (OggPlayDataHeader *));
-    if (track_info->records == NULL)
-    {
-      for (i = 0; i < me->num_tracks; i++) {
-        if ((*info)[i]->records != NULL) 
-          oggplay_free ((*info)[i]->records);
-      }
-      oggplay_free (*info);
-      *info = NULL;
-      return -1;
+    track_info->records = 
+      oggplay_calloc ((count+1), sizeof (OggPlayDataHeader *));
+    if (track_info->records == NULL) {
+      clear_callback_info (me, info);
+      return E_OGGPLAY_OUT_OF_MEMORY;
     }
 
     track_info->records[count] = NULL;
 
     track_info->available_records = count;
     track_info->required_records = 0;
 
     track_info->data_type = track->decoded_type;
@@ -245,17 +268,17 @@ oggplay_callback_info_prepare(OggPlay *m
         track->active == 1
         && 
         me->pt_update_valid
       )
     ) {
       added_required_record --;
     }
 
-  }
+  } /* end of for loop, that fills each track */
  
    me->pt_update_valid = 0;
     
   //printf("\n");
 
   /*
    * there are no required records!  This means that we need to advance the
    * target to the period before the first actual record - the bitstream has
@@ -430,17 +453,16 @@ oggplay_callback_info_unlock_item(OggPla
 
 long
 oggplay_callback_info_get_presentation_time(OggPlayDataHeader *header) {
 
   if (header == NULL) {
     return -1;
   }
 
-  /* SGS: is this correct? */
   return OGGPLAY_TIME_FP_TO_INT(header->presentation_time);
 }
 
 OggPlayVideoData *
 oggplay_callback_info_get_video_data(OggPlayDataHeader *header) {
 
   if (header == NULL) {
     return NULL;
--- a/media/liboggplay/src/liboggplay/oggplay_data.c
+++ b/media/liboggplay/src/liboggplay/oggplay_data.c
@@ -65,27 +65,35 @@
  * (a) early consumption by user (user calls oggplay_mark_record_consumed)
  * (b) frame locking by user (user calls oggplay_mark_record_locked) and
  *     subsequent unlocking (user calls oggplay_mark_record_consumed)
  */
 
 void
 oggplay_data_initialise_list (OggPlayDecode *decode) {
 
+  if (decode == NULL) {
+    return;
+  }
+  
   decode->data_list = decode->end_of_data_list = NULL;
   decode->untimed_data_list = NULL;
 
 }
 
 /*
  * helper function to append data packets to end of data_list
  */
 void
 oggplay_data_add_to_list_end(OggPlayDecode *decode, OggPlayDataHeader *data) {
 
+  if (decode == NULL) {
+    return;
+  }
+  
   data->next = NULL;
 
   if (decode->data_list == NULL) {
     decode->data_list = data;
     decode->end_of_data_list = data;
   } else {
     decode->end_of_data_list->next = data;
     decode->end_of_data_list = data;
@@ -93,46 +101,54 @@ oggplay_data_add_to_list_end(OggPlayDeco
 
 }
 
 /*
  * helper function to append data packets to front of data_list
  */
 void
 oggplay_data_add_to_list_front(OggPlayDecode *decode, OggPlayDataHeader *data) {
+  if (decode == NULL) {
+    return;
+  }
+  
   if (decode->data_list == NULL) {
     decode->data_list = decode->end_of_data_list = data;
     data->next = NULL;
   } else {
     data->next = decode->data_list;
     decode->data_list = data;
   }
 }
 
 void
 _print_list(char *name, OggPlayDataHeader *p) {
     printf("%s: ", name);
     for (; p != NULL; p = p->next) {
-      printf("%"PRId64"[%d]", p->presentation_time >> 32, p->lock);
+      printf("%"PRId64"[%d]", OGGPLAY_TIME_FP_TO_INT (p->presentation_time), p->lock);
       if (p->next != NULL) printf("->");
     }
     printf("\n");
 }
 
 
 void
 oggplay_data_add_to_list (OggPlayDecode *decode, OggPlayDataHeader *data) {
 
   /*
    * if this is a packet with an unknown display time, prepend it to
    * the untimed_data_list for later timestamping.
    */
 
   ogg_int64_t samples_in_next_in_list;
 
+  if ((decode == NULL) || (data == NULL)) {
+    return;
+  }
+
   //_print_list("before", decode->data_list);
   //_print_list("untimed before", decode->untimed_data_list);
 
   if (data->presentation_time == -1) {
     data->next = decode->untimed_data_list;
     decode->untimed_data_list = data;
   } else {
     /*
@@ -189,34 +205,44 @@ oggplay_data_free_list(OggPlayDataHeader
     list = list->next;
     oggplay_free(p);
   }
 }
 
 void
 oggplay_data_shutdown_list (OggPlayDecode *decode) {
 
+  if (decode == NULL) {
+    return;
+  }
+  
   oggplay_data_free_list(decode->data_list);
   oggplay_data_free_list(decode->untimed_data_list);
 
 }
 
 /*
  * this function removes any displayed, unlocked frames from the list.
  *
  * this function also removes any undisplayed frames that are before the
  * global presentation time.
  */
 void
 oggplay_data_clean_list (OggPlayDecode *decode) {
 
-  ogg_int64_t         target = decode->player->target;
-  OggPlayDataHeader * header = decode->data_list;
+  ogg_int64_t         target;
+  OggPlayDataHeader * header = NULL;
   OggPlayDataHeader * p      = NULL;
-
+  
+  if (decode == NULL) {
+    return;
+  }
+  header = decode->data_list;
+  target = decode->player->target;
+  
   while (header != NULL) {
     if
     (
       header->lock == 0
       &&
       (
         (
           (header->presentation_time < (target + decode->offset))
@@ -247,79 +273,131 @@ oggplay_data_clean_list (OggPlayDecode *
     } else {
       p = header;
       header = header->next;
     }
   }
 }
 
 void
-oggplay_data_initialise_header (OggPlayDecode *decode,
-                OggPlayDataHeader *header) {
+oggplay_data_initialise_header (const OggPlayDecode *decode,
+                                OggPlayDataHeader *header) {
+  
+  if ((decode == NULL) || (header == NULL)) {
+    return;
+  }
+  
   /*
    * the frame is not cleaned until its presentation time has passed.  We'll
    * check presentation times in oggplay_data_clean_list.
    */
   header->lock = 0;
   header->next = NULL;
   header->presentation_time = decode->current_loc;
   header->has_been_presented = 0;
-
 }
 
-void
+OggPlayErrorCode
 oggplay_data_handle_audio_data (OggPlayDecode *decode, void *data,
-      int samples, int samplesize) {
+                                long samples, size_t samplesize) {
 
-  int                   num_channels;
+  int                   num_channels, ret;
+  size_t                record_size = sizeof(OggPlayAudioRecord);
+  long                  samples_size;
   OggPlayAudioRecord  * record = NULL;
 
   num_channels = ((OggPlayAudioDecode *)decode)->sound_info.channels;
-  record = (OggPlayAudioRecord*)oggplay_calloc(sizeof(OggPlayAudioRecord) +
-                  samples * samplesize * num_channels, 1);
+  
+  /* check for possible integer overflows....*/
+  if ((samples < 0) || (num_channels < 0)) {
+    return E_OGGPLAY_TYPE_OVERFLOW;
+  }
+
+  ret = oggplay_mul_signed_overflow (samples, num_channels, &samples_size);
+  if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+    return ret;
+  }
 
-  if (record == NULL)
-    return;
+  ret = oggplay_mul_signed_overflow (samples_size, samplesize, &samples_size);
+  if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+    return ret;
+  }
 
+  ret = oggplay_check_add_overflow (record_size, samples_size, &record_size);
+  if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+    return ret;
+  }
+
+  /* try to allocate the memory for the record */
+  record = (OggPlayAudioRecord*)oggplay_calloc(record_size, 1);
+  if (record == NULL) {
+    return E_OGGPLAY_OUT_OF_MEMORY;
+  }
+
+  /* initialise the header of OggPlayAudioRecord struct */
   oggplay_data_initialise_header(decode, &(record->header));
 
   record->header.samples_in_record = samples;
 
   record->data = (void *)(record + 1);
-
-  memcpy(record->data, data, samples * samplesize * num_channels);
+  
+  /* copy the received data - the header has been initialised! */
+  memcpy (record->data, data, samples_size);
   /*
   printf("[%f%f%f]\n", ((float *)record->data)[0], ((float *)record->data)[1],
                     ((float *)record->data)[2]);
   */
   oggplay_data_add_to_list(decode, &(record->header));
+  
+  return E_OGGPLAY_CONTINUE;
 }
 
-void
-oggplay_data_handle_cmml_data(OggPlayDecode *decode, unsigned char *data,
-                int size) {
+OggPlayErrorCode
+oggplay_data_handle_cmml_data(OggPlayDecode *decode, 
+                              unsigned char *data, 
+                              long size) {
 
   OggPlayTextRecord * record = NULL;
-
-  record =
-      (OggPlayTextRecord*)oggplay_calloc (sizeof(OggPlayTextRecord) + size + 1, 1);
+  size_t              record_size = sizeof(OggPlayTextRecord);
 
-  if (record == NULL)
-    return;
+  /* check that the size we want to allocate doesn't overflow */
+  if ((size < 0) || (size+1 < 0)) {
+    return E_OGGPLAY_TYPE_OVERFLOW;
+  }
+  size += 1;
+  
+  if 
+  (
+    oggplay_check_add_overflow (record_size, size, &record_size)
+    == 
+    E_OGGPLAY_TYPE_OVERFLOW
+  ) 
+  {
+    return E_OGGPLAY_TYPE_OVERFLOW;
+  }
+  
+  /* allocate the memory for the record */
+  record = (OggPlayTextRecord*)oggplay_calloc (record_size, 1);
+  if (record == NULL) {
+    return E_OGGPLAY_OUT_OF_MEMORY;
+  }
 
+  /* initialise the record's header */
   oggplay_data_initialise_header(decode, &(record->header));
 
   record->header.samples_in_record = 1;
   record->data = (char *)(record + 1);
 
+  /* copy the data */
   memcpy(record->data, data, size);
   record->data[size] = '\0';
 
   oggplay_data_add_to_list(decode, &(record->header));
 
+  return E_OGGPLAY_CONTINUE;
 }
 
 static int
 get_uv_offset(OggPlayTheoraDecode *decode, yuv_buffer *buffer)
 {
   int xo=0, yo = 0;
   if (decode->y_width != 0 &&
       decode->uv_width != 0 &&
@@ -329,68 +407,95 @@ get_uv_offset(OggPlayTheoraDecode *decod
   if (decode->y_height != 0 &&
       decode->uv_height != 0 &&
       decode->y_height/decode->uv_height != 0) {
     yo = (buffer->uv_stride)*(decode->video_info.offset_y/(decode->y_height/decode->uv_height));
   }
   return xo + yo;
 }
 
-void
+int
 oggplay_data_handle_theora_frame (OggPlayTheoraDecode *decode,
-                                    yuv_buffer *buffer) {
+                                  const yuv_buffer *buffer) {
 
-  int                   size = sizeof (OggPlayVideoRecord);
-  int                   i;
-  int                   uv_offset;
+  size_t                size = sizeof (OggPlayVideoRecord);
+  int                   i, ret;
+  long                  y_size, uv_size, y_offset, uv_offset;
   unsigned char       * p;
   unsigned char       * q;
   unsigned char       * p2;
   unsigned char       * q2;
   OggPlayVideoRecord  * record;
   OggPlayVideoData    * data;
 
+  /* check for possible integer overflows */
+  ret = 
+    oggplay_mul_signed_overflow (buffer->y_height, buffer->y_stride, &y_size);
+  if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+    return ret;
+  }
+
+  ret = 
+    oggplay_mul_signed_overflow (buffer->uv_height, buffer->uv_stride, &uv_size);
+  if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+    return ret;
+  }
+
+  ret = oggplay_mul_signed_overflow (uv_size, 2, &uv_size);
+  if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+    return ret;
+  }
+
   if (buffer->y_stride < 0) {
-    size -= buffer->y_stride * buffer->y_height;
-    size -= buffer->uv_stride * buffer->uv_height * 2;
-  } else {
-    size += buffer->y_stride * buffer->y_height;
-    size += buffer->uv_stride * buffer->uv_height * 2;
+    y_size  *= -1;
+    uv_size *= -1;
+  }
+
+  ret = oggplay_check_add_overflow (size, y_size, &size);
+  if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+    return ret;
+  }
+  
+  ret = oggplay_check_add_overflow (size, uv_size, &size);
+  if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+    return ret;
   }
 
   /*
    * we need to set the output strides to the input widths because we are
    * trying not to pass negative output stride issues on to the poor user.
    */
   record = (OggPlayVideoRecord*)oggplay_malloc (size);
 
-  if (record == NULL)
-    return;
-
+  if (record == NULL) {
+    return E_OGGPLAY_OUT_OF_MEMORY;
+  }
+  
   record->header.samples_in_record = 1;
   data = &(record->data);
 
   data->y = (unsigned char *)(record + 1);
   data->u = data->y + (decode->y_stride * decode->y_height);
   data->v = data->u + (decode->uv_stride * decode->uv_height);
 
   /*
    * *grumble* theora plays silly buggers with pointers so we need to do
    * a row-by-row copy (stride may be negative)
    */
+  y_offset = (decode->video_info.offset_x&~1) 
+              + buffer->y_stride*(decode->video_info.offset_y&~1);
   p = data->y;
-  q = buffer->y + (decode->video_info.offset_x&~1)+buffer->y_stride*(decode->video_info.offset_y&~1);
+  q = buffer->y + y_offset;
   for (i = 0; i < decode->y_height; i++) {
     memcpy(p, q, decode->y_width);
     p += decode->y_width;
     q += buffer->y_stride;
   }
 
   uv_offset = get_uv_offset(decode, buffer);
-
   p = data->u;
   q = buffer->u + uv_offset;
   p2 = data->v;
   q2 = buffer->v + uv_offset;
   for (i = 0; i < decode->uv_height; i++) {
     memcpy(p, q, decode->uv_width);
     memcpy(p2, q2, decode->uv_width);
     p += decode->uv_width;
@@ -400,148 +505,221 @@ oggplay_data_handle_theora_frame (OggPla
   }
 
   /* if we're to send RGB video, convert here */
   if (decode->convert_to_rgb) {
     OggPlayYUVChannels      yuv;
     OggPlayRGBChannels      rgb;
     OggPlayOverlayRecord  * orecord;
     OggPlayOverlayData    * odata;
+    long                    overlay_size;
 
     yuv.ptry = data->y;
     yuv.ptru = data->u;
     yuv.ptrv = data->v;
     yuv.y_width = decode->y_width;
     yuv.y_height = decode->y_height;
     yuv.uv_width = decode->uv_width;
     yuv.uv_height = decode->uv_height;
 
-    size = sizeof(OggPlayOverlayRecord) + decode->y_width * decode->y_height * 4;
+    size = sizeof(OggPlayOverlayRecord);
+    /* check for possible integer oveflows */
+    ret = oggplay_mul_signed_overflow(decode->y_width, decode->y_height, 
+                                      &overlay_size);
+    if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+      return ret;
+    }
+    
+    ret = oggplay_mul_signed_overflow(overlay_size, 4, &overlay_size);
+    if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+      return ret;
+    }
+
+    ret =  oggplay_check_add_overflow (size, overlay_size, &size);
+    if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+      return ret;
+    }
+
+    /* allocate memory for the overlay record */
     orecord = (OggPlayOverlayRecord*) oggplay_malloc (size);
-    if (orecord) {
+    if (orecord != NULL) {
       oggplay_data_initialise_header((OggPlayDecode *)decode, &(orecord->header));
       orecord->header.samples_in_record = 1;
       odata = &(orecord->data);
 
       rgb.ptro = (unsigned char*)(orecord+1);
       rgb.rgb_width = yuv.y_width;
       rgb.rgb_height = yuv.y_height;
 
-      oggplay_yuv2rgba(&yuv, &rgb);
-
-//      odata->rgb = NULL;
-//      odata->rgba = rgb.ptro;
+      if (!decode->swap_rgb) {
+        oggplay_yuv2bgra(&yuv, &rgb);
+      } else {
+        oggplay_yuv2rgba(&yuv, &rgb);
+      }
+      
       odata->rgb = rgb.ptro;
       odata->rgba = NULL;
       odata->width = rgb.rgb_width;
       odata->height = rgb.rgb_height;
       odata->stride = rgb.rgb_width*4;
 
       oggplay_free(record);
     
       oggplay_data_add_to_list((OggPlayDecode *)decode, &(orecord->header));
+    } else {
+      /* memory allocation failed! */
+      oggplay_free (record);
+      
+      return E_OGGPLAY_OUT_OF_MEMORY;
     }
   }
   else {
     oggplay_data_initialise_header((OggPlayDecode *)decode, &(record->header));
     oggplay_data_add_to_list((OggPlayDecode *)decode, &(record->header));
   }
+  
+  return E_OGGPLAY_CONTINUE;
 }
 
 #ifdef HAVE_KATE
-void
+OggPlayErrorCode
 oggplay_data_handle_kate_data(OggPlayKateDecode *decode, const kate_event *ev) {
 
   OggPlayTextRecord * record = NULL;
-
+  size_t              rec_size = sizeof(OggPlayTextRecord);
+  
+  if (decode == NULL) {
+    return -1; 
+  }
 #ifdef HAVE_TIGER
   tiger_renderer_add_event(decode->tr, ev->ki, ev);
 
   if (decode->use_tiger) {
     /* if rendering with Tiger, we don't add an event, a synthetic one will be
        generated each "tick" with an updated tracker state */
   }
   else
 #endif
   {
-    record = (OggPlayTextRecord*)oggplay_calloc (sizeof(OggPlayTextRecord) + ev->len0, 1);
-    if (!record)
-      return;
+    /* check for integer overflow */
+    if 
+    ( 
+      oggplay_check_add_overflow (rec_size, ev->len0, &rec_size)
+      == 
+      E_OGGPLAY_TYPE_OVERFLOW
+    )
+    {
+      return E_OGGPLAY_TYPE_OVERFLOW;
+    }
+    
+    record = (OggPlayTextRecord*)oggplay_calloc (rec_size, 1);
+    if (!record) {
+      return E_OGGPLAY_OUT_OF_MEMORY;
+    }
 
     oggplay_data_initialise_header(&decode->decoder, &(record->header));
 
     //record->header.presentation_time = (ogg_int64_t)(ev->start_time*1000);
     record->header.samples_in_record = (ev->end_time-ev->start_time)*1000;
     record->data = (char *)(record + 1);
 
     memcpy(record->data, ev->text, ev->len0);
 
     oggplay_data_add_to_list(&decode->decoder, &(record->header));
   }
+  
+  return E_OGGPLAY_CONTINUE;
 }
 #endif
 
 #ifdef HAVE_TIGER
-void
+OggPlayErrorCode
 oggplay_data_update_tiger(OggPlayKateDecode *decode, int active, ogg_int64_t presentation_time, OggPlayCallbackInfo *info) {
 
   OggPlayOverlayRecord  * record = NULL;
   OggPlayOverlayData    * data = NULL;
   size_t                size = sizeof (OggPlayOverlayRecord);
   int                   track = active && decode->use_tiger;
+  int                   ret;
   kate_float            t = OGGPLAY_TIME_FP_TO_INT(presentation_time) / 1000.0f;
 
-  if (!decode->init) return;
+  if (!decode->decoder.initialised) return -1;
 
   if (track) {
     if (info) {
       if (info->required_records>0) {
         OggPlayDataHeader *header = info->records[0];
         data = (OggPlayOverlayData*)(header+1);
         if (decode->tr && data->rgb) {
+#if WORDS_BIGENDIAN || IS_BIG_ENDIAN
+          tiger_renderer_set_buffer(decode->tr, data->rgb, data->width, data->height, data->stride, 0);
+#else
           tiger_renderer_set_buffer(decode->tr, data->rgb, data->width, data->height, data->stride, 1);
+#endif
         }
         else {
           /* we're supposed to overlay on a frame, but the available frame has no RGB buffer */
           /* fprintf(stderr,"no RGB buffer found for video frame\n"); */
-          return;
+          return -1;
         }
       }
       else {
         /* we're supposed to overlay on a frame, but there is no frame available */
         /* fprintf(stderr,"no video frame to overlay on\n"); */
-        return;
+        return -1;
       }
     }
     else {
       // TODO: some way of knowing the size of the video we'll be drawing onto, if any
-      int width = decode->k.ki->original_canvas_width;
-      int height = decode->k.ki->original_canvas_height;
+      int width = decode->k_state.ki->original_canvas_width;
+      int height = decode->k_state.ki->original_canvas_height;
+      long overlay_size;
       if (width <= 0 || height <= 0) {
         /* some default resolution if we're not overlaying onto a video and the canvas size is unknown */
-        width = 640;
-        height = 480;
+        if (decode->default_width > 0 && decode->default_height > 0) {
+          width = decode->default_width;
+          height = decode->default_height;
+        }
+        else {
+          width = 640;
+          height = 480;
+        }
       }
-      size = sizeof (OggPlayOverlayRecord) + width*height*4;
+      /* check for integer overflow */
+      ret = oggplay_mul_signed_overflow (width, height, &overlay_size);
+      if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+        return ret;
+      }
+      
+      ret = oggplay_mul_signed_overflow (overlay_size, 4, &overlay_size);
+      if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+        return E_OGGPLAY_TYPE_OVERFLOW;
+      }
+      
+      ret = oggplay_check_add_overflow (size, overlay_size, &size);
+      if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
+        return E_OGGPLAY_TYPE_OVERFLOW;
+      }
+
       record = (OggPlayOverlayRecord*)oggplay_calloc (1, size);
       if (!record)
-        return;
+        return E_OGGPLAY_OUT_OF_MEMORY;
 
       record->header.samples_in_record = 1;
       data= &(record->data);
       oggplay_data_initialise_header((OggPlayDecode *)decode, &(record->header));
 
       data->rgba = (unsigned char*)(record+1);
       data->rgb = NULL;
       data->width = width;
       data->height = height;
       data->stride = width*4;
 
       if (decode->tr && data->rgba) {
-        tiger_renderer_set_buffer(decode->tr, data->rgba, data->width, data->height, data->stride, 1);
+        tiger_renderer_set_buffer(decode->tr, data->rgba, data->width, data->height, data->stride, decode->swap_rgb);
       }
 
       oggplay_data_add_to_list(&decode->decoder, &(record->header));
       record->header.presentation_time=presentation_time;
     }
   }
 
   if (decode->tr) {
@@ -549,11 +727,13 @@ oggplay_data_update_tiger(OggPlayKateDec
   }
 
   if (track) {
     /* buffer was either calloced, so already cleared, or already filled with video, so no clearing */
     if (decode->tr) {
       tiger_renderer_render(decode->tr);
     }
   }
+  
+  return E_OGGPLAY_CONTINUE;
 }
 #endif
 
--- a/media/liboggplay/src/liboggplay/oggplay_data.h
+++ b/media/liboggplay/src/liboggplay/oggplay_data.h
@@ -36,36 +36,36 @@
  * Shane Stephens <shane.stephens@annodex.net>
  */
 #ifndef __OGGPLAY_DATA_H__
 #define __OGGPLAY_DATA_H__
 
 void
 oggplay_data_initialise_list (OggPlayDecode *decode);
 
-void
+OggPlayErrorCode
 oggplay_data_handle_theora_frame (OggPlayTheoraDecode *decode, 
-                                  yuv_buffer *buffer);
+                                  const yuv_buffer *buffer);
 
-void
-oggplay_data_handle_audio_data (OggPlayDecode *decode, void *data, 
-                                int samples, int samplesize);
+OggPlayErrorCode
+oggplay_data_handle_audio_data (OggPlayDecode *decode, 
+                                void *data, long samples, size_t samplesize);
 
-void
-oggplay_data_handle_cmml_data(OggPlayDecode *decode, unsigned char *data,
-                                int size);
+OggPlayErrorCode
+oggplay_data_handle_cmml_data(OggPlayDecode *decode, 
+                              unsigned char *data, long size);
 
 #ifdef HAVE_KATE
-void
+OggPlayErrorCode
 oggplay_data_handle_kate_data(OggPlayKateDecode *decode,
                               const kate_event *ev);
 #endif
 
 #ifdef HAVE_TIGER
-void
+OggPlayErrorCode
 oggplay_data_update_tiger(OggPlayKateDecode *decode,
                           int active, ogg_int64_t presentation_time,
                           OggPlayCallbackInfo *info);
 #endif
 
 void
 oggplay_data_clean_list (OggPlayDecode *decode);
 
--- a/media/liboggplay/src/liboggplay/oggplay_file_reader.c
+++ b/media/liboggplay/src/liboggplay/oggplay_file_reader.c
@@ -67,30 +67,42 @@ oggplay_file_reader_initialise(OggPlayRe
 
   return E_OGGPLAY_OK;
 }
 
 OggPlayErrorCode
 oggplay_file_reader_destroy(OggPlayReader * opr) {
 
   OggPlayFileReader * me;
-
+  
+  if (opr == NULL) {
+    return E_OGGPLAY_BAD_READER;
+  }
+  
   me = (OggPlayFileReader *)opr;
 
-  fclose(me->file);
+  if (me->file != NULL) {
+    fclose(me->file);
+  }
+  
   oggplay_free(me);
 
   return E_OGGPLAY_OK;
 }
 
 int
 oggplay_file_reader_available(OggPlayReader * opr, ogg_int64_t current_bytes,
-    ogg_int64_t current_time) {
+                              ogg_int64_t current_time) {
 
   OggPlayFileReader *me = (OggPlayFileReader *)opr;
+  
+  if (me == NULL) {
+    return -1;
+  }
+
   return me->size;
 
 }
 
 int
 oggplay_file_reader_finished_retrieving(OggPlayReader *opr) {
 
   return 1;
@@ -98,47 +110,60 @@ oggplay_file_reader_finished_retrieving(
 }
 
 
 static size_t
 oggplay_file_reader_io_read(void * user_handle, void * buf, size_t n) {
 
   OggPlayFileReader *me = (OggPlayFileReader *)user_handle;
   int r;
+  
+  if (me == NULL) {
+    return -1;
+  }
+  
   r = fread(buf, 1, n, me->file);
   if (r > 0) {
     me->current_position += r;
   }
 
   return r;
 }
 
 static int
 oggplay_file_reader_io_seek(void * user_handle, long offset, int whence) {
 
   OggPlayFileReader * me = (OggPlayFileReader *)user_handle;
   int                 r;
 
+  if (me == NULL) {
+    return -1;
+  }
+  
   r = fseek(me->file, offset, whence);
   me->current_position = ftell(me->file);
   return r;
 
 }
 
 static long
 oggplay_file_reader_io_tell(void * user_handle) {
 
   OggPlayFileReader * me = (OggPlayFileReader *)user_handle;
 
+  if (me == NULL) {
+    return -1;
+  }
+  
   return ftell(me->file);
 
 }
 
 OggPlayReader *
-oggplay_file_reader_new(char *file_name) {
+oggplay_file_reader_new(const char *file_name) {
 
   OggPlayFileReader * me = oggplay_malloc (sizeof (OggPlayFileReader));
 
   if (me == NULL)
     return NULL;
 
   me->current_position = 0;
   me->file_name = file_name;
--- a/media/liboggplay/src/liboggplay/oggplay_file_reader.h
+++ b/media/liboggplay/src/liboggplay/oggplay_file_reader.h
@@ -42,15 +42,15 @@
 
 #include <stdio.h>
 
 #define FILE_READER_CHUNK_SIZE              8192
 #define FILE_READER_INITIAL_NUM_BUFFERS     8
 
 typedef struct {
   OggPlayReader     functions;
-  char            * file_name;
+  const char      * file_name;
   FILE            * file;
   long              current_position;
   long              size;
 } OggPlayFileReader;
 
 #endif
--- a/media/liboggplay/src/liboggplay/oggplay_private.h
+++ b/media/liboggplay/src/liboggplay/oggplay_private.h
@@ -163,34 +163,36 @@ typedef struct {
   int                   active;             /**< indicates whether the track is active or not */
   ogg_int64_t           final_granulepos;   /**<  */
   struct _OggPlay     * player;             /**< reference to the OggPlay handle */
   OggPlayDataHeader   * data_list;          
   OggPlayDataHeader   * end_of_data_list;   
   OggPlayDataHeader   * untimed_data_list;  
   OggPlayStreamInfo     stream_info;        /**< @see OggPlayStreamInfo */
   int                   preroll;            /**< num. of past content packets to take into account when decoding the current Ogg page */
+  short                 initialised;        /**< */
+  int                   num_header_packets; /**< number of header packets left to process for the stream.*/
 } OggPlayDecode;
 
 typedef struct {
   OggPlayDecode   decoder;
   theora_state    video_handle;
   theora_info     video_info;
   theora_comment  video_comment;
-  int             remaining_header_packets;
   int             granulepos_seen;
   int             frame_delta;
   int             y_width;
   int             y_height;
   int             y_stride;
   int             uv_width;
   int             uv_height;
   int             uv_stride;
   int             cached_keyframe;
   int             convert_to_rgb;
+  int             swap_rgb;
 } OggPlayTheoraDecode;
 
 typedef struct {
   OggPlayDecode   decoder;
   FishSound     * sound_handle;
   FishSoundInfo   sound_info;
 } OggPlayAudioDecode;
 
@@ -207,70 +209,81 @@ typedef struct {
   ogg_int64_t     presentation_time;
   ogg_int64_t     base_time;
 } OggPlaySkeletonDecode;
 
 typedef struct {
   OggPlayDecode   decoder;
 #ifdef HAVE_KATE
   int             granuleshift;
-  kate_state      k;
+  kate_state      k_state;
+  kate_info       k_info;
+  kate_comment    k_comment;
   int             init;
 #ifdef HAVE_TIGER
   int use_tiger;
   int overlay_dest;
   tiger_renderer *tr;
+  int default_width;
+  int default_height;
+  int swap_rgb;
 #endif
 #endif
 } OggPlayKateDecode;
 
 struct OggPlaySeekTrash;
 
+/**
+ *
+ */
 typedef struct OggPlaySeekTrash {
   OggPlayDataHeader       * old_data;
   OggPlayBuffer           * old_buffer;
   struct OggPlaySeekTrash * next;
 } OggPlaySeekTrash;
 
+/**
+ * 
+ */
 struct _OggPlay {
-  OggPlayReader           * reader;
-  OGGZ                    * oggz;
-  OggPlayDecode          ** decode_data;
-  OggPlayCallbackInfo     * callback_info;
-  int                       num_tracks;
-  int                       all_tracks_initialised;
-  ogg_int64_t               callback_period;
-  OggPlayDataCallback     * callback;
-  void                    * callback_user_ptr;
-  ogg_int64_t               target;
-  int                       active_tracks;
-  volatile OggPlayBuffer  * buffer;
-  ogg_int64_t               presentation_time;  /**< presentation time in seconds in 32.32 fixed point format */
-  OggPlaySeekTrash        * trash;
-  int                       shutdown;
-  int                       pt_update_valid;
-  ogg_int64_t               duration;	          /**< The value of the duration the last time it was retrieved.*/
+  OggPlayReader           * reader;                 /**< @see OggPlayReader */
+  OGGZ                    * oggz;                   /**< @see OGGZ */
+  OggPlayDecode          ** decode_data;            /**< */
+  OggPlayCallbackInfo     * callback_info;          /**< */
+  int                       num_tracks;             /**< number of tracks in the Ogg container */
+  int                       all_tracks_initialised; /**< "= 1" indicates that all tracks are initialised */
+  ogg_int64_t               callback_period;        /**< */
+  OggPlayDataCallback     * callback;               /**< */
+  void                    * callback_user_ptr;      /**< */
+  ogg_int64_t               target;                 /**< */
+  int                       active_tracks;          /**< number of active tracks */
+  volatile OggPlayBuffer  * buffer;                 /**< @see OggPlayBuffer */
+  ogg_int64_t               presentation_time;      /**< */
+  OggPlaySeekTrash        * trash;                  /**< @see OggPlaySeekTrash */
+  int                       shutdown;               /**< "= 1" indicates shutdown event */
+  int                       pt_update_valid;        /**< */
+  ogg_int64_t               duration;	              /**< The value of the duration the last time it was retrieved.*/
 };
 
 void
 oggplay_set_data_callback_force(OggPlay *me, OggPlayDataCallback callback,
-                void *user);
+                                void *user);
 
 void
 oggplay_take_out_trash(OggPlay *me, OggPlaySeekTrash *trash);
 
-void
+OggPlayErrorCode
 oggplay_seek_cleanup(OggPlay *me, ogg_int64_t milliseconds);
 
 typedef struct {
-  void (*init)(void *user_data);
-  int (*callback)(OGGZ * oggz, ogg_packet * op, long serialno,
-                                                          void * user_data);
-  void (*shutdown)(void *user_data);
-  int size;
+  void  (*init)     (void *user_data);
+  int   (*callback) (OGGZ * oggz, ogg_packet * op, long serialno,
+                     void * user_data);
+  void  (*shutdown) (void *user_data);
+  int   size;
 } OggPlayCallbackFunctions;
 
 /**
  * Conversion function for fixed point 32.32 representation of time. 
  * 
  * OGGPLAY_TIME_INT_TO_FP(x)
  *  converts 'x' to a 32.32 fixed point integer
  *
@@ -285,13 +298,160 @@ typedef struct {
 
 /* Allocate and free dynamic memory used by ogg.
  * By default they are the ones from stdlib */
 #define oggplay_malloc _ogg_malloc
 #define oggplay_calloc _ogg_calloc
 #define oggplay_realloc _ogg_realloc
 #define oggplay_free _ogg_free
 
+/**
+ * macros for obtaining a type's max and min values
+ * http://www.fefe.de/intof.html 
+ */
+#define OGGPLAY_TYPE_HALF_MAX_SIGNED(type) ((type)1 << (sizeof(type)*8-2))
+#define OGGPLAY_TYPE_MAX_SIGNED(type) (OGGPLAY_TYPE_HALF_MAX_SIGNED(type) - 1 + OGGPLAY_TYPE_HALF_MAX_SIGNED(type))
+#define OGGPLAY_TYPE_MIN_SIGNED(type) (-1 - OGGPLAY_TYPE_MAX_SIGNED(type))
+#define OGGPLAY_TYPE_MIN(type) ((type)-1 < 1?OGGPLAY_TYPE_MIN_SIGNED(type):(type)0)
+#define OGGPLAY_TYPE_MAX(type) ((type)~OGGPLAY_TYPE_MIN(type))
+
+static inline int
+oggplay_check_add_overflow (size_t a, long b, size_t* r) {  
+  /* we cannot assume that sizeof(size_t) >= sizeof(long) !!! */
+  if (sizeof(size_t) < sizeof(long)) {
+    /* check whether the number fits into a size_t */
+    if
+    (
+      (b < 0) ?
+        ((OGGPLAY_TYPE_MAX(size_t)+b >= 0) ? 0 : 1) :
+        ((OGGPLAY_TYPE_MAX(size_t)-b >= 0) ? 0 : 1)
+    )
+    {
+      return E_OGGPLAY_TYPE_OVERFLOW;
+    }
+  } 
+  /* check whether the sum of the 'a' and 'b' fits into a size_t */
+  if
+  (
+    (b < 0) ?
+      ((OGGPLAY_TYPE_MIN(size_t)-b <= a) ? 0 : 1) :
+      ((OGGPLAY_TYPE_MAX(size_t)-b >= a) ? 0 : 1)
+  )
+  {
+    return E_OGGPLAY_TYPE_OVERFLOW;
+  }
+  
+  /* if 'r' is supplied give back the sum of 'a' and 'b' */
+  if (r != NULL)
+    *r = a+b;
+  
+  return 0;
+}
+
+static inline int
+oggplay_mul_signed_overflow_generic(long a, long b, long *re) {  
+  long _a, _b, ah, bh, x, y, r;
+  int sign = 1;
+  
+  _a = a;
+  _b = b;
+  ah = _a >> (sizeof(long)*4);
+  bh = _b >> (sizeof(long)*4);
+  
+  if (a < 0) {
+    _a = -_a;
+    if (_a < 0) {
+      if (_b == 0 || _b == 1) {
+        r = _a*_b;
+        goto ok;
+      } else {
+        goto overflow;
+      }
+    }
+    sign = -sign;
+    ah = _a >> (sizeof(long)*4);
+  }
+
+  if (_b < 0) {
+    _b = -_b;
+    if (_b < 0) {
+      if (_a == 0 || (_a == 1 && sign == 1)) {
+        r = _a*_b;
+        goto ok;
+      } else {
+        goto overflow;
+      }
+    }
+    sign = -sign;
+    bh = _b >> (sizeof(long)*4);
+  }
+
+  if (ah != 0 && bh != 0) {
+    goto overflow;
+  }
+  
+  if (ah == 0 && bh == 0) {
+    r = _a*_b;
+    if (r < 0)
+      goto overflow;
+    
+    goto ok;
+  }
+  
+  if (_a < _b) {
+    x = _a;
+    _a = _b;
+    _b = x;
+    ah = bh;
+  }
+
+  y = ah*_b;
+  if (y >= (1L << (sizeof(long)*4 - 1)))
+    goto overflow;
+  _a &= (1L << sizeof(long)*4) - 1;
+  x = _a*_b;
+  if (x < 0)
+    goto overflow;
+  x += (y << sizeof(long)*4);
+  if (x < 0)
+    goto overflow;
+          
+ok:
+  if (re != NULL) {
+    *re = sign*r;
+  }
+  
+  return 0;
+  
+overflow:
+  return E_OGGPLAY_TYPE_OVERFLOW;
+}
+
+static inline int 
+oggplay_mul_signed_overflow(long a, long b, long *r) {
+  if (sizeof(long) > 4) {
+    return oggplay_mul_signed_overflow_generic (a, b, r);
+  } else {
+    ogg_int64_t c = (ogg_int64_t) a*b;
+
+    /* check whether the result fits in a long bit */
+    if
+    (
+      (c < 1) ?
+        ((OGGPLAY_TYPE_MIN (long) > c) ? 1 : 0) :
+        ((OGGPLAY_TYPE_MAX (long) < c) ? 1 : 0)
+    ) 
+    {
+      return E_OGGPLAY_TYPE_OVERFLOW;
+    }
+    
+    if (r != NULL) {
+      *r = (long)c;
+    }
+    return 0; 
+  }
+}
+
 #include "oggplay_callback.h"
 #include "oggplay_data.h"
 #include "oggplay_buffer.h"
 
 #endif
--- a/media/liboggplay/src/liboggplay/oggplay_query.c
+++ b/media/liboggplay/src/liboggplay/oggplay_query.c
@@ -125,21 +125,26 @@ oggplay_set_track_active(OggPlay *me, in
   /*
    * Skeleton tracks should not be set active - data in them should be queried
    * using alternative mechanisms (there is no concept of time-synced data
    * in a skeleton track)
    */
   if (me->decode_data[track_num]->content_type == OGGZ_CONTENT_SKELETON) {
     return E_OGGPLAY_TRACK_IS_SKELETON;
   }
-
+  
   if (me->decode_data[track_num]->content_type == OGGZ_CONTENT_UNKNOWN) {
     return E_OGGPLAY_TRACK_IS_UNKNOWN;
   }
 
+  /* there was an error while decoding the headers of this track! */
+  if (me->decode_data[track_num]->initialised != 1) {
+    return E_OGGPLAY_TRACK_UNINITIALISED;
+  }
+
   if ((p = me->decode_data[track_num]->final_granulepos) != -1) {
     if (p * me->decode_data[track_num]->granuleperiod > me->target) {
       return E_OGGPLAY_TRACK_IS_OVER;
     }
   }
 
   if (me->decode_data[track_num]->active == 0) {
     me->decode_data[track_num]->active = 1;
--- a/media/liboggplay/src/liboggplay/oggplay_seek.c
+++ b/media/liboggplay/src/liboggplay/oggplay_seek.c
@@ -67,20 +67,17 @@ oggplay_seek(OggPlay *me, ogg_int64_t mi
       return E_OGGPLAY_CANT_SEEK;
     }
   } else {
     if (oggz_seek_units(me->oggz, milliseconds, SEEK_SET) == -1) {
       return E_OGGPLAY_CANT_SEEK;
     }
   }
 
-  oggplay_seek_cleanup(me, milliseconds);
-
-  return E_OGGPLAY_OK;
-
+  return oggplay_seek_cleanup(me, milliseconds);
 }
 
 OggPlayErrorCode
 oggplay_seek_to_keyframe(OggPlay *me,
                          int* tracks,
                          int num_tracks,
                          ogg_int64_t milliseconds,
                          ogg_int64_t offset_begin,
@@ -118,63 +115,60 @@ oggplay_seek_to_keyframe(OggPlay *me,
                                 offset_begin,
                                 offset_end);
   oggplay_free(serial_nos);
 
   if (time == -1) {
     return E_OGGPLAY_CANT_SEEK;
   }
 
-  oggplay_seek_cleanup(me, time);
-
-  return E_OGGPLAY_OK;
-
+  return oggplay_seek_cleanup(me, time);
 }
 
-void
+OggPlayErrorCode
 oggplay_seek_cleanup(OggPlay* me, ogg_int64_t milliseconds)
 {
 
   OggPlaySeekTrash    * trash;
   OggPlaySeekTrash   ** p;
   OggPlayDataHeader  ** end_of_list_p;
   int                   i;
 
-  if (me  == NULL)
-    return;
+  if (me == NULL)
+    return E_OGGPLAY_BAD_OGGPLAY;
 
   /*
    * first, create a trash object to store the context that we want to
    * delete but can't until the presentation thread is no longer using it -
    * this will occur as soon as the thread calls oggplay_buffer_release_next
    */
 
   trash = oggplay_calloc(1, sizeof(OggPlaySeekTrash));
 
   if (trash == NULL)
-    return;
+    return E_OGGPLAY_OUT_OF_MEMORY;
 
   /*
    * store the old buffer in it next.
    */
   if (me->buffer != NULL) {
-
+  
     trash->old_buffer = (OggPlayBuffer *)me->buffer;
 
     /*
      * replace the buffer with a new one.  From here on, the presentation thread
      * will start using this buffer instead.
      */
     me->buffer = oggplay_buffer_new_buffer(me->buffer->buffer_size);
 
-    if (me->buffer == NULL) {
-      return;
+    if (me->buffer == NULL)
+    {
+      return E_OGGPLAY_OUT_OF_MEMORY;
     }
   }
-  
   /*
    * strip all of the data packets out of the streams and put them into the
    * trash.  We can free the untimed packets immediately - they are USELESS
    * SCUM OF THE EARTH (and also unreferenced by the buffer).
    */
   end_of_list_p = &trash->old_data;
   for (i = 0; i < me->num_tracks; i++) {
     OggPlayDecode *track = me->decode_data[i];
@@ -214,16 +208,32 @@ oggplay_seek_cleanup(OggPlay* me, ogg_in
   trash->next = NULL;
 
   p = &(me->trash);
   while (*p != NULL) {
     p = &((*p)->next);
   }
 
   *p = trash;
+
+  if (milliseconds == 0) {
+    for (i = 0; i < me->num_tracks; i++) {
+      OggPlayDecode *track = me->decode_data[i];
+      FishSound *sound_handle;
+      OggPlayAudioDecode *audio_decode;
+      if (track->content_type != OGGZ_CONTENT_VORBIS) {
+        continue;
+      }
+      audio_decode = (OggPlayAudioDecode*)track;
+      sound_handle = audio_decode->sound_handle;
+      fish_sound_reset(sound_handle);
+    }
+  }
+  
+  return E_OGGPLAY_OK;
 }
 
 void
 oggplay_take_out_trash(OggPlay *me, OggPlaySeekTrash *trash) {
 
   OggPlaySeekTrash *p = NULL;
 
   for (; trash != NULL; trash = trash->next) {
--- a/media/liboggplay/src/liboggplay/oggplay_tcp_reader.c
+++ b/media/liboggplay/src/liboggplay/oggplay_tcp_reader.c
@@ -156,17 +156,17 @@ oggplay_create_socket() {
  * @param proxy The proxy if there's any.
  * @param proxy_port The port of the proxy if there's any.
  * @param host The host to connect to; using proxy if set. 
  * @param port The port to connect to;
  * @param path The path where the content resides on the server.  
  * @retval -1 in case of error, 0 otherwise. 
  */
 int
-oggplay_hostname_and_path(char *location, char *proxy, int proxy_port,
+oggplay_hostname_and_path(const char *location, const char *proxy, int proxy_port,
                           char **host, int *port, char **path) {
 
 
   char  * colon;
   char  * slash;
   char  * end_of_host;
 
   /* if we have a proxy installed this is all dead simple */
@@ -293,17 +293,17 @@ oggplay_tcp_reader_initialise(OggPlayRea
   int                   port;
   int                   nbytes;
   int                   remaining;
   char                  http_request_header[1024];
   ogg_int64_t           time_ref;
   int                   r;
 
   char                * pos;
-  int                   len;
+  size_t                len;
 
   if (me == NULL) {
     return E_OGGPLAY_BAD_READER;
   }
   if (me->state == OTRS_INIT_COMPLETE) {
     return E_OGGPLAY_OK;
   }
 
@@ -354,16 +354,25 @@ oggplay_tcp_reader_initialise(OggPlayRea
 
   oggplay_free(host);
   oggplay_free(path);
 
   if (he == NULL) {
     printf("Host not found\n");
     return E_OGGPLAY_BAD_INPUT;
   }
+  /* 
+   * currently we only support IPv4
+   * TODO: switch to getaddrinfo and support IPv6!
+   */
+  if (sizeof(addr.sin_addr.s_addr) != he->h_length) {
+    printf("No IPv6 support, yet!\n");
+    return E_OGGPLAY_BAD_INPUT;
+  }
+  
   memcpy(&addr.sin_addr.s_addr, he->h_addr, he->h_length);
   addr.sin_family = AF_INET;
   addr.sin_port = htons(port);
 
   /*
    * Connect to the host.
    */
   if (me->state == OTRS_SOCKET_CREATED) {
@@ -441,19 +450,19 @@ oggplay_tcp_reader_initialise(OggPlayRea
       if (me->amount_in_memory < 15) {
         continue;
       }
 
       if
       (
         (!found_http_response)
         &&
-        strncmp((char *)me->buffer, "HTTP/1.1 200 OK", 15) != 0
+        strncmp((char *)me->buffer, "HTTP/1.1 200 ", 13) != 0
         &&
-        strncmp((char *)me->buffer, "HTTP/1.0 200 OK", 15) != 0
+        strncmp((char *)me->buffer, "HTTP/1.0 200 ", 13) != 0
       )
       {
         return E_OGGPLAY_BAD_INPUT;
       } else {
         found_http_response = 1;
       }
 
       dpos = strstr((char *)me->buffer, "X-Content-Duration:");
@@ -532,16 +541,20 @@ oggplay_tcp_reader_initialise(OggPlayRea
 }
 
 
 OggPlayErrorCode
 oggplay_tcp_reader_destroy(OggPlayReader * opr) {
 
   OggPlayTCPReader * me = (OggPlayTCPReader *)opr;
 
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_READER;
+  }
+
   if (me->socket != INVALID_SOCKET) {
 #ifdef WIN32
 #ifdef HAVE_WINSOCK2
     shutdown(me->socket, SD_BOTH);
 #endif
     closesocket(me->socket);
     WSACleanup();
 #else
@@ -559,16 +572,20 @@ oggplay_tcp_reader_destroy(OggPlayReader
 }
 
 OggPlayErrorCode
 grab_some_data(OggPlayTCPReader *me, int block) {
 
   int remaining;
   int r;
 
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_READER;
+  }
+  
   if (me->socket == INVALID_SOCKET) return E_OGGPLAY_OK;
 
   /*
    * see if we can grab some more data
    * if we're not blocking, make sure there's some available data
    */
   if (!block) {
     struct timeval tv;
@@ -618,41 +635,54 @@ int
 oggplay_tcp_reader_available(OggPlayReader * opr, ogg_int64_t current_bytes,
     ogg_int64_t current_time) {
 
   OggPlayTCPReader  * me;
   ogg_int64_t         tpb     = (current_time << 16) / current_bytes;
 
   me = (OggPlayTCPReader *)opr;
 
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_READER;
+  }
+  
   if (me->socket == INVALID_SOCKET) {
     return me->duration;
   }
 
   grab_some_data(me, 0);
   if (me->duration > -1 && ((tpb * me->stored_offset) >> 16) > me->duration)
   {
     return me->duration;
   }
   return (int)((tpb * me->stored_offset) >> 16);
 
 }
 
 ogg_int64_t
 oggplay_tcp_reader_duration(OggPlayReader * opr) {
   OggPlayTCPReader    *me = (OggPlayTCPReader *)opr;
+
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_READER;
+  }
+
   return me->duration;
 }
 
 static size_t
 oggplay_tcp_reader_io_read(void * user_handle, void * buf, size_t n) {
 
   OggPlayTCPReader  * me = (OggPlayTCPReader *)user_handle;
   int                 len;
 
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_READER;
+  }
+  
   grab_some_data(me, 0);
 
   fseek(me->backing_store, me->current_position, SEEK_SET);
   len = fread(buf, 1, n, me->backing_store);
   if (len == 0) {
     fseek(me->backing_store, 0, SEEK_END);
     grab_some_data(me, 1);
     fseek(me->backing_store, me->current_position, SEEK_SET);
@@ -671,35 +701,43 @@ oggplay_tcp_reader_finished_retrieving(O
 
 
 static int
 oggplay_tcp_reader_io_seek(void * user_handle, long offset, int whence) {
 
   OggPlayTCPReader  * me = (OggPlayTCPReader *)user_handle;
   int                 r;
 
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_READER;
+  }
+  
   fseek(me->backing_store, me->current_position, SEEK_SET);
   r = fseek(me->backing_store, offset, whence);
   me->current_position = ftell(me->backing_store);
   fseek(me->backing_store, 0, SEEK_END);
 
   return r;
 }
 
 static long
 oggplay_tcp_reader_io_tell(void * user_handle) {
 
   OggPlayTCPReader  * me = (OggPlayTCPReader *)user_handle;
 
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_READER;
+  }
+  
   return me->current_position;
 
 }
 
 OggPlayReader *
-oggplay_tcp_reader_new(char *location, char *proxy, int proxy_port) {
+oggplay_tcp_reader_new(const char *location, const char *proxy, int proxy_port) {
 
   OggPlayTCPReader * me = (OggPlayTCPReader *)oggplay_malloc (sizeof (OggPlayTCPReader));
 
   if (me == NULL)
     return NULL;
 
   me->state = OTRS_UNINITIALISED;
   me->socket = INVALID_SOCKET;
--- a/media/liboggplay/src/liboggplay/oggplay_tcp_reader.h
+++ b/media/liboggplay/src/liboggplay/oggplay_tcp_reader.h
@@ -69,17 +69,17 @@ typedef struct {
   SOCKET            socket;
 #else
   int               socket;
 #endif
   unsigned char   * buffer;
   int               buffer_size;
   int               current_position;
   char            * location;
-  char            * proxy;
+  const char      * proxy;
   int               proxy_port;
   int               amount_in_memory;
   FILE            * backing_store;
   int               stored_offset;
   dataLocation      mode;
   int               duration;
 } OggPlayTCPReader;
 
--- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
+++ b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
@@ -34,40 +34,54 @@
  * yuv2rgb.c
  *
  * YUV->RGB function, using platform-specific optimisations where possible.
  *
  * Shane Stephens <shane.stephens@annodex.net>
  * Michael Martin
  * Marcin Lubonski
  * Viktor Gal
+ * Makoto Kato <m_kato@ga2.so-net.ne.jp>
  */
 
 #include "oggplay_private.h"
 #include "oggplay_yuv2rgb_template.h"
 
+#ifdef __SUNPRO_C
+#define DISABLE_CPU_FEATURES
+/* gcc inline asm and intristics have problems with Sun Studio.
+ * We need to fix it.
+ */
+#else
 /* cpu extension detection */
 #include "cpu.c"
+#endif
 
 /**
  * yuv_convert_fptr type is a function pointer type for
  * the various yuv-rgb converters
  */
 typedef void (*yuv_convert_fptr) (const OggPlayYUVChannels *yuv, 
-					OggPlayRGBChannels *rgb);
+                                  OggPlayRGBChannels *rgb);
 
 /* it is useless to determine each YUV conversion run
  * the cpu type/featurs, thus we save the conversion function
  * pointers
  */
 static struct OggPlayYUVConverters {
-	yuv_convert_fptr yuv2rgba; /**< YUV420 to RGBA */
-	yuv_convert_fptr yuv2bgra; /**< YUV420 to BGRA */
-	yuv_convert_fptr yuv2argb; /**< YUV420 to ARGB */
-} yuv_conv = {NULL, NULL, NULL};
+	yuv_convert_fptr yuv420rgba; /**< YUV420 to RGBA */
+	yuv_convert_fptr yuv420bgra; /**< YUV420 to BGRA */
+	yuv_convert_fptr yuv420argb; /**< YUV420 to ARGB */
+	yuv_convert_fptr yuv422rgba; /**< YUV422 to RGBA */
+	yuv_convert_fptr yuv422bgra; /**< YUV422 to BGRA */
+	yuv_convert_fptr yuv422argb; /**< YUV422 to ARGB */
+	yuv_convert_fptr yuv444rgba; /**< YUV444 to RGBA */
+	yuv_convert_fptr yuv444bgra; /**< YUV444 to BGRA */
+	yuv_convert_fptr yuv444argb; /**< YUV444 to ARGB */
+} yuv_conv = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
 
 /**
  * vanilla implementation of YUV-to-RGB conversion.
  *
  *  - using table-lookups instead of multiplication
  *  - avoid CLAMPing by incorporating 
  *
  */
@@ -116,45 +130,71 @@ out[1] = CLAMP(b); \
 out[2] = CLAMP(g); \
 out[3] = CLAMP(r);
 
 #define LOOKUP_COEFFS int ruv = CoefsRV[*pv]; 			\
 		      int guv = CoefsGU[*pu] + CoefsGV[*pv]; 	\
 		      int buv = CoefsBU[*pu]; 			\
                       int r, g, b;
 
-/* yuv420p -> */
+/* yuv420p, yuv422p -> */
 #define CONVERT(OUTPUT_FUNC) LOOKUP_COEFFS				 \
 			     VANILLA_YUV2RGB_PIXEL(py[0], ruv, guv, buv) \
 			     OUTPUT_FUNC(dst, r, g, b)  \
 			     VANILLA_YUV2RGB_PIXEL(py[1], ruv, guv, buv) \
 			     OUTPUT_FUNC((dst+4), r, g, b)
 
 #define CLEANUP
 
-YUV_CONVERT(yuv420_to_rgba_vanilla, CONVERT(VANILLA_RGBA_OUT), VANILLA_RGBA_OUT, 2, 8, 2, 1)
-YUV_CONVERT(yuv420_to_bgra_vanilla, CONVERT(VANILLA_BGRA_OUT), VANILLA_BGRA_OUT, 2, 8, 2, 1)
-YUV_CONVERT(yuv420_to_abgr_vanilla, CONVERT(VANILLA_ABGR_OUT), VANILLA_ABGR_OUT, 2, 8, 2, 1)
-YUV_CONVERT(yuv420_to_argb_vanilla, CONVERT(VANILLA_ARGB_OUT), VANILLA_ARGB_OUT, 2, 8, 2, 1)
+YUV_CONVERT(yuv420_to_rgba_vanilla, CONVERT(VANILLA_RGBA_OUT), VANILLA_RGBA_OUT, 2, 8, 2, 1, 2)
+YUV_CONVERT(yuv420_to_bgra_vanilla, CONVERT(VANILLA_BGRA_OUT), VANILLA_BGRA_OUT, 2, 8, 2, 1, 2)
+YUV_CONVERT(yuv420_to_abgr_vanilla, CONVERT(VANILLA_ABGR_OUT), VANILLA_ABGR_OUT, 2, 8, 2, 1, 2)
+YUV_CONVERT(yuv420_to_argb_vanilla, CONVERT(VANILLA_ARGB_OUT), VANILLA_ARGB_OUT, 2, 8, 2, 1, 2)
+
+YUV_CONVERT(yuv422_to_rgba_vanilla, CONVERT(VANILLA_RGBA_OUT), VANILLA_RGBA_OUT, 2, 8, 2, 1, 1)
+YUV_CONVERT(yuv422_to_bgra_vanilla, CONVERT(VANILLA_BGRA_OUT), VANILLA_BGRA_OUT, 2, 8, 2, 1, 1)
+YUV_CONVERT(yuv422_to_abgr_vanilla, CONVERT(VANILLA_ABGR_OUT), VANILLA_ABGR_OUT, 2, 8, 2, 1, 1)
+YUV_CONVERT(yuv422_to_argb_vanilla, CONVERT(VANILLA_ARGB_OUT), VANILLA_ARGB_OUT, 2, 8, 2, 1, 1)
+
+#undef CONVERT
+
+/* yuv444p -> */
+#define CONVERT(OUTPUT_FUNC) LOOKUP_COEFFS				 \
+			     VANILLA_YUV2RGB_PIXEL(py[0], ruv, guv, buv) \
+			     OUTPUT_FUNC(dst, r, g, b)  
+
+YUV_CONVERT(yuv444_to_rgba_vanilla, CONVERT(VANILLA_RGBA_OUT), VANILLA_RGBA_OUT, 1, 4, 1, 1, 1)
+YUV_CONVERT(yuv444_to_bgra_vanilla, CONVERT(VANILLA_BGRA_OUT), VANILLA_BGRA_OUT, 1, 4, 1, 1, 1)
+YUV_CONVERT(yuv444_to_abgr_vanilla, CONVERT(VANILLA_ABGR_OUT), VANILLA_ABGR_OUT, 1, 4, 1, 1, 1)
+YUV_CONVERT(yuv444_to_argb_vanilla, CONVERT(VANILLA_ARGB_OUT), VANILLA_ARGB_OUT, 1, 4, 1, 1, 1)
 
 #undef CONVERT
 #undef CLEANUP
 
+#ifndef DISABLE_CPU_FEATURES
 /* although we use cpu runtime detection, we still need these
  * macros as there's no way e.g. we could compile a x86 asm code 
  * on a ppc machine and vica-versa
  */
-#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
+#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64)
+#if !defined(_M_AMD64)
+#define ENABLE_MMX
+#endif
 #include "x86/oggplay_yuv2rgb_x86.c"
+#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
+#define ENABLE_SSE2
+#endif
 #elif defined(__ppc__) || defined(__ppc64__)
+#define ENABLE_ALTIVEC
 //altivec intristics only working with -maltivec gcc flag, 
 //but we want runtime altivec detection, hence this has to be
 //fixed!
 //#include "oggplay_yuv2rgb_altivec.c"
 #endif
+#endif
 
 
 /**
  * Initialize the lookup-table for vanilla yuv to rgb conversion.
  */
 static void
 init_vanilla_coeffs (void)
 {
@@ -176,90 +216,145 @@ init_vanilla_coeffs (void)
  * Initialize the function pointers in yuv_conv, based on the
  * the available CPU extensions.
  */
 static void
 init_yuv_converters(void)
 {
 	ogg_uint32_t features = 0;
 
-	if ( yuv_conv.yuv2rgba == NULL )
+	if ( yuv_conv.yuv420rgba == NULL )
 	{
 		init_vanilla_coeffs ();
-		features = oc_cpu_flags_get(); 		
-#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
-#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
+#ifndef DISABLE_CPU_FEATURES
+		features = oc_cpu_flags_get(); 
+#endif
+#ifdef ENABLE_SSE2	
 		if (features & OC_CPU_X86_SSE2) 
 		{
-			yuv_conv.yuv2rgba = yuv420_to_rgba_sse2;
-			yuv_conv.yuv2bgra = yuv420_to_bgra_sse2;
-			yuv_conv.yuv2argb = yuv420_to_argb_sse2;
+			yuv_conv.yuv420rgba = yuv420_to_rgba_sse2;
+			yuv_conv.yuv420bgra = yuv420_to_bgra_sse2;
+			yuv_conv.yuv420argb = yuv420_to_argb_sse2;
+			yuv_conv.yuv422rgba = yuv422_to_rgba_sse2;
+			yuv_conv.yuv422bgra = yuv422_to_bgra_sse2;
+			yuv_conv.yuv422argb = yuv422_to_argb_sse2;
+			yuv_conv.yuv444rgba = yuv444_to_rgba_sse2;
+  		yuv_conv.yuv444bgra = yuv444_to_bgra_sse2;
+  		yuv_conv.yuv444argb = yuv444_to_argb_sse2;
 			return;
 		}
+#endif /* SSE2 */
+#ifdef ENABLE_MMX
+#ifndef ENABLE_SSE2
 		else
-#endif /* ATTRIBUTE_ALIGNED_MAX */
+#endif
 		if (features & OC_CPU_X86_MMXEXT)	
 		{
-			yuv_conv.yuv2rgba = yuv420_to_rgba_sse;
-			yuv_conv.yuv2bgra = yuv420_to_bgra_sse;
-			yuv_conv.yuv2argb = yuv420_to_argb_sse;
+			yuv_conv.yuv420rgba = yuv420_to_rgba_sse;
+			yuv_conv.yuv420bgra = yuv420_to_bgra_sse;
+			yuv_conv.yuv420argb = yuv420_to_argb_sse;
+			yuv_conv.yuv422rgba = yuv422_to_rgba_sse;
+			yuv_conv.yuv422bgra = yuv422_to_bgra_sse;
+			yuv_conv.yuv422argb = yuv422_to_argb_sse;
+			yuv_conv.yuv444rgba = yuv444_to_rgba_sse;
+  		yuv_conv.yuv444bgra = yuv444_to_bgra_sse;
+  		yuv_conv.yuv444argb = yuv444_to_argb_sse;
 			return;
 		}
 		else if (features & OC_CPU_X86_MMX)
 		{   
-			yuv_conv.yuv2rgba = yuv420_to_rgba_mmx;
-			yuv_conv.yuv2bgra = yuv420_to_bgra_mmx;
-			yuv_conv.yuv2argb = yuv420_to_argb_mmx;
+			yuv_conv.yuv420rgba = yuv420_to_rgba_mmx;
+			yuv_conv.yuv420bgra = yuv420_to_bgra_mmx;
+			yuv_conv.yuv420argb = yuv420_to_argb_mmx;
+			yuv_conv.yuv422rgba = yuv422_to_rgba_mmx;
+			yuv_conv.yuv422bgra = yuv422_to_bgra_mmx;
+			yuv_conv.yuv422argb = yuv422_to_argb_mmx;
+			yuv_conv.yuv444rgba = yuv444_to_rgba_mmx;
+  		yuv_conv.yuv444bgra = yuv444_to_bgra_mmx;
+  		yuv_conv.yuv444argb = yuv444_to_argb_mmx;
 			return;
 		}
-#elif defined(__ppc__) || defined(__ppc64__)
+#elif defined(ENABLE_ALTIVEC)		
 		if (features & OC_CPU_PPC_ALTIVEC)
 		{
-			yuv_conv.yuv2rgba = yuv420_to_abgr_vanilla;
-			yuv_conv.yuv2bgra = yuv420_to_argb_vanilla;
-			yuv_conv.yuv2argb = yuv420_to_bgra_vanilla;
+			yuv_conv.yuv420rgba = yuv420_to_abgr_vanilla;
+			yuv_conv.yuv420bgra = yuv420_to_argb_vanilla;
+			yuv_conv.yuv420argb = yuv420_to_bgra_vanilla;
+			yuv_conv.yuv422rgba = yuv422_to_abgr_vanilla;
+			yuv_conv.yuv422bgra = yuv422_to_argb_vanilla;
+			yuv_conv.yuv422argb = yuv422_to_bgra_vanilla;
+			yuv_conv.yuv444rgba = yuv444_to_abgr_vanilla;
+  		yuv_conv.yuv444bgra = yuv444_to_argb_vanilla;
+  		yuv_conv.yuv444argb = yuv444_to_bgra_vanilla;
 			return;
 		}
-#endif		
+#endif
+
 		/*
      * no CPU extension was found... using vanilla converter, with respect
      * to the endianness of the host
      */
 #if WORDS_BIGENDIAN || IS_BIG_ENDIAN 
-		yuv_conv.yuv2rgba = yuv420_to_abgr_vanilla;
-		yuv_conv.yuv2bgra = yuv420_to_argb_vanilla;
-		yuv_conv.yuv2argb = yuv420_to_bgra_vanilla;
+		yuv_conv.yuv420rgba = yuv420_to_abgr_vanilla;
+		yuv_conv.yuv420bgra = yuv420_to_argb_vanilla;
+		yuv_conv.yuv420argb = yuv420_to_bgra_vanilla;
+		yuv_conv.yuv422rgba = yuv422_to_abgr_vanilla;
+		yuv_conv.yuv422bgra = yuv422_to_argb_vanilla;
+		yuv_conv.yuv422argb = yuv422_to_bgra_vanilla;
+		yuv_conv.yuv444rgba = yuv444_to_abgr_vanilla;
+		yuv_conv.yuv444bgra = yuv444_to_argb_vanilla;
+		yuv_conv.yuv444argb = yuv444_to_bgra_vanilla;
 #else
-		yuv_conv.yuv2rgba = yuv420_to_rgba_vanilla;
-		yuv_conv.yuv2bgra = yuv420_to_bgra_vanilla;
-		yuv_conv.yuv2argb = yuv420_to_argb_vanilla;
+		yuv_conv.yuv420rgba = yuv420_to_rgba_vanilla;
+		yuv_conv.yuv420bgra = yuv420_to_bgra_vanilla;
+		yuv_conv.yuv420argb = yuv420_to_argb_vanilla;
+		yuv_conv.yuv422rgba = yuv422_to_rgba_vanilla;
+		yuv_conv.yuv422bgra = yuv422_to_bgra_vanilla;
+		yuv_conv.yuv422argb = yuv422_to_argb_vanilla;
+		yuv_conv.yuv444rgba = yuv444_to_rgba_vanilla;
+		yuv_conv.yuv444bgra = yuv444_to_bgra_vanilla;
+		yuv_conv.yuv444argb = yuv444_to_argb_vanilla;
 #endif
 	}
 }
 
 
 void
 oggplay_yuv2rgba(const OggPlayYUVChannels* yuv, OggPlayRGBChannels* rgb)
 {
-	if (yuv_conv.yuv2rgba == NULL)
-		init_yuv_converters();
+	if (yuv_conv.yuv420rgba == NULL)
+ 		init_yuv_converters();
 
-	yuv_conv.yuv2rgba(yuv, rgb);
+	if (yuv->y_height!=yuv->uv_height)
+		yuv_conv.yuv420rgba(yuv, rgb);
+	else if (yuv->y_width!=yuv->uv_width)
+		yuv_conv.yuv422rgba(yuv,rgb);
+	else
+		yuv_conv.yuv444rgba(yuv,rgb);
 }
 
 void 
 oggplay_yuv2bgra(const OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb)
 {
-	if (yuv_conv.yuv2bgra == NULL)
-		init_yuv_converters();
+	if (yuv_conv.yuv420bgra == NULL)
+ 		init_yuv_converters();
 
-	yuv_conv.yuv2bgra(yuv, rgb);
-}
+	if (yuv->y_height!=yuv->uv_height)
+		yuv_conv.yuv420bgra(yuv, rgb);
+	else if (yuv->y_width!=yuv->uv_width)
+		yuv_conv.yuv422bgra(yuv,rgb);
+	else
+		yuv_conv.yuv444bgra(yuv,rgb);}
 
 void 
 oggplay_yuv2argb(const OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb)
 {
-	if (yuv_conv.yuv2argb == NULL)
-		init_yuv_converters();
+	if (yuv_conv.yuv420argb == NULL)
+ 		init_yuv_converters();
 
-	yuv_conv.yuv2argb(yuv, rgb);
+	if (yuv->y_height!=yuv->uv_height)
+		yuv_conv.yuv420argb(yuv, rgb);
+	else if (yuv->y_width!=yuv->uv_width)
+		yuv_conv.yuv422argb(yuv,rgb);
+	else
+		yuv_conv.yuv444argb(yuv,rgb);
 }
 
--- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
+++ b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb_template.h
@@ -14,18 +14,19 @@
  *
  * @param FUNC function name
  * @param CONVERT a macro that defines the actual conversion function
  * @param VANILLA_OUT 
  * @param NUM_PIXELS number of pixels processed in one iteration
  * @param OUT_SHIFT number of pixels to shift after one iteration in rgb data stream
  * @param Y_SHIFT number of pixels to shift after one iteration in Y data stream
  * @param UV_SHIFT
+ * @param UV_VERT_SUB
  */
-#define YUV_CONVERT(FUNC, CONVERT, VANILLA_OUT, NUM_PIXELS, OUT_SHIFT, Y_SHIFT, UV_SHIFT)\
+#define YUV_CONVERT(FUNC, CONVERT, VANILLA_OUT, NUM_PIXELS, OUT_SHIFT, Y_SHIFT, UV_SHIFT, UV_VERT_SUB)\
 static void                                                     \
 (FUNC)(const OggPlayYUVChannels* yuv, OggPlayRGBChannels* rgb)  \
 {                                                               \
 	int             i,j, w, h, r;                           \
 	unsigned char*  restrict ptry;                          \
 	unsigned char*  restrict ptru;                          \
 	unsigned char*  restrict ptrv;                          \
 	unsigned char*  restrict ptro;                          \
@@ -55,47 +56,51 @@ static void                             
 			CONVERT                                 \
 		}                                               \
 		/*						\
 		 * the video frame is not the multiple of NUM_PIXELS, \
 		 * thus we have to deal with remaning pixels using 	\
 		 * vanilla implementation.				\
 		 */						\
 		if (r) { 					\
-			/* if there's only 1 remaining pixel to process  \
-			   and the luma width is odd, the for loop above \
-			   has already advanced pu and pv too far. */    \
-			if (r==1 && yuv->y_width&1) {           \
+			if (r==1 && yuv->y_width&1) {		\
 				pu -= 1; pv -= 1;               \
-			}                                       \
+			}					\
+								\
 			for 					\
 			( 					\
 			  j=(yuv->y_width-r); j < yuv->y_width; \
 			  ++j, 					\
 			  dst += 4,				\
 			  py += 1 				\
 			) 					\
 			{ 					\
 				LOOKUP_COEFFS			\
 				VANILLA_YUV2RGB_PIXEL(py[0], ruv, guv, buv) \
 				VANILLA_OUT(dst, r, g, b)	\
-				/* advance chroma ptrs every second sample, except \
-				   when the luma width is odd, in which case the   \
-				   chroma samples are truncated and we must reuse  \
-				   the previous chroma sample */                   \
-				if (j%2 && !(j+1==yuv->y_width-1 && yuv->y_width&1)) { \
+				if 				\
+				(				\
+				  (j%2 && !(j+1==yuv->y_width-1 && yuv->y_width&1)) \
+				  ||				\
+				  UV_VERT_SUB==1		\
+				) { 				\
 					pu += 1; pv += 1;	\
 				} 				\
 			}					\
 		} 						\
 								\
 		ptro += rgb->rgb_width * 4;                     \
 		ptry += yuv->y_width;                           \
 								\
-		if (i & 0x1 && !(i+1==h-1 && h&1))              \
+		if 						\
+		(						\
+		  (i & 0x1 && !(i+1==h-1 && h&1))		\
+		  ||						\
+		  UV_VERT_SUB==1				\
+		)		            			\
 		{                                               \
 			ptru += yuv->uv_width;                  \
 			ptrv += yuv->uv_width;                  \
 		}                                               \
 	}                                                       \
 	CLEANUP                                                 \
 }  
 
--- a/media/liboggplay/src/liboggplay/std_semaphore.h
+++ b/media/liboggplay/src/liboggplay/std_semaphore.h
@@ -69,19 +69,23 @@
  *
  * Macro that closes a given semaphore.
  *
  * @param p semaphore handle
  * @retval 0 on success
  * @retval non-zero on error 
  */
 
-#if defined(linux) || defined(SOLARIS)
+#if defined(linux) || defined(SOLARIS) || defined(AIX) || defined(__FreeBSD__)
 #include <semaphore.h>
+#if defined(__FreeBSD__) 
+#define SEM_CREATE(p,s) sem_init(&(p), 0, s)  
+#else
 #define SEM_CREATE(p,s) sem_init(&(p), 1, s)
+#endif
 #define SEM_SIGNAL(p)   sem_post(&(p))
 #define SEM_WAIT(p)     sem_wait(&(p))
 #define SEM_CLOSE(p)    sem_destroy(&(p))
 typedef sem_t           semaphore;
 #elif defined(WIN32)
 #include <windows.h>
 #define SEM_CREATE(p,s) (!(p = CreateSemaphore(NULL, (long)(s), (long)(s), NULL)))
 #define SEM_SIGNAL(p)   (!ReleaseSemaphore(p, 1, NULL))
--- a/media/liboggplay/src/liboggplay/x86/oggplay_yuv2rgb_x86.c
+++ b/media/liboggplay/src/liboggplay/x86/oggplay_yuv2rgb_x86.c
@@ -33,16 +33,20 @@
 /**
  * YUV to RGB conversion using x86 CPU extensions
  */
 #include "oggplay_private.h"
 #include "oggplay_yuv2rgb_template.h"
 #include "cpu.h"
 
 #if defined(_MSC_VER)
+# if defined(_M_AMD64)
+  /* MSVC with x64 doesn't support inline assembler */
+#include <emmintrin.h>
+# endif
 #include "yuv2rgb_x86_vs.h" 
 #elif defined(__GNUC__)
 #include "yuv2rgb_x86.h" 
 #endif
 
 typedef union
 {
 	long long               q[2];
@@ -76,77 +80,111 @@ static const simd_t simd_table[9] = {
 	{{BU_Co, BU_Co}},
 	{{RV_Co, RV_Co}},
 	{{Y_16, Y_16}},
 	{{Y_Co, Y_Co}},
 	{{Y_MASK, Y_MASK}},
 	{{ALFA, ALFA}}
 };
 
+/* MMX intristics are not supported by VS in x64 mode, thus disable it */
+#if !(defined(_MSC_VER) && defined(_M_AMD64))
 /**
  *  the conversion functions using MMX instructions 
  */
 
 /* template for the MMX conversion functions */
-#define YUV_CONVERT_MMX(FUNC, CONVERT, CONV_BY_PIXEL) YUV_CONVERT(FUNC, CONVERT, CONV_BY_PIXEL, 8, 32, 8, 4)
+#define YUV_CONVERT_MMX(FUNC, CONVERT, CONV_BY_PIXEL, UV_SHIFT, UV_VERT_SUB) YUV_CONVERT(FUNC, CONVERT, CONV_BY_PIXEL, 8, 32, 8, UV_SHIFT, UV_VERT_SUB)
 
 #define CLEANUP emms()
 #define OUT_RGBA_32 OUTPUT_RGBA_32(movq, mm, 8, 16, 24)
 #define OUT_ARGB_32 OUTPUT_ARGB_32(movq, mm, 8, 16, 24)
 #define OUT_BGRA_32 OUTPUT_BGRA_32(movq, mm, 8, 16, 24)
 #define MOVNTQ MMX_MOVNTQ
 
 /* yuv420 -> */
 #define CONVERT(OUTPUT_FUNC) LOAD_YUV_PLANAR_2(movq, mm) \
                              YUV_2_RGB(movq, mm) 	\
                              OUTPUT_FUNC
 
-YUV_CONVERT_MMX(yuv420_to_rgba_mmx, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT)
-YUV_CONVERT_MMX(yuv420_to_bgra_mmx, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT) 
-YUV_CONVERT_MMX(yuv420_to_argb_mmx, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT) 
+YUV_CONVERT_MMX(yuv420_to_rgba_mmx, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT, 4, 2)
+YUV_CONVERT_MMX(yuv420_to_bgra_mmx, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT, 4, 2) 
+YUV_CONVERT_MMX(yuv420_to_argb_mmx, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT, 4, 2) 
+
+YUV_CONVERT_MMX(yuv422_to_rgba_mmx, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT, 4, 1)
+YUV_CONVERT_MMX(yuv422_to_bgra_mmx, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT, 4, 1) 
+YUV_CONVERT_MMX(yuv422_to_argb_mmx, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT, 4, 1)
+
+YUV_CONVERT_MMX(yuv444_to_rgba_mmx, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT, 8, 1)
+YUV_CONVERT_MMX(yuv444_to_bgra_mmx, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT, 8, 1) 
+YUV_CONVERT_MMX(yuv444_to_argb_mmx, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT, 8, 1)
 
 #undef MOVNTQ
 
 
 /* template for the SSE conversion functions */
 #define MOVNTQ SSE_MOVNTQ
 
-YUV_CONVERT_MMX(yuv420_to_rgba_sse, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT)
-YUV_CONVERT_MMX(yuv420_to_bgra_sse, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT)
-YUV_CONVERT_MMX(yuv420_to_argb_sse, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT)
+YUV_CONVERT_MMX(yuv420_to_rgba_sse, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT, 4, 2)
+YUV_CONVERT_MMX(yuv420_to_bgra_sse, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT, 4, 2)
+YUV_CONVERT_MMX(yuv420_to_argb_sse, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT, 4, 2)
+
+YUV_CONVERT_MMX(yuv422_to_rgba_sse, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT, 4, 1)
+YUV_CONVERT_MMX(yuv422_to_bgra_sse, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT, 4, 1)
+YUV_CONVERT_MMX(yuv422_to_argb_sse, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT, 4, 1)
+
+YUV_CONVERT_MMX(yuv444_to_rgba_sse, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT, 8, 1)
+YUV_CONVERT_MMX(yuv444_to_bgra_sse, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT, 8, 1)
+YUV_CONVERT_MMX(yuv444_to_argb_sse, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT, 8, 1)
 
 #undef CONVERT
 #undef CLEANUP
 #undef OUT_RGBA_32
 #undef OUT_ARGB_32
 #undef OUT_BGRA_32
 #undef MOVNTQ
+#endif
 
 
 /**
  *  the conversion functions using SSE2 instructions 
  */
 
 /* template for the SSE2 conversion functions */
-#define YUV_CONVERT_SSE2(FUNC, CONVERT, CONV_BY_PIX) YUV_CONVERT(FUNC, CONVERT, CONV_BY_PIX, 16, 64, 16, 8)
+#define YUV_CONVERT_SSE2(FUNC, CONVERT, CONV_BY_PIX, UV_SHIFT, UV_VERT_SUB) YUV_CONVERT(FUNC, CONVERT, CONV_BY_PIX, 16, 64, 16, UV_SHIFT, UV_VERT_SUB)
 
 #define OUT_RGBA_32 OUTPUT_RGBA_32(movdqa, xmm, 16, 32, 48)
 #define OUT_ARGB_32 OUTPUT_ARGB_32(movdqa, xmm, 16, 32, 48)
 #define OUT_BGRA_32 OUTPUT_BGRA_32(movdqa, xmm, 16, 32, 48)
 #define MOVNTQ SSE2_MOVNTQ
 #define CLEANUP
 
 /* yuv420 -> */
+#if defined(_MSC_VER) && defined(_M_AMD64)
+#define CONVERT(OUTPUT_FUNC) __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; \
+				LOAD_YUV_PLANAR_2(movdqu, xmm) \
+				YUV_2_RGB(movdqa, xmm)	\
+				OUTPUT_FUNC
+#else
 #define CONVERT(OUTPUT_FUNC) LOAD_YUV_PLANAR_2(movdqu, xmm) \
 				YUV_2_RGB(movdqa, xmm)	\
 				OUTPUT_FUNC
+#endif
+				
+YUV_CONVERT_SSE2(yuv420_to_rgba_sse2, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT, 8, 2)
+YUV_CONVERT_SSE2(yuv420_to_bgra_sse2, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT, 8, 2)
+YUV_CONVERT_SSE2(yuv420_to_argb_sse2, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT, 8, 2)
 
-YUV_CONVERT_SSE2(yuv420_to_rgba_sse2, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT)
-YUV_CONVERT_SSE2(yuv420_to_bgra_sse2, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT)
-YUV_CONVERT_SSE2(yuv420_to_argb_sse2, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT)
+YUV_CONVERT_SSE2(yuv422_to_rgba_sse2, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT, 8, 1)
+YUV_CONVERT_SSE2(yuv422_to_bgra_sse2, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT, 8, 1)
+YUV_CONVERT_SSE2(yuv422_to_argb_sse2, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT, 8, 1)
+
+YUV_CONVERT_SSE2(yuv444_to_rgba_sse2, CONVERT(OUT_RGBA_32), VANILLA_RGBA_OUT, 16, 1)
+YUV_CONVERT_SSE2(yuv444_to_bgra_sse2, CONVERT(OUT_BGRA_32), VANILLA_BGRA_OUT, 16, 1)
+YUV_CONVERT_SSE2(yuv444_to_argb_sse2, CONVERT(OUT_ARGB_32), VANILLA_ARGB_OUT, 16, 1)
 
 #undef CONVERT
 #undef OUT_RGBA_32
 #undef OUT_ARGB_32
 #undef OUT_BGRA_32
 #undef MOVNTQ
 #undef CLEANUP
 
--- a/media/liboggplay/src/liboggplay/x86/yuv2rgb_x86_vs.h
+++ b/media/liboggplay/src/liboggplay/x86/yuv2rgb_x86_vs.h
@@ -3,27 +3,38 @@
 
 #define ATTR_ALIGN(_align) __declspec(align(_align))
 
 #define emms() __asm emms
 #define MMX_MOVNTQ movq
 #define SSE_MOVNTQ movntq
 #define SSE2_MOVNTQ movdqu
 
+#if defined(_M_IX86)
 #define LOAD_YUV_PLANAR_2(mov_instr, reg_type)		\
 	__asm {								\
 		__asm mov	eax, py					\
 		__asm mov	edx, pu					\
 		__asm mov_instr	reg_type##6, [eax]			\
 		__asm mov_instr	reg_type##0, [edx]			\
 		__asm mov	eax, pv					\
 		__asm mov_instr	reg_type##1, [eax]			\
 		__asm pxor	reg_type##4, reg_type##4		\
 	}
+#elif defined(_M_AMD64)
+#define LOAD_YUV_PLANAR_2(mov_instr, reg_type)		\
+	{								\
+		xmm6 = _mm_loadu_si128((__m128i*)py);			\
+		xmm0 = _mm_loadu_si128((__m128i*)pu);			\
+		xmm1 = _mm_loadu_si128((__m128i*)pv);			\
+		xmm4 = _mm_setzero_si128();				\
+	}
+#endif
 
+#if defined(_M_IX86)
 #define OUTPUT_RGBA_32(mov_instr, reg_type, offset0, offset1, offset2) \
 	__asm {								\
 		__asm mov	eax, dst				\
 		__asm mov_instr	reg_type##3, [simd_table+128]		\
 		__asm mov_instr reg_type##4, reg_type##1		\
 		__asm mov_instr reg_type##5, reg_type##0		\
 		__asm punpcklbw reg_type##1, reg_type##2		\
 		__asm punpcklbw reg_type##0, reg_type##3		\
@@ -35,17 +46,36 @@
 		__asm punpckhwd reg_type##6, reg_type##0                \
 		__asm punpcklwd reg_type##4, reg_type##5                \
 		__asm punpckhwd reg_type##7, reg_type##5                \
 		__asm MOVNTQ	[eax], reg_type##1			\
 		__asm MOVNTQ	[eax+offset0], reg_type##6		\
 		__asm MOVNTQ	[eax+offset1], reg_type##4		\
 		__asm MOVNTQ	[eax+offset2], reg_type##7		\
 	}
+#elif defined(_M_AMD64)
+#define OUTPUT_RGBA_32(mov_instr, reg_type, offset0, offset1, offset2) \
+	{								\
+		xmm3 = _mm_load_si128((__m128i*)simd_table+8);		\
+		xmm4 = _mm_unpackhi_epi8(xmm1, xmm2);			\
+		xmm1 = _mm_unpacklo_epi8(xmm1, xmm2);			\
+		xmm5 = _mm_unpackhi_epi8(xmm0, xmm3);			\
+		xmm0 = _mm_unpacklo_epi8(xmm0, xmm3);			\
+		xmm6 = _mm_unpackhi_epi8(xmm1, xmm0);			\
+		xmm1 = _mm_unpacklo_epi8(xmm1, xmm0);			\
+		xmm7 = _mm_unpackhi_epi8(xmm4, xmm5);			\
+		xmm4 = _mm_unpacklo_epi8(xmm4, xmm5);			\
+		_mm_storeu_si128(dst, xmm1);				\
+		_mm_storeu_si128(dst + offset0, xmm6);			\
+		_mm_storeu_si128(dst + offset1, xmm4);			\
+		_mm_storeu_si128(dst + offset2, xmm7);			\
+	}
+#endif
 
+#if defined(_M_IX86)
 #define OUTPUT_ARGB_32(mov_instr, reg_type, offset0, offset1, offset2) \
 	__asm {								\
 		__asm mov	eax, dst				\
 		__asm mov_instr	reg_type##3, [simd_table+128]		\
 		__asm mov_instr reg_type##4, reg_type##3		\
 		__asm mov_instr reg_type##5, reg_type##2		\
 		__asm punpcklbw reg_type##2, reg_type##0		\
 		__asm punpcklbw reg_type##3, reg_type##1		\
@@ -57,17 +87,36 @@
 		__asm punpckhwd reg_type##0, reg_type##2                \
 		__asm punpcklwd reg_type##4, reg_type##5                \
 		__asm punpckhwd reg_type##1, reg_type##5                \
 		__asm MOVNTQ	[eax], reg_type##3			\
 		__asm MOVNTQ	[eax+offset0], reg_type##0		\
 		__asm MOVNTQ	[eax+offset1], reg_type##4		\
 		__asm MOVNTQ	[eax+offset2], reg_type##1		\
 	}
+#elif defined(_M_AMD64)
+#define OUTPUT_ARGB_32(mov_instr, reg_type, offset0, offset1, offset2) \
+	{								\
+		xmm3 = _mm_load_si128((__m128i*)simd_table+8);		\
+		xmm5 = _mm_unpackhi_epi8(xmm2, xmm0);			\
+		xmm2 = _mm_unpacklo_epi8(xmm2, xmm0);			\
+		xmm4 = _mm_unpackhi_epi8(xmm3, xmm1);			\
+		xmm3 = _mm_unpacklo_epi8(xmm3, xmm1);			\
+		xmm0 = _mm_unpackhi_epi16(xmm3, xmm2);			\
+		xmm3 = _mm_unpacklo_epi16(xmm3, xmm2);			\
+		xmm1 = _mm_unpackhi_epi16(xmm4, xmm5);			\
+		xmm4 = _mm_unpacklo_epi16(xmm4, xmm5);			\
+		_mm_storeu_si128(dst, xmm3);				\
+		_mm_storeu_si128(dst + offset0, xmm0);			\
+		_mm_storeu_si128(dst + offset1, xmm4);			\
+		_mm_storeu_si128(dst + offset2, xmm1);			\
+	}
+#endif
 
+#if defined(_M_IX86)
 #define OUTPUT_BGRA_32(mov_instr, reg_type, offset0, offset1, offset2) \
 	__asm {								\
 		__asm mov	eax, dst				\
 		__asm mov_instr	reg_type##3, [simd_table+128]		\
 		__asm mov_instr reg_type##4, reg_type##0		\
 		__asm mov_instr reg_type##5, reg_type##1		\
 		__asm punpcklbw reg_type##0, reg_type##2		\
 		__asm punpcklbw reg_type##1, reg_type##3		\
@@ -79,17 +128,36 @@
 		__asm punpckhwd reg_type##6, reg_type##1                \
 		__asm punpcklwd reg_type##4, reg_type##5                \
 		__asm punpckhwd reg_type##7, reg_type##5                \
 		__asm MOVNTQ	[eax], reg_type##0			\
 		__asm MOVNTQ	[eax+offset0], reg_type##6		\
 		__asm MOVNTQ	[eax+offset1], reg_type##4		\
 		__asm MOVNTQ	[eax+offset2], reg_type##7		\
 	}
+#elif defined(_M_AMD64)
+#define OUTPUT_BGRA_32(mov_instr, reg_type, offset0, offset1, offset2) \
+	{								\
+		xmm3 = _mm_load_si128((__m128i*)simd_table+8);		\
+		xmm4 = _mm_unpackhi_epi8(xmm0, xmm2);			\
+		xmm0 = _mm_unpacklo_epi8(xmm0, xmm2);			\
+		xmm5 = _mm_unpackhi_epi8(xmm1, xmm3);			\
+		xmm1 = _mm_unpacklo_epi8(xmm1, xmm3);			\
+		xmm6 = _mm_unpackhi_epi8(xmm0, xmm1);			\
+		xmm0 = _mm_unpacklo_epi8(xmm0, xmm1);			\
+		xmm7 = _mm_unpackhi_epi8(xmm4, xmm5);			\
+		xmm4 = _mm_unpacklo_epi8(xmm4, xmm5);			\
+		_mm_storeu_si128(dst, xmm0);				\
+		_mm_storeu_si128(dst + offset0, xmm6);			\
+		_mm_storeu_si128(dst + offset1, xmm4);			\
+		_mm_storeu_si128(dst + offset2, xmm7);			\
+	}
+#endif
 
+#if defined(_M_IX86)
 #define YUV_2_RGB(mov_instr, reg_type) \
 	__asm {											\
 		__asm punpcklbw reg_type##0, reg_type##4	/* mm0 = u3 u2 u1 u0 */\
 		__asm punpcklbw reg_type##1, reg_type##4	/* mm1 = v3 v2 v1 v0 */\
 		__asm psubsw	reg_type##0, [simd_table]	/* u -= 128 */\
 		__asm psubsw	reg_type##1, [simd_table]	/* v -= 128 */\
 		__asm psllw	reg_type##0, 3			/* promote precision */\
 		__asm psllw	reg_type##1, 3			/* promote precision */\
@@ -122,11 +190,53 @@
 		__asm packuswb	reg_type##2, reg_type##2	/* saturate to 0-255 */\
 		__asm packuswb	reg_type##3, reg_type##3	/* saturate to 0-255 */\
 		__asm packuswb	reg_type##4, reg_type##4	/* saturate to 0-255 */\
 		__asm packuswb	reg_type##5, reg_type##5	/* saturate to 0-255 */\
 		__asm punpcklbw	reg_type##0, reg_type##3	/* mm0 = B7 B6 B5 B4 B3 B2 B1 B0 */\
 		__asm punpcklbw	reg_type##1, reg_type##4	/* mm1 = R7 R6 R5 R4 R3 R2 R1 R0 */\
 		__asm punpcklbw	reg_type##2, reg_type##5	/* mm2 = G7 G6 G5 G4 G3 G2 G1 G0 */\
 	}
+#elif defined(_M_AMD64)
+#define YUV_2_RGB(mov_instr, reg_type) \
+	{									\
+		xmm0 = _mm_unpacklo_epi8(xmm0, xmm4);					/* mm0 = u3 u2 u1 u0 */\
+		xmm1 = _mm_unpacklo_epi8(xmm1, xmm4);					/* mm1 = v3 v2 v1 v0 */\
+		xmm0 = _mm_subs_epi16(xmm0, _mm_load_si128((__m128i*)simd_table));	/* u -= 128 */\
+		xmm1 = _mm_subs_epi16(xmm1, _mm_load_si128((__m128i*)simd_table));	/* v -= 128 */\
+		xmm0 = _mm_slli_epi16(xmm0, 3);						/* promote precision */\
+		xmm1 = _mm_slli_epi16(xmm1, 3);						/* promote precision */\
+		xmm2 = _mm_mulhi_epi16(xmm0, _mm_load_si128((__m128i*)simd_table+1));	/* mm2 = u * u_green */\
+		xmm3 = _mm_mulhi_epi16(xmm1, _mm_load_si128((__m128i*)simd_table+2));	/* mm3 = v * v_green */\
+		xmm0 = _mm_mulhi_epi16(xmm0, _mm_load_si128((__m128i*)simd_table+3));	/* mm0 = chroma_b */\
+		xmm1 = _mm_mulhi_epi16(xmm1, _mm_load_si128((__m128i*)simd_table+4));	/* mm1 = chroma_r */\
+		xmm2 = _mm_adds_epi16(xmm2, xmm3);					/* mm2 = chroma_g */\
+		xmm6 = _mm_subs_epu8(xmm6, _mm_load_si128((__m128i*)simd_table+5));		/* Y -= 16  */\
+		xmm7 = xmm6;								/* mm7 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */\
+		xmm6 = _mm_and_si128(xmm6, _mm_load_si128((__m128i*)simd_table+7);	/* mm6 =    Y6    Y4    Y2    Y0 */\
+		xmm7 = _mm_srli_epi16(xmm7, 8);						/* mm7 =    Y7    Y5    Y3    Y1 */\
+		xmm6 = _mm_slli_epi16(xmm6, 3);						/* promote precision */\
+		xmm7 = _mm_slli_epi16(xmm7, 3);						/* promote precision */\
+		xmm6 = _mm_mulhi_epi16(xmm6, _mm_load_si128((__m128i*)simd_table+6));	/* mm6 = luma_rgb even */\
+		xmm7 = _mm_mulhi_epi16(xmm7, _mm_load_si128((__m128i*)simd_table+6));	/* mm7 = luma_rgb odd */\
+		xmm3 = xmm0;								/* mm3 = chroma_b */\
+		xmm4 = xmm1;								/* mm4 = chroma_r */\
+		xmm5 = xmm2;								/* mm5 = chroma_g */\
+		xmm0 = _mm_adds_epi16(xmm0, xmm6);					/* mm0 = B6 B4 B2 B0 */\
+		xmm3 = _mm_adds_epi16(xmm3, xmm7);					/* mm3 = B7 B5 B3 B1 */\
+		xmm1 = _mm_adds_epi16(xmm1, xmm6);					/* mm1 = R6 R4 R2 R0 */\
+		xmm4 = _mm_adds_epi16(xmm4, xmm7);					/* mm4 = R7 R5 R3 R1 */\
+		xmm2 = _mm_adds_epi16(xmm2, xmm6);					/* mm2 = G6 G4 G2 G0 */\
+		xmm5 = _mm_adds_epi16(xmm5, xmm7);					/* mm5 = G7 G5 G3 G1 */\
+		xmm0 = _mm_packus_epi16(xmm0, xmm0);					/* saturate to 0-255 */\
+		xmm1 = _mm_packus_epi16(xmm1, xmm1);					/* saturate to 0-255 */\
+		xmm2 = _mm_packus_epi16(xmm2, xmm2);					/* saturate to 0-255 */\
+		xmm3 = _mm_packus_epi16(xmm3, xmm3);					/* saturate to 0-255 */\
+		xmm4 = _mm_packus_epi16(xmm4, xmm4);					/* saturate to 0-255 */\
+		xmm5 = _mm_packus_epi16(xmm5, xmm5);					/* saturate to 0-255 */\
+		xmm0 = _mm_unpacklo_epi8(xmm0, xmm3);					/* mm0 = B7 B6 B5 B4 B3 B2 B1 B0 */\
+		xmm1 = _mm_unpacklo_epi8(xmm1, xmm4);					/* mm1 = R7 R6 R5 R4 R3 R2 R1 R0 */\
+		xmm2 = _mm_unpacklo_epi8(xmm2, xmm5);					/* mm2 = G7 G6 G5 G4 G3 G2 G1 G0 */\
+	}
+#endif
 
 #endif
 
deleted file mode 100644
--- a/media/liboggplay/trac466.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-diff --git a/media/liboggplay/src/liboggplay/oggplay.c b/media/liboggplay/src/liboggplay/oggplay.c
-index 3296fea..d6256c6 100644
---- a/media/liboggplay/src/liboggplay/oggplay.c
-+++ b/media/liboggplay/src/liboggplay/oggplay.c
-@@ -708,14 +708,15 @@ read_more_data:
-     oggplay_data_clean_list (me->decode_data[i]);
-   }
- 
-+  if (me->shutdown) {
-+    return E_OGGPLAY_OK;
-+  }
-+
-   if (info == NULL) {
-     goto read_more_data;
-   }
- 
-   me->target += me->callback_period;
--  if (me->shutdown) {
--    return E_OGGPLAY_OK;
--  }
-   if (r == -1) {
-     return E_OGGPLAY_USER_INTERRUPT;
-   }
--- a/media/liboggplay/update.sh
+++ b/media/liboggplay/update.sh
@@ -28,40 +28,27 @@ cp $1/src/liboggplay/oggplay_file_reader
 cp $1/src/liboggplay/std_semaphore.h ./src/liboggplay/std_semaphore.h
 cp $1/src/liboggplay/oggplay.c ./src/liboggplay/oggplay.c
 cp $1/src/liboggplay/oggplay_callback.h ./src/liboggplay/oggplay_callback.h
 cp $1/src/liboggplay/oggplay_tcp_reader.c ./src/liboggplay/oggplay_tcp_reader.c
 cp $1/src/liboggplay/oggplay_query.c ./src/liboggplay/oggplay_query.c
 cp $1/src/liboggplay/cpu.c ./src/liboggplay/cpu.c
 cp $1/src/liboggplay/cpu.h ./src/liboggplay/cpu.h
 cp $1/src/liboggplay/oggplay_yuv2rgb_template.h ./src/liboggplay/oggplay_yuv2rgb_template.h
-cp $1/src/liboggplay/oggplay_yuv2rgb_x86.c ./src/liboggplay/oggplay_yuv2rgb_x86.c
-cp $1/src/liboggplay/yuv2rgb_x86.h ./src/liboggplay/yuv2rgb_x86.h
-cp $1/src/liboggplay/yuv2rgb_x86_vs.h ./src/liboggplay/yuv2rgb_x86_vs.h
+cp $1/src/liboggplay/x86/oggplay_yuv2rgb_x86.c ./src/liboggplay/x86/oggplay_yuv2rgb_x86.c
+cp $1/src/liboggplay/x86/yuv2rgb_x86.h ./src/liboggplay/x86/yuv2rgb_x86.h
+cp $1/src/liboggplay/x86/yuv2rgb_x86_vs.h ./src/liboggplay/x86/yuv2rgb_x86_vs.h
 sed 's/#include "config_win32.h"//g' $1/src/liboggplay/oggplay_private.h >./src/liboggplay/oggplay_private.h1
 sed 's/#include <config.h>/#ifdef WIN32\
 #include "config_win32.h"\
 #else\
 #include <config.h>\
 #endif/g' ./src/liboggplay/oggplay_private.h1 >./src/liboggplay/oggplay_private.h
 rm ./src/liboggplay/oggplay_private.h1
 sed s/\#ifdef\ HAVE_INTTYPES_H/\#if\ HAVE_INTTYPES_H/g $1/src/liboggplay/oggplay_data.c >./src/liboggplay/oggplay_data.c
 patch -p3 < endian.patch
-patch -p3 < trac466.patch
-patch -p3 < bug492436.patch
-patch -p3 < bug493140.patch
 patch -p3 < bug481921.patch
 patch -p3 < aspect_ratio.patch
-patch -p3 < bug493678.patch
-patch -p1 < bug493224.patch
 patch -p3 < seek_to_key_frame.patch
-patch -p3 < bug488951.patch
-patch -p3 < bug488951_yuv_fix.patch
-patch -p3 < bug488951_yuv_fix_2.patch
-patch -p3 < bug495129a.patch
-patch -p3 < bug495129b.patch
-patch -p3 < bug487519.patch
+rm -f src/liboggplay/os2_semaphore.c
+rm -f src/liboggplay/os2_semaphore.h
 patch -p3 < oggplay_os2.patch
-patch -p3 < bug498815.patch
-patch -p3 < bug498824.patch
 patch -p3 < bug496529.patch
-patch -p3 < bug499519.patch
-patch -p3 < bug500311.patch