gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r9656: Fix segfault when video pitch


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r9656: Fix segfault when video pitch is not a multiple of 4. Fix segfault when
Date: Mon, 01 Sep 2008 16:35:49 +0200
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 9656
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Mon 2008-09-01 16:35:49 +0200
message:
  Fix segfault when video pitch is not a multiple of 4. Fix segfault when
  decoder setup fails for embedded video. Don't abort when an unknown codec
  is encountered; instead, log error, fail to construct a VideoDecoder, and
  continue. Also don't construct a VideoDecoder when other fatal errors
  occur.
  
  Add MediaException class for use in libmedia.
modified:
  libbase/GnashException.h
  libbase/image.cpp
  libcore/asobj/NetStreamFfmpeg.cpp
  libcore/video_stream_instance.cpp
  libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
  libmedia/ffmpeg/VideoDecoderFfmpeg.h
    ------------------------------------------------------------
    revno: 9653.1.8
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2008-09-01 12:51:19 +0200
    message:
      Set width to nearest 4-byte boundary, which fixes display (and segfaults)
      for some SWFs.
    modified:
      libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
    ------------------------------------------------------------
    revno: 9653.1.9
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2008-09-01 15:09:28 +0200
    message:
      Don't adjust image pitch to be a multiple of four bytes, as this causes
      segfaults where that's not the case. If anyone knows of a case where
      this is necessary, please let me know.
      
      Add a MediaException subclass of GnashException.
    modified:
      libbase/GnashException.h
      libbase/image.cpp
    ------------------------------------------------------------
    revno: 9653.1.10
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2008-09-01 15:10:41 +0200
    message:
      Throw an exception on construction of a VideoDecoder when a fatal error
      (such as not finding a suitable codec) means that decoding would be
      impossible. This prevents future calls to decode() when there's nothing
      to do.
      
      Catch a MediaException in NetStreamFfmpeg.cpp, log and continue.
      
      Wrap AVCodecContext so that it is always closed and freed when it exists
      when VideoDecoder is destroyed. This could also be used for AudioDecoder.
    modified:
      libcore/asobj/NetStreamFfmpeg.cpp
      libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
      libmedia/ffmpeg/VideoDecoderFfmpeg.h
    ------------------------------------------------------------
    revno: 9653.1.11
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2008-09-01 15:24:45 +0200
    message:
      If there's no decoder, don't try to use it.
    modified:
      libcore/video_stream_instance.cpp
    ------------------------------------------------------------
    revno: 9653.1.12
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2008-09-01 15:30:43 +0200
    message:
      Use the actual codec, not 0 (was for testing). Improve logging text.
    modified:
      libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
=== modified file 'libbase/GnashException.h'
--- a/libbase/GnashException.h  2008-06-11 19:54:43 +0000
+++ b/libbase/GnashException.h  2008-09-01 13:09:28 +0000
@@ -49,8 +49,27 @@
        std::string _msg;
 };
 
+class MediaException : public GnashException
+{
+
+public:
+
+       MediaException(const std::string& s)
+               :
+               GnashException(s)
+       {}
+
+       MediaException()
+               :
+               GnashException("Media error")
+       {}
+
+       virtual ~MediaException() throw() {}
+
+};
+
 /// An SWF parsing exception 
-class ParserException: public GnashException
+class ParserException : public GnashException
 {
 
 public:

=== modified file 'libbase/image.cpp'
--- a/libbase/image.cpp 2008-08-18 23:53:04 +0000
+++ b/libbase/image.cpp 2008-09-01 13:09:28 +0000
@@ -104,13 +104,10 @@
        ImageRGB::ImageRGB(int width, int height)
                :
                ImageBase( width, height,
-                       (width * 3 + 3) & ~3, // round pitch up to nearest 
4-byte boundary
-                       GNASH_IMAGE_RGB)
+                       width * 3, GNASH_IMAGE_RGB)
        {
                assert(width > 0);
                assert(height > 0);
-               assert(_pitch >= _width * 3);
-               assert((_pitch & 3) == 0);
        }
 
        ImageRGB::~ImageRGB()

=== modified file 'libcore/asobj/NetStreamFfmpeg.cpp'
--- a/libcore/asobj/NetStreamFfmpeg.cpp 2008-08-27 11:07:07 +0000
+++ b/libcore/asobj/NetStreamFfmpeg.cpp 2008-09-01 13:10:41 +0000
@@ -199,9 +199,13 @@
 
        assert ( _mediaHandler ); // caller should check this
 
-       _videoDecoder = _mediaHandler->createVideoDecoder(*videoInfo);
-       if ( ! _videoDecoder.get() )
-               log_error(_("Could not create video decoder for codec %d"), 
videoInfo->codec);
+    try {
+           _videoDecoder = _mediaHandler->createVideoDecoder(*videoInfo);
+       }
+       catch (MediaException& e) {
+           log_error("Could not create Video decoder: %s", e.what());
+       }
+
 }
 
 

=== modified file 'libcore/video_stream_instance.cpp'
--- a/libcore/video_stream_instance.cpp 2008-08-18 23:53:04 +0000
+++ b/libcore/video_stream_instance.cpp 2008-09-01 13:24:45 +0000
@@ -161,7 +161,6 @@
 void
 video_stream_instance::initializeDecoder()
 {
-       //if ( _decoder.get() ) return; // already initialized
 
        media::MediaHandler* mh = media::MediaHandler::get();
        if ( ! mh )
@@ -178,11 +177,13 @@
                return;
        }
 
-       _decoder = mh->createVideoDecoder(*info); 
-       if ( ! _decoder.get() )
+    try
+    {
+           _decoder = mh->createVideoDecoder(*info);
+       }
+       catch (MediaException &e)
        {
-               log_error(_("Could not create video decoder from VideoInfo 
%s"), *info);
-               return;
+           log_error("Could not create Video Decoder: %s", e.what());
        }
 }
 
@@ -247,6 +248,12 @@
        // If this is a video from a VideoFrame tag, retrieve a video frame 
from there.
        else if (_embeddedStream)
        {
+
+        // Don't try to do anything if there is no decoder. If it was
+        // never constructed (most likely), we'll return nothing,
+        // otherwise the last decoded frame.
+        if (!_decoder.get()) return _lastDecodedVideoFrame.get();
+
                int current_frame = get_ratio(); 
 
 #ifdef DEBUG_EMBEDDED_VIDEO_DECODING

=== modified file 'libmedia/ffmpeg/VideoDecoderFfmpeg.cpp'
--- a/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp    2008-08-28 22:48:50 +0000
+++ b/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp    2008-09-01 13:30:43 +0000
@@ -1,6 +1,6 @@
 // VideoDecoderFfmpeg.cpp: Video decoding using the FFMPEG library.
 // 
-//   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+//     Copyright (C) 2007, 2008 Free Software Foundation, Inc.
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -9,17 +9,18 @@
 //
 // This program is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
 // GNU General Public License for more details.
 //
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA    02110-1301    
USA
 //
 
 
 #include "VideoDecoderFfmpeg.h"
 #include "MediaParserFfmpeg.h" // for ExtraVideoInfoFfmpeg 
+#include "GnashException.h" // for MediaException
 
 #ifdef HAVE_FFMPEG_SWSCALE_H
 #define HAVE_SWSCALE_H 1
@@ -36,6 +37,7 @@
 #endif
 
 #include <boost/scoped_array.hpp>
+#include <boost/format.hpp>
 #include <algorithm>
 
 namespace gnash {
@@ -58,7 +60,7 @@
          sws_freeContext(_context);
     }
     
-    SwsContext* getContext() { return _context; }
+    SwsContext* getContext() const { return _context; }
 
 private:
     SwsContext* _context;
@@ -66,91 +68,120 @@
 };
 #endif
 
+// A Wrapper ensuring an AVCodecContext is closed and freed
+// on destruction.
+class CodecContextWrapper
+{
+public:
+    CodecContextWrapper(AVCodecContext* context)
+        :
+        _codecCtx(context)
+    {}
+
+    ~CodecContextWrapper()
+    {
+        if (_codecCtx)
+        {
+            avcodec_close(_codecCtx);
+            av_free(_codecCtx);
+        }
+    }
+
+    AVCodecContext* getContext() const { return _codecCtx; }
+
+private:
+    AVCodecContext* _codecCtx;
+};
+
+
 VideoDecoderFfmpeg::VideoDecoderFfmpeg(videoCodecType format, int width, int 
height)
-  :
-  _videoCodec(NULL),
-  _videoCodecCtx(NULL)
+    :
+    _videoCodec(NULL)
 {
-  enum CodecID codec_id = flashToFfmpegCodec(format);
-
-  init(codec_id, width, height);
+
+    CodecID codec_id = flashToFfmpegCodec(format);
+    init(codec_id, width, height);
+
 }
 
 VideoDecoderFfmpeg::VideoDecoderFfmpeg(VideoInfo& info)
-  :
-  _videoCodec(NULL),
-  _videoCodecCtx(NULL)
+    :
+    _videoCodec(NULL)
 {
-  enum CodecID codec_id = CODEC_ID_NONE;
-  if ( info.type == FLASH )
-  {
-    codec_id = flashToFfmpegCodec(static_cast<videoCodecType>(info.codec));
-  }
-  else codec_id = static_cast<enum CodecID>(info.codec);
-
-  // This would cause nasty segfaults.
-  assert(codec_id != CODEC_ID_NONE);
-
-  boost::uint8_t* extradata=0;
-  int extradataSize=0;
-  if ( info.extra.get() )
-  {
-    assert(dynamic_cast<ExtraVideoInfoFfmpeg*>(info.extra.get()));
-    const ExtraVideoInfoFfmpeg& ei = 
static_cast<ExtraVideoInfoFfmpeg&>(*info.extra);
-    extradata = ei.data;
-    extradataSize = ei.dataSize;
-  }
-  init(codec_id, info.width, info.height, extradata, extradataSize);
+
+    CodecID codec_id = CODEC_ID_NONE;
+
+    if ( info.type == FLASH )
+    {
+        codec_id = flashToFfmpegCodec(static_cast<videoCodecType>(info.codec));
+    }
+    else codec_id = static_cast<CodecID>(info.codec);
+
+    // This would cause nasty segfaults.
+    if (codec_id == CODEC_ID_NONE)
+    {
+        boost::format msg = boost::format(_("Cannot find suitable "
+                "decoder for flash codec %d")) % info.codec;
+        throw MediaException(msg.str());
+    }
+
+    boost::uint8_t* extradata=0;
+    int extradataSize=0;
+    if ( info.extra.get() )
+    {
+        assert(dynamic_cast<ExtraVideoInfoFfmpeg*>(info.extra.get()));
+        const ExtraVideoInfoFfmpeg& ei = 
static_cast<ExtraVideoInfoFfmpeg&>(*info.extra);
+        extradata = ei.data;
+        extradataSize = ei.dataSize;
+    }
+    init(codec_id, info.width, info.height, extradata, extradataSize);
 }
 
 void
 VideoDecoderFfmpeg::init(enum CodecID codecId, int width, int height, 
boost::uint8_t* extradata, int extradataSize)
 {
-  // Init the avdecoder-decoder
-  avcodec_init();
-  avcodec_register_all();// change this to only register need codec?
-
-  _videoCodec = avcodec_find_decoder(codecId); 
-
-  if (!_videoCodec) {
-    log_error(_("libavcodec can't decode the current video format"));
-    return;
-  }
-
-  _videoCodecCtx = avcodec_alloc_context();
-  if (!_videoCodecCtx) {
-    log_error(_("libavcodec couldn't allocate context"));
-    return;
-  }
-
-  _videoCodecCtx->extradata = extradata;
-  _videoCodecCtx->extradata_size = extradataSize;
-
-  int ret = avcodec_open(_videoCodecCtx, _videoCodec);
-  if (ret < 0) {
-    log_error(_("VideoDecoderFfmpeg::init: avcodec_open: failed to initialize 
FFMPEG codec %s (%d)"),
-               _videoCodec->name, (int)codecId);
-    av_free(_videoCodecCtx);
-    _videoCodecCtx=0;
-    return;
-  }
-  _videoCodecCtx->width = width;
-  _videoCodecCtx->height = height;
-
-  log_debug(_("VideoDecoderFfmpeg::init: initialized FFMPEG codec %s (%d)"), 
-               _videoCodec->name, (int)codecId);
-
-  assert(_videoCodecCtx->width > 0);
-  assert(_videoCodecCtx->height > 0);
+    // Init the avdecoder-decoder
+    avcodec_init();
+    avcodec_register_all();// change this to only register need codec?
+
+    _videoCodec = avcodec_find_decoder(codecId); 
+
+    if (!_videoCodec) {
+        throw MediaException(_("libavcodec can't decode this video format"));
+    }
+
+    _videoCodecCtx.reset(new CodecContextWrapper(avcodec_alloc_context()));
+    if (!_videoCodecCtx->getContext()) {
+        throw MediaException(_("libavcodec couldn't allocate context"));
+    }
+
+    AVCodecContext* const ctx = _videoCodecCtx->getContext();
+
+    ctx->extradata = extradata;
+    ctx->extradata_size = extradataSize;
+
+    int ret = avcodec_open(ctx, _videoCodec);
+    if (ret < 0) {
+        boost::format msg = boost::format(_("libavcodec"
+                            "failed to initialize FFMPEG "
+                            "codec %s (%d)")) % 
+                            _videoCodec->name % (int)codecId;
+
+        throw MediaException(msg.str());
+    }
+    
+    ctx->width = width;
+    ctx->height = height;
+
+    log_debug(_("VideoDecoder: initialized FFMPEG codec %s (%d)"), 
+               _videoCodec->name, (int)codecId);
+
+    assert(ctx->width > 0);
+    assert(ctx->height > 0);
 }
 
 VideoDecoderFfmpeg::~VideoDecoderFfmpeg()
 {
-  if (_videoCodecCtx)
-  {
-    avcodec_close(_videoCodecCtx);
-    av_free(_videoCodecCtx);
-  }
 }
 
 std::auto_ptr<image::ImageBase>
@@ -158,174 +189,179 @@
                                  const AVFrame& srcFrame)
 {
 
-  const int width = srcCtx->width;
-  const int height = srcCtx->height;
+    // Adjust to next highest 4-pixel value.
+    const int width = srcCtx->width;
+    const int height = srcCtx->height;
 
-  PixelFormat pixFmt;
-  std::auto_ptr<image::ImageBase> im;
+    PixelFormat pixFmt;
+    std::auto_ptr<image::ImageBase> im;
 
 #ifdef FFMPEG_VP6A
-  if (srcCtx->codec->id == CODEC_ID_VP6A)
+    if (srcCtx->codec->id == CODEC_ID_VP6A)
 #else
-  if (0)
+    if (0)
 #endif // def FFMPEG_VP6A
-  {
-    // Expect RGBA data
-    //log_debug("alpha image");
-    pixFmt = PIX_FMT_RGBA;
-    im.reset(new image::ImageRGBA(width, height));    
-  }
-  else
-  {
-    // Expect RGB data
-    pixFmt = PIX_FMT_RGB24;
-    im.reset(new image::ImageRGB(width, height));
-  }
+    {
+        // Expect RGBA data
+        //log_debug("alpha image");
+        pixFmt = PIX_FMT_RGBA;
+        im.reset(new image::ImageRGBA(width, height));        
+    }
+    else
+    {
+        // Expect RGB data
+        pixFmt = PIX_FMT_RGB24;
+        im.reset(new image::ImageRGB(width, height));
+    }
 
 #ifdef HAVE_SWSCALE_H
-  // Check whether the context wrapper exists
-  // already.
-  if (!_swsContext.get()) {
-
-    _swsContext.reset(
-            new SwsContextWrapper(
-                sws_getContext(width, height, srcCtx->pix_fmt,
-                width, height, pixFmt,
-                SWS_BILINEAR, NULL, NULL, NULL)
-            ));
-    
-    // Check that the context was assigned.
-    if (!_swsContext->getContext()) {
-
-      // This means we will try to assign the 
-      // context again next time.
-      _swsContext.reset();
-      
-      // Can't do anything now, though.
-      im.reset();
-      return im;
+    // Check whether the context wrapper exists
+    // already.
+    if (!_swsContext.get()) {
+
+        _swsContext.reset(
+                        new SwsContextWrapper(
+                                sws_getContext(width, height, srcCtx->pix_fmt,
+                                width, height, pixFmt,
+                                SWS_BILINEAR, NULL, NULL, NULL)
+                        ));
+        
+        // Check that the context was assigned.
+        if (!_swsContext->getContext()) {
+
+            // This means we will try to assign the 
+            // context again next time.
+            _swsContext.reset();
+            
+            // Can't do anything now, though.
+            im.reset();
+            return im;
+        }
     }
-  }
 #endif
 
-  int bufsize = avpicture_get_size(pixFmt, width, height);
-      if (bufsize == -1) {
+    int bufsize = avpicture_get_size(pixFmt, width, height);
+            if (bufsize == -1) {
+                im.reset();
+                return im;
+            }
+
+    boost::uint8_t* buffer = new boost::uint8_t[bufsize];
+
+    AVPicture picture;
+    picture.data[0] = NULL;
+
+    avpicture_fill(&picture, buffer, pixFmt, width, height);
+
+#ifndef HAVE_SWSCALE_H
+    img_convert(&picture, PIX_FMT_RGB24, (AVPicture*) &srcFrame,
+            srcCtx->pix_fmt, width, height);
+#else
+
+    // Is it possible for the context to be reset
+    // to NULL once it's been created?
+    assert(_swsContext->getContext());
+
+    int rv = sws_scale(_swsContext->getContext(), 
const_cast<uint8_t**>(srcFrame.data),
+        const_cast<int*>(srcFrame.linesize), 0, height, picture.data,
+        picture.linesize);
+
+    if (rv == -1) {
+        delete [] buffer;
         im.reset();
         return im;
-      }
-
-  boost::uint8_t* buffer = new boost::uint8_t[bufsize];
-
-  AVPicture picture;
-  picture.data[0] = NULL;
-
-  avpicture_fill(&picture, buffer, pixFmt, width, height);
-
-#ifndef HAVE_SWSCALE_H
-  img_convert(&picture, PIX_FMT_RGB24, (AVPicture*) &srcFrame,
-      srcCtx->pix_fmt, width, height);
-#else
-
-  // Is it possible for the context to be reset
-  // to NULL once it's been created?
-  assert(_swsContext->getContext());
-
-  int rv = sws_scale(_swsContext->getContext(), 
const_cast<uint8_t**>(srcFrame.data),
-    const_cast<int*>(srcFrame.linesize), 0, height, picture.data,
-    picture.linesize);
-
-  if (rv == -1) {
-    delete [] buffer;
-    im.reset();
+    }
+#endif
+
+    im->update(picture.data[0]);
     return im;
-  }
-#endif
-
-  im->update(picture.data[0]);
-  return im;
 
 }
 
 std::auto_ptr<image::ImageBase>
 VideoDecoderFfmpeg::decode(const boost::uint8_t* input, boost::uint32_t 
input_size)
 {
-  std::auto_ptr<image::ImageBase> ret;
-
-  AVFrame* frame = avcodec_alloc_frame();
-  if ( ! frame ) {
-    log_error(_("Out of memory while allocating avcodec frame"));
-    return ret;
-  }
-
-  int bytes = 0;  
-  // no idea why avcodec_decode_video wants a non-const input...
-  avcodec_decode_video(_videoCodecCtx, frame, &bytes, 
const_cast<boost::uint8_t*>(input), input_size);
-  
-  if (!bytes) {
-    log_error("Decoding of a video frame failed");
+
+    // This object shouldn't exist if there's no codec, as it can'
+    // do anything anyway.
+    assert(_videoCodecCtx.get());
+
+    std::auto_ptr<image::ImageBase> ret;
+
+    AVFrame* frame = avcodec_alloc_frame();
+    if ( ! frame ) {
+        log_error(_("Out of memory while allocating avcodec frame"));
+        return ret;
+    }
+
+    int bytes = 0;    
+    // no idea why avcodec_decode_video wants a non-const input...
+    avcodec_decode_video(_videoCodecCtx->getContext(), frame, &bytes, 
const_cast<boost::uint8_t*>(input), input_size);
+    
+    if (!bytes) {
+        log_error("Decoding of a video frame failed");
+        av_free(frame);
+        return ret;
+    }
+
+    ret = frameToImage(_videoCodecCtx->getContext(), *frame);
+
+    // FIXME: av_free doesn't free frame->data!
     av_free(frame);
     return ret;
-  }
-
-  ret = frameToImage(_videoCodecCtx, *frame);
-
-  // FIXME: av_free doesn't free frame->data!
-  av_free(frame);
-  return ret;
 }
 
 
 void
 VideoDecoderFfmpeg::push(const EncodedVideoFrame& buffer)
 {
-  _video_frames.push_back(&buffer);
-
+    _video_frames.push_back(&buffer);
 }
 
 std::auto_ptr<image::ImageBase>
 VideoDecoderFfmpeg::pop()
 {
-  std::auto_ptr<image::ImageBase> ret;
-
-  for (std::vector<const EncodedVideoFrame*>::iterator it =
-       _video_frames.begin(), end = _video_frames.end(); it != end; ++it) {
-     ret = decode((*it)->data(), (*it)->dataSize());
-  }
-
-  _video_frames.clear();
-
-  return ret;
+    std::auto_ptr<image::ImageBase> ret;
+
+    for (std::vector<const EncodedVideoFrame*>::iterator it =
+             _video_frames.begin(), end = _video_frames.end(); it != end; 
++it) {
+         ret = decode((*it)->data(), (*it)->dataSize());
+    }
+
+    _video_frames.clear();
+
+    return ret;
 }
-  
+    
 bool
 VideoDecoderFfmpeg::peek()
 {
-  return (!_video_frames.empty());
+    return (!_video_frames.empty());
 }
 
 /* public static */
 enum CodecID
 VideoDecoderFfmpeg::flashToFfmpegCodec(videoCodecType format)
 {
-    // Find the decoder and init the parser
-    switch(format) {
-        case VIDEO_CODEC_H263:
-             return CODEC_ID_FLV1; // why not CODEC_ID_H263I ?
+        // Find the decoder and init the parser
+        switch(format) {
+                case VIDEO_CODEC_H263:
+                         return CODEC_ID_FLV1; // why not CODEC_ID_H263I ?
 #ifdef FFMPEG_VP6
-        case VIDEO_CODEC_VP6:
-            return CODEC_ID_VP6F;
+                case VIDEO_CODEC_VP6:
+                        return CODEC_ID_VP6F;
 #endif
 #ifdef FFMPEG_VP6A
-        case VIDEO_CODEC_VP6A:
-               return CODEC_ID_VP6A;
+                case VIDEO_CODEC_VP6A:
+                       return CODEC_ID_VP6A;
 #endif
-        case VIDEO_CODEC_SCREENVIDEO:
-            return CODEC_ID_FLASHSV;
-        default:
-            log_error(_("Unsupported video codec %d"),
-                static_cast<int>(format));
-            return CODEC_ID_NONE;
-    }
+                case VIDEO_CODEC_SCREENVIDEO:
+                        return CODEC_ID_FLASHSV;
+                default:
+                        log_error(_("Unsupported video codec %d"),
+                                static_cast<int>(format));
+                        return CODEC_ID_NONE;
+        }
 }
 
 

=== modified file 'libmedia/ffmpeg/VideoDecoderFfmpeg.h'
--- a/libmedia/ffmpeg/VideoDecoderFfmpeg.h      2008-08-28 16:30:58 +0000
+++ b/libmedia/ffmpeg/VideoDecoderFfmpeg.h      2008-09-01 13:10:41 +0000
@@ -53,6 +53,7 @@
 
 
 /// Forward declarations
+class CodecContextWrapper;
 class image::ImageBase;
 #ifdef HAVE_SWSCALE_H
 class SwsContextWrapper;
@@ -105,7 +106,7 @@
     }
 
     AVCodec* _videoCodec;
-    AVCodecContext* _videoCodecCtx;
+    std::auto_ptr<CodecContextWrapper> _videoCodecCtx;
 
 #if HAVE_SWSCALE_H
     /// A pointer to a wrapper round an SwsContext


reply via email to

[Prev in Thread] Current Thread [Next in Thread]