[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog libmedia/Makefile.am libmedia/V... [relea
From: |
Bastiaan Jacques |
Subject: |
[Gnash-commit] gnash ChangeLog libmedia/Makefile.am libmedia/V... [release_0_8_2_rc1] |
Date: |
Wed, 27 Feb 2008 20:55:04 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Branch: release_0_8_2_rc1
Changes by: Bastiaan Jacques <bjacques> 08/02/27 20:55:03
Modified files:
. : ChangeLog
libmedia : Makefile.am VideoDecoder.h
libmedia/ffmpeg: VideoDecoderFfmpeg.cpp VideoDecoderFfmpeg.h
libmedia/gst : VideoDecoderGst.cpp VideoDecoderGst.h
server/asobj : NetStreamFfmpeg.cpp
server/parser : video_stream_def.cpp video_stream_def.h
Log message:
Backport of embedded video work, enabling embedded video for ffmpeg.
* libmedia/Makefile.am: Remove MediaDecoder* from the build,
since
they are unused and unmaintained.
* libmedia/VideoDecoder.h: Revise the VideoDecoder interface,
closely
modeled after that of VideoDecoderGst.
* libmedia/ffmpeg/VideoDecoderFfmpeg.{cpp,h}: Implement the new
VideoDecoder interface. This fixes embedded video.
* libmedia/gst/VideoDecoderGst.{cpp,h}: Update VideoDecoderGst
to
match the new VideoDecoder interface.
* libmedia/ffmpeg/VideoDecoderFfmpeg.{cpp,h}: Cleanup; remove
unused
methods and code. Avoid unnecessary memcpy calls. Tabs to
spaces.
Fix up convertRGB24 so that it no longer touches the source
frame
and enforce that with constness.
* server/parser/video_stream_def.{cpp,h}: Mutex-protect the
video
frames vector, because video_stream_def's methods are called
from
both the "loading thread" (parser) and the main execution thread
(rendering). Remove Gstreamer-specific calls and get rid of
#ifdefs.
* server/asobj/NetStreamFfmpeg.cpp: Update to match the changes
to
convertRGB24.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.5711.2.29&r2=1.5711.2.30
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/Makefile.am?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.13.2.2&r2=1.13.2.3
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/VideoDecoder.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.11&r2=1.11.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/VideoDecoderFfmpeg.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.15.2.1&r2=1.15.2.2
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.13&r2=1.13.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamFfmpeg.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.105.2.1&r2=1.105.2.2
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.39.2.1&r2=1.39.2.2
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.22.2.1&r2=1.22.2.2
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5711.2.29
retrieving revision 1.5711.2.30
diff -u -b -r1.5711.2.29 -r1.5711.2.30
--- ChangeLog 27 Feb 2008 17:41:01 -0000 1.5711.2.29
+++ ChangeLog 27 Feb 2008 20:55:00 -0000 1.5711.2.30
@@ -1,3 +1,24 @@
+2008-02-27 Bastiaan Jacques <address@hidden>
+
+ * libmedia/Makefile.am: Remove MediaDecoder* from the build, since
+ they are unused and unmaintained.
+ * libmedia/VideoDecoder.h: Revise the VideoDecoder interface, closely
+ modeled after that of VideoDecoderGst.
+ * libmedia/ffmpeg/VideoDecoderFfmpeg.{cpp,h}: Implement the new
+ VideoDecoder interface. This fixes embedded video.
+ * libmedia/gst/VideoDecoderGst.{cpp,h}: Update VideoDecoderGst to
+ match the new VideoDecoder interface.
+ * libmedia/ffmpeg/VideoDecoderFfmpeg.{cpp,h}: Cleanup; remove unused
+ methods and code. Avoid unnecessary memcpy calls. Tabs to spaces.
+ Fix up convertRGB24 so that it no longer touches the source frame
+ and enforce that with constness.
+ * server/parser/video_stream_def.{cpp,h}: Mutex-protect the video
+ frames vector, because video_stream_def's methods are called from
+ both the "loading thread" (parser) and the main execution thread
+ (rendering). Remove Gstreamer-specific calls and get rid of #ifdefs.
+ * server/asobj/NetStreamFfmpeg.cpp: Update to match the changes to
+ convertRGB24.
+
2008-02-27 Sandro Santilli <address@hidden>
* testsuite/swfdec/PASSING: prototype-addProperty-6.swf
Index: libmedia/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/libmedia/Makefile.am,v
retrieving revision 1.13.2.2
retrieving revision 1.13.2.3
diff -u -b -r1.13.2.2 -r1.13.2.3
--- libmedia/Makefile.am 22 Feb 2008 14:39:21 -0000 1.13.2.2
+++ libmedia/Makefile.am 27 Feb 2008 20:55:01 -0000 1.13.2.3
@@ -77,13 +77,11 @@
FLVParser.cpp \
AudioDecoderNellymoser.cpp \
AudioDecoderSimple.cpp \
- MediaDecoder.cpp \
$(NULL)
noinst_HEADERS = \
FLVParser.h \
MediaBuffer.h \
- MediaDecoder.h \
AudioDecoder.h \
VideoDecoder.h \
MediaParser.h \
@@ -103,7 +101,6 @@
gst/SoundHandlerGst.cpp \
gst/GstUtil.cpp \
gst/SoundGst.cpp \
- gst/MediaDecoderGst.cpp \
gst/gstflvdemux.c \
gst/gstflvparse.c \
gst/gstbuffersrc.c
@@ -116,7 +113,6 @@
gst/SoundHandlerGst.h \
gst/GstUtil.h \
gst/SoundGst.h \
- gst/MediaDecoderGst.h \
gst/gstflvdemux.h \
gst/gstflvparse.h \
gst/gstbuffersrc.h \
Index: libmedia/VideoDecoder.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/VideoDecoder.h,v
retrieving revision 1.11
retrieving revision 1.11.2.1
diff -u -b -r1.11 -r1.11.2.1
--- libmedia/VideoDecoder.h 21 Jan 2008 23:10:14 -0000 1.11
+++ libmedia/VideoDecoder.h 27 Feb 2008 20:55:01 -0000 1.11.2.1
@@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// $Id: VideoDecoder.h,v 1.11 2008/01/21 23:10:14 rsavoye Exp $
+// $Id: VideoDecoder.h,v 1.11.2.1 2008/02/27 20:55:01 bjacques Exp $
#ifndef __VIDEODECODER_H__
#define __VIDEODECODER_H__
@@ -24,95 +24,89 @@
#include "MediaParser.h"
#include "image.h"
+#include <boost/noncopyable.hpp>
+
namespace gnash {
namespace media {
-/// Video decoding base class.
-class VideoDecoder {
-
-public:
- VideoDecoder() {}
+class EncodedVideoFrame;
- // virtual classes need a virtual destructor !
- virtual ~VideoDecoder() {}
+/// Abstract base class for embedded video decoders.
+//
+/// This very simple design allows, but does not require,
+/// the use of threads in an implementation. A user of this class push a frame
+/// into the decoder and can subsequently pop a decoded frame. Since the pop()
+/// call may block, it is advisable to first call peek() to see if there is a
+/// frame ready to be popped.
+///
+class VideoDecoder : public boost::noncopyable {
- /// Return the number of bytes input frame data is expected
- /// to be padded with zeroes. Make sure to provide such
- /// padding to avoid illegal reads.
- ///
- virtual unsigned getPaddingBytes() const { return 8; }
+public:
+ virtual ~VideoDecoder()
+ {
+ }
- /// Sets up the decoder.
+ /// Push an encoded video frame into the decoder
//
- /// @param info
- /// VideoInfo class with all the info needed to decode
- /// the video correctly.
- ///
- /// @return true if succesfull else false
+ /// @param the video frame to decode
///
- virtual bool setup(VideoInfo* /*info*/) { return false; }
+ virtual void push(const EncodedVideoFrame& buffer) = 0;
- /// Sets up the decoder.
+ /// Pop a decoded frame from the decoder. THIS METHOD MAY BLOCK.
//
- /// @param width
- /// The width of the video
- ///
- /// @param height
- /// The height of the video
- ///
- /// @param deblocking
- /// Should a deblocking filter be used? 1 = off, 2 = on
- ///
- /// @param smoothing
- /// Should the video be smoothed?
- ///
- /// @param format
- /// The codec of the video, see codecType
- ///
- /// @param outputFormat
- /// The outputFormat of the video, see videoOutputFormat
- ///
- /// @return true if succesfull else false
- ///
- virtual bool setup(
- int /*width*/,
- int /*height*/,
- int /*deblocking*/,
- bool /*smoothing*/,
- videoCodecType /*format*/,
- int /*outputFormat*/) /* should this argument be of
VideoOutputFormat type ?*/ { return false; }
+ /// @return The decoded video frame, or a NULL-containing auto_ptr if an
+ /// error occurred.
+ virtual std::auto_ptr<image::rgb> pop() = 0;
- /// Decodes a frame and returns a pointer to the data
+ /// \brief
+ /// Check whether a decoded frame is ready to be popped.
//
- /// @param input
- /// The video data
- ///
- /// @param inputSize
- /// The size of the video data
- ///
- /// @param outputSize
- /// The output size of the video data, is passed by reference.
+ /// This method will never block.
///
- /// @return a pointer to the decoded data, or NULL if decoding fails.
- /// The caller owns the decoded data.
+ /// @return true if there is a frame ready to be popped.
///
- virtual boost::uint8_t* decode(boost::uint8_t* /*input*/,
boost::uint32_t /*inputSize*/, boost::uint32_t& /*outputSize*/) { return NULL; }
+ virtual bool peek() = 0;
+};
- /// Decodes a frame and returns an image::base containing it
- //
- /// @param input
- /// The video data
- ///
- /// @param inputSize
- /// The size of the video data
- ///
- /// @return a pointer to the image with the decoded data, or NULL if
decoding fails.
- /// The caller owns the decoded data.
- ///
- virtual std::auto_ptr<image::image_base> decodeToImage(boost::uint8_t*
/*input*/, boost::uint32_t /*inputSize*/) { return
std::auto_ptr<image::image_base>(NULL); }
+/// This class represents a video frame that has not yet been decoded.
+class EncodedVideoFrame : public boost::noncopyable
+{
+public:
+ /// @param buffer Pointer to the video data corresponding to this frame. This
+ /// class takes ownership of the pointer.
+ /// @param buf_size The size, in bytes, of the data pointed to in the buffer
+ /// argument
+ /// @param frame_number The number of the frame in the video stream.
+ EncodedVideoFrame(boost::uint8_t* buffer, size_t buf_size, size_t frame_num)
+ : _buffer(buffer),
+ _buffer_size(buf_size),
+ _frame_number(frame_num)
+ {}
+
+ uint8_t* data() const
+ {
+ return _buffer.get();
+ }
+
+ size_t dataSize() const
+ {
+ return _buffer_size;
+ }
+
+ size_t frameNum() const
+ {
+ return _frame_number;
+ }
+
+private:
+ boost::scoped_array<uint8_t> _buffer;
+ size_t _buffer_size;
+ size_t _frame_number;
};
+
+
} // gnash.media namespace
} // gnash namespace
Index: libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- libmedia/ffmpeg/VideoDecoderFfmpeg.cpp 22 Feb 2008 14:16:34 -0000
1.1.2.1
+++ libmedia/ffmpeg/VideoDecoderFfmpeg.cpp 27 Feb 2008 20:55:01 -0000
1.1.2.2
@@ -17,7 +17,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-// $Id: VideoDecoderFfmpeg.cpp,v 1.1.2.1 2008/02/22 14:16:34 strk Exp $
+// $Id: VideoDecoderFfmpeg.cpp,v 1.1.2.2 2008/02/27 20:55:01 bjacques Exp $
#include "VideoDecoderFfmpeg.h"
@@ -27,32 +27,15 @@
}
#endif
#include <boost/scoped_array.hpp>
+#include <boost/foreach.hpp>
namespace gnash {
namespace media {
-VideoDecoderFfmpeg::VideoDecoderFfmpeg ()
+VideoDecoderFfmpeg::VideoDecoderFfmpeg(videoCodecType format, int width,int
height)
:
_videoCodec(NULL),
_videoCodecCtx(NULL)
-{}
-
-VideoDecoderFfmpeg::~VideoDecoderFfmpeg()
-{
- if (_videoCodecCtx)
- {
- avcodec_close(_videoCodecCtx);
- av_free(_videoCodecCtx);
- }
-}
-
-bool VideoDecoderFfmpeg::setup(
- int width,
- int height,
- int /*deblocking*/,
- bool /*smoothing*/,
- videoCodecType format, // should this argument be of codecType
type ?
- int /*outputFormat*/)
{
// Init the avdecoder-decoder
avcodec_init();
@@ -76,298 +59,152 @@
default:
log_error(_("Unsupported video codec %d"),
static_cast<int>(format));
- return false;
+ return;
}
- _videoCodec = avcodec_find_decoder(static_cast<CodecID>(codec_id));
+ _videoCodec = avcodec_find_decoder(static_cast<CodecID>(codec_id)); // WTF?
if (!_videoCodec) {
log_error(_("libavcodec can't decode the current video
format"));
- return false;
+ return;
}
_videoCodecCtx = avcodec_alloc_context();
if (!_videoCodecCtx) {
log_error(_("libavcodec couldn't allocate context"));
- return false;
+ return;
}
int ret = avcodec_open(_videoCodecCtx, _videoCodec);
if (ret < 0) {
log_error(_("libavcodec failed to initialize codec"));
- return false;
+ return;
}
_videoCodecCtx->width = width;
_videoCodecCtx->height = height;
assert(_videoCodecCtx->width > 0);
assert(_videoCodecCtx->height > 0);
- return true;
+ return;
}
-bool VideoDecoderFfmpeg::setup(VideoInfo* info)
+VideoDecoderFfmpeg::~VideoDecoderFfmpeg()
{
- // Init the avdecoder-decoder
- avcodec_init();
- avcodec_register_all();// change this to only register need codec?
-
- if (info->type == FLASH) {
- enum CodecID codec_id;
-
- // Find the decoder and init the parser
- switch(info->codec) {
- case VIDEO_CODEC_H263:
- codec_id = CODEC_ID_FLV1;
- break;
-#ifdef FFMPEG_VP6
- case VIDEO_CODEC_VP6:
- codec_id = CODEC_ID_VP6F;
- break;
-#endif
- case VIDEO_CODEC_SCREENVIDEO:
- codec_id = CODEC_ID_FLASHSV;
- break;
- default:
- log_error(_("Unsupported video codec %d"),
- static_cast<int>(info->codec));
- return false;
- }
- _videoCodec =
avcodec_find_decoder(static_cast<CodecID>(codec_id));
- } else if (info->type == FFMPEG) {
- _videoCodec =
avcodec_find_decoder(static_cast<CodecID>(info->codec));
- } else {
- //log_error("Video codecType unknown: %d, %d, %d",
- // info->type, FLASH, FFMPEG);
- return false;
- }
-
- if (!_videoCodec) {
- log_error(_("libavcodec can't decode the current video
format"));
- return false;
- }
-
- // Reuse the videoCodecCtx from the ffmpeg parser if exists/possible
- if (info->videoCodecCtx) {
- log_debug("re-using the parsers videoCodecCtx");
- _videoCodecCtx = info->videoCodecCtx;
- } else {
- _videoCodecCtx = avcodec_alloc_context();
- }
-
- if (!_videoCodecCtx) {
- log_error(_("libavcodec couldn't allocate context"));
- return false;
- }
-
- int ret = avcodec_open(_videoCodecCtx, _videoCodec);
- if (ret < 0) {
- log_error(_("libavcodec failed to initialize codec"));
- return false;
+ if (_videoCodecCtx)
+ {
+ avcodec_close(_videoCodecCtx);
+ av_free(_videoCodecCtx);
}
-
- return true;
}
-boost::uint8_t*
-VideoDecoderFfmpeg::convertRGB24(AVCodecContext* srcCtx, AVFrame* srcFrame)
+AVPicture /*static*/
+VideoDecoderFfmpeg::convertRGB24(AVCodecContext* srcCtx,
+ const AVFrame& srcFrame)
{
+ AVPicture picture;
int width = srcCtx->width, height = srcCtx->height;
+ picture.data[0] = NULL;
+
int bufsize = avpicture_get_size(PIX_FMT_RGB24, width, height);
if (bufsize == -1) {
- return NULL;
+ return picture;
}
boost::uint8_t* buffer = new boost::uint8_t[bufsize];
- if (!buffer) {
- return NULL;
- }
-
- AVPicture picture;
avpicture_fill(&picture, buffer, PIX_FMT_RGB24, width, height);
#ifndef HAVE_SWSCALE_H
- img_convert(&picture, PIX_FMT_RGB24, (AVPicture*) srcFrame,
+ img_convert(&picture, PIX_FMT_RGB24, (AVPicture*) &srcFrame,
srcCtx->pix_fmt, width, height);
#else
+ // FIXME: this will live forever ...
static struct SwsContext* context = NULL;
- if (!context)
- {
+ if (!context) {
+ // FIXME: this leads to wrong results (read: segfaults) if this method
+ // is called from two unrelated video contexts, for example from
+ // a NetStreamFfmpeg and an embedded video context. Or two
+ // separate instances of one of the former two.
context = sws_getContext(width, height, srcCtx->pix_fmt,
width, height, PIX_FMT_RGB24,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
- if (!context)
- {
+ if (!context) {
delete [] buffer;
- return NULL;
+ return picture;
}
}
- int rv = sws_scale(
- context, srcFrame->data, srcFrame->linesize, 0, height,
- picture.data, picture.linesize
- );
+ int rv = sws_scale(context, const_cast<uint8_t**>(srcFrame.data),
+ const_cast<int*>(srcFrame.linesize), 0, height, picture.data,
+ picture.linesize);
- if (rv == -1)
- {
+ if (rv == -1) {
delete [] buffer;
- return NULL;
}
#endif // HAVE_SWSCALE_H
-
- srcFrame->linesize[0] = picture.linesize[0];
- srcFrame->data[0] = picture.data[0];
-
- return buffer;
+ return picture;
}
-boost::uint8_t* VideoDecoderFfmpeg::decode(boost::uint8_t* input,
- boost::uint32_t inputSize,
- boost::uint32_t& outputSize)
+std::auto_ptr<image::rgb>
+VideoDecoderFfmpeg::decode(boost::uint8_t* input, boost::uint32_t input_size)
{
- // Allocate a frame to store the decoded frame in
+ std::auto_ptr<image::rgb> ret;
+
AVFrame* frame = avcodec_alloc_frame();
- if ( ! frame )
- {
+ if ( ! frame ) {
log_error(_("Out of memory while allocating avcodec frame"));
- throw std::bad_alloc();
+ return ret;
}
- int got = 0;
-
- avcodec_decode_video(_videoCodecCtx, frame, &got, input, inputSize);
-
- if (got)
- {
- boost::scoped_array<boost::uint8_t> buffer;
-
- // Set to the next multiple of four. Some videos have
- // padding bytes, so that the source width is more than three
times
- // the video width. A likely explanation (supported by
- // tests) is that it is always padded out to a multiple of 4.
- // Have found no documenation on this.
- unsigned int srcwidth = (_videoCodecCtx->width * 3 + 3) &~ 3;
-
- boost::uint8_t* decodedData = new boost::uint8_t[srcwidth *
_videoCodecCtx->height];
-
- buffer.reset(convertRGB24(_videoCodecCtx, frame));
-
- // Copy the data to the buffer in the correct RGB format
- boost::uint8_t* srcptr = frame->data[0];
- boost::uint8_t* srcend = frame->data[0]
- + frame->linesize[0]
- * _videoCodecCtx->height;
- boost::uint8_t* dstptr = decodedData;
+ int bytes = 0;
+ avcodec_decode_video(_videoCodecCtx, frame, &bytes, input, input_size);
- outputSize = 0;
-
- while (srcptr < srcend)
- {
- memcpy(dstptr, srcptr, srcwidth);
- srcptr += frame->linesize[0];
- dstptr += srcwidth;
- outputSize += srcwidth;
+ if (!bytes) {
+ log_error("Decoding of a video frame failed");
+ av_free(frame);
+ return ret;
}
- av_free(frame);
- return decodedData;
+ AVPicture rgbpicture = convertRGB24(_videoCodecCtx, *frame);
-/* if (_videoFrameFormat == NONE) { // NullGui?
- return;
+ ret.reset(new image::rgb(rgbpicture.data[0], _videoCodecCtx->width,
+ _videoCodecCtx->height, rgbpicture.linesize[0]));
- } else if (_videoFrameFormat == YUV && _videoCodecCtx->pix_fmt
!= PIX_FMT_YUV420P) {
- abort(); // TODO
- //img_convert((AVPicture*) pFrameYUV, PIX_FMT_YUV420P,
(AVPicture*) pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
- // Don't use depreceted img_convert, use sws_scale
-
- } else if (_videoFrameFormat == RGB && _videoCodecCtx->pix_fmt
!= PIX_FMT_RGB24) {
- buffer.reset(convertRGB24(_videoCodecCtx, frame));
- }
-
- raw_mediadata_t* video = new raw_mediadata_t;
- if (_videoFrameFormat == YUV) {
- abort(); // See image.cpp to see what yuv size is
- //video->m_data = new
boost::uint8_t[static_cast<image::yuv*>(m_imageframe)->size()];
- } else if (_videoFrameFormat == RGB) {
- video->m_data = new
boost::uint8_t[_videoCodecCtx->width * _videoCodecCtx->height * 3];
- //}
-
- video->m_ptr = video->m_data;
- video->m_stream_index = _videoIndex;
- video->m_pts = 0;
-
- video->m_pts =
static_cast<boost::uint32_t>((as_double(_videoStream->time_base) * packet->dts)
* 1000.0);
-
-
- if (_videoFrameFormat == YUV) {
- //image::yuv* yuvframe =
static_cast<image::yuv*>(_imageframe);
- int copied = 0;
- boost::uint8_t* ptr = video->m_data;
- for (int i = 0; i < 3 ; i++)
- {
- int shift = (i == 0 ? 0 : 1);
- boost::uint8_t* yuv_factor = _frame->data[i];
- int h = _videoCodecCtx->height >> shift;
- int w = _videoCodecCtx->width >> shift;
- for (int j = 0; j < h; j++)
- {
- copied += w;
- //assert(copied <= yuvframe->size());
- memcpy(ptr, yuv_factor, w);
- yuv_factor += _frame->linesize[i];
- ptr += w;
- }
- }
- video->m_size = copied;
- } else if (_videoFrameFormat == RGB) {
-
- boost::uint8_t* srcptr = _frame->data[0];
- boost::uint8_t* srcend = _frame->data[0] +
_frame->linesize[0] * _videoCodecCtx->height;
- boost::uint8_t* dstptr = video->m_data;
- unsigned int srcwidth = _videoCodecCtx->width * 3;
+ // FIXME: av_free doesn't free frame->data!
+ av_free(frame);
+ return ret;
+}
- video->m_size = 0;
- while (srcptr < srcend) {
- memcpy(dstptr, srcptr, srcwidth);
- srcptr += _frame->linesize[0];
- dstptr += srcwidth;
- video->m_size += srcwidth;
- }
+void
+VideoDecoderFfmpeg::push(const EncodedVideoFrame& buffer)
+{
+ _video_frames.push_back(&buffer);
- }*/
- }
- else
- {
- log_error("Decoding of a video frame failed");
- av_free(frame);
- return NULL;
- }
}
-std::auto_ptr<image::image_base>
-VideoDecoderFfmpeg::decodeToImage(boost::uint8_t* input, boost::uint32_t
inputSize)
+std::auto_ptr<image::rgb>
+VideoDecoderFfmpeg::pop()
{
- boost::uint32_t outputSize = 0;
- boost::uint8_t* decodedData = decode(input, inputSize, outputSize);
+ std::auto_ptr<image::rgb> ret;
- if (!decodedData || outputSize == 0)
- {
- return std::auto_ptr<image::image_base>(NULL);
+ BOOST_FOREACH(const EncodedVideoFrame* frame, _video_frames) {
+ ret = decode(frame->data(), frame->dataSize());
}
- std::auto_ptr<image::image_base> ret(new image::rgb(
- _videoCodecCtx->width,
- _videoCodecCtx->height
- ));
- ret->update(decodedData);
- delete [] decodedData;
+ _video_frames.clear();
+
return ret;
+}
+bool
+VideoDecoderFfmpeg::peek()
+{
+ return (!_video_frames.empty());
}
} // gnash.media namespace
Index: libmedia/ffmpeg/VideoDecoderFfmpeg.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/ffmpeg/VideoDecoderFfmpeg.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- libmedia/ffmpeg/VideoDecoderFfmpeg.h 22 Feb 2008 14:16:35 -0000
1.1.2.1
+++ libmedia/ffmpeg/VideoDecoderFfmpeg.h 27 Feb 2008 20:55:02 -0000
1.1.2.2
@@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// $Id: VideoDecoderFfmpeg.h,v 1.1.2.1 2008/02/22 14:16:35 strk Exp $
+// $Id: VideoDecoderFfmpeg.h,v 1.1.2.2 2008/02/27 20:55:02 bjacques Exp $
#ifndef __VIDEODECODERFFMPEG_H__
#define __VIDEODECODERFFMPEG_H__
@@ -40,32 +40,35 @@
class VideoDecoderFfmpeg : public VideoDecoder {
public:
- VideoDecoderFfmpeg();
+ VideoDecoderFfmpeg(videoCodecType format, int width, int height);
~VideoDecoderFfmpeg();
- virtual unsigned getPaddingBytes() const { return
FF_INPUT_BUFFER_PADDING_SIZE; }
+ void push(const EncodedVideoFrame& buffer);
- bool setup(VideoInfo* info);
+ std::auto_ptr<image::rgb> pop();
- bool setup(
- int /*width*/,
- int /*height*/,
- int /*deblocking*/,
- bool /*smoothing*/,
- videoCodecType /*format*/,
- int /*outputFormat*/);
+ bool peek();
- boost::uint8_t* decode(boost::uint8_t* input, boost::uint32_t
inputSize, boost::uint32_t& outputSize);
- std::auto_ptr<image::image_base> decodeToImage(boost::uint8_t*
/*input*/, boost::uint32_t /*inputSize*/);
+ /// \brief converts an video frame from (almost) any type to RGB24.
+ ///
+ /// @param srcCtx The source context that was used to decode srcFrame.
+ /// @param srcFrame the source frame to be converted.
+ /// @return an AVPicture containing the converted image. Please be advised
+ /// that the RGB data pointer is stored in AVPicture::data[0]. The
+ /// caller owns that pointer, which must be freed with delete [].
+ /// It is advised to wrap the pointer in a boost::scoped_array.
+ /// If conversion fails, AVPicture::data[0] will be NULL.
+ static AVPicture convertRGB24(AVCodecContext* srcCtx, const AVFrame&
srcFrame);
- static boost::uint8_t* convertRGB24(AVCodecContext* srcCtx, AVFrame*
srcFrame);
+private:
+ std::auto_ptr<image::rgb> decode(boost::uint8_t* input, boost::uint32_t
input_size);
private:
AVCodec* _videoCodec;
AVCodecContext* _videoCodecCtx;
-
+ std::vector<const EncodedVideoFrame*> _video_frames;
};
} // gnash.media namespace
Index: libmedia/gst/VideoDecoderGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.cpp,v
retrieving revision 1.15.2.1
retrieving revision 1.15.2.2
diff -u -b -r1.15.2.1 -r1.15.2.2
--- libmedia/gst/VideoDecoderGst.cpp 22 Feb 2008 18:26:58 -0000 1.15.2.1
+++ libmedia/gst/VideoDecoderGst.cpp 27 Feb 2008 20:55:02 -0000 1.15.2.2
@@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// $Id: VideoDecoderGst.cpp,v 1.15.2.1 2008/02/22 18:26:58 bjacques Exp $
+// $Id: VideoDecoderGst.cpp,v 1.15.2.2 2008/02/27 20:55:02 bjacques Exp $
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
@@ -125,22 +125,31 @@
}
void
-VideoDecoderGst::pushRawFrame(GstBuffer* buffer)
+VideoDecoderGst::push(const EncodedVideoFrame& frame)
{
if (!_pipeline) {
return;
}
+
+ GstBuffer* buffer = gst_buffer_new();
+
+ GST_BUFFER_DATA(buffer) = frame.data();
+ GST_BUFFER_SIZE(buffer) = frame.dataSize();
+ GST_BUFFER_OFFSET(buffer) = frame.frameNum();
+ GST_BUFFER_TIMESTAMP(buffer) = GST_CLOCK_TIME_NONE;
+ GST_BUFFER_DURATION(buffer) = GST_CLOCK_TIME_NONE;
+
gst_app_src_push_buffer (GST_APP_SRC(_appsrc), buffer);
checkMessages();
}
-std::auto_ptr<gnashGstBuffer>
-VideoDecoderGst::popDecodedFrame()
+std::auto_ptr<image::rgb>
+VideoDecoderGst::pop()
{
if (!_pipeline) {
- return std::auto_ptr<gnashGstBuffer>();
+ return std::auto_ptr<image::rgb>();
}
checkMessages();
@@ -148,7 +157,7 @@
GstBuffer* buffer = gst_app_sink_pull_buffer_timed (GST_APP_SINK(_appsink));
if (!buffer) {
- return std::auto_ptr<gnashGstBuffer>();
+ return std::auto_ptr<image::rgb>();
}
GstCaps* caps = gst_buffer_get_caps(buffer);
@@ -164,7 +173,7 @@
gst_caps_unref(caps);
- std::auto_ptr<gnashGstBuffer> ret(new gnashGstBuffer(buffer, width, height));
+ std::auto_ptr<image::rgb> ret(new gnashGstBuffer(buffer, width, height));
return ret;
}
@@ -181,17 +190,6 @@
}
void
-VideoDecoderGst::reset()
-{
- if (!_pipeline) {
- return;
- }
-
- gst_element_set_state (GST_ELEMENT (_pipeline), GST_STATE_NULL); // Flushes
- gst_element_set_state (GST_ELEMENT (_pipeline), GST_STATE_PLAYING);
-}
-
-void
VideoDecoderGst::checkMessages() // any messages for me?
{
if (!_pipeline) {
Index: libmedia/gst/VideoDecoderGst.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.h,v
retrieving revision 1.13
retrieving revision 1.13.2.1
diff -u -b -r1.13 -r1.13.2.1
--- libmedia/gst/VideoDecoderGst.h 29 Jan 2008 05:18:33 -0000 1.13
+++ libmedia/gst/VideoDecoderGst.h 27 Feb 2008 20:55:02 -0000 1.13.2.1
@@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// $Id: VideoDecoderGst.h,v 1.13 2008/01/29 05:18:33 bjacques Exp $
+// $Id: VideoDecoderGst.h,v 1.13.2.1 2008/02/27 20:55:02 bjacques Exp $
#ifndef __VIDEODECODERGST_H__
#define __VIDEODECODERGST_H__
@@ -30,6 +30,7 @@
#include <gst/gst.h>
#include "log.h"
#include "MediaParser.h"
+#include "VideoDecoder.h"
namespace gnash {
@@ -64,35 +65,22 @@
};
-class VideoDecoderGst
+class VideoDecoderGst : public VideoDecoder
{
public:
-
VideoDecoderGst(videoCodecType codec_type, int width, int height);
~VideoDecoderGst();
- void pushRawFrame(GstBuffer* buffer);
+ void push(const EncodedVideoFrame& buffer);
- /// Will block
- std::auto_ptr<gnashGstBuffer> popDecodedFrame();
+ std::auto_ptr<image::rgb> pop();
- /// Returns true if there is a decoded frame ready to be popped.
bool peek();
- /// Clears the pipeline so that the stream can start from scratch.
- void reset();
-
+private:
void checkMessages();
-
- static void
- decodebin_newpad_cb(GstElement* decodebin, GstPad* pad,
- gboolean last, gpointer user_data);
- static void
- decodebin_unknown_cb(GstElement* decodebin, GstPad* pad,
- gboolean last, gpointer user_data);
-
void handleMessage(GstMessage* message);
-private:
+
VideoDecoderGst();
VideoDecoderGst(const gnash::media::VideoDecoderGst&);
Index: server/asobj/NetStreamFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamFfmpeg.cpp,v
retrieving revision 1.105.2.1
retrieving revision 1.105.2.2
diff -u -b -r1.105.2.1 -r1.105.2.2
--- server/asobj/NetStreamFfmpeg.cpp 22 Feb 2008 14:16:40 -0000
1.105.2.1
+++ server/asobj/NetStreamFfmpeg.cpp 27 Feb 2008 20:55:02 -0000
1.105.2.2
@@ -17,7 +17,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-/* $Id: NetStreamFfmpeg.cpp,v 1.105.2.1 2008/02/22 14:16:40 strk Exp $ */
+/* $Id: NetStreamFfmpeg.cpp,v 1.105.2.2 2008/02/27 20:55:02 bjacques Exp $ */
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
@@ -892,8 +892,6 @@
avcodec_decode_video(m_VCodecCtx, m_Frame, &got, packet->data,
packet->size);
if (got)
{
- boost::scoped_array<boost::uint8_t> buffer;
-
if (m_imageframe == NULL)
{
if (m_videoFrameFormat == render::YUV)
@@ -906,6 +904,8 @@
}
}
+ AVPicture rgbpicture;
+
if (m_videoFrameFormat == render::NONE)
{
// NullGui?
@@ -921,7 +921,10 @@
}
else if (m_videoFrameFormat == render::RGB &&
m_VCodecCtx->pix_fmt != PIX_FMT_RGB24)
{
-
buffer.reset(media::VideoDecoderFfmpeg::convertRGB24(m_VCodecCtx, m_Frame));
+ rgbpicture =
media::VideoDecoderFfmpeg::convertRGB24(m_VCodecCtx, *m_Frame);
+ if (!rgbpicture.data[0]) {
+ return false;
+ }
}
media::raw_mediadata_t* video = new media::raw_mediadata_t();
@@ -991,9 +994,17 @@
}
else if (m_videoFrameFormat == render::RGB)
{
+ AVPicture* src;
+ if (m_VCodecCtx->pix_fmt != PIX_FMT_RGB24)
+ {
+ src = &rgbpicture;
+ } else
+ {
+ src = (AVPicture*) m_Frame;
+ }
- boost::uint8_t* srcptr = m_Frame->data[0];
- boost::uint8_t* srcend = m_Frame->data[0] +
m_Frame->linesize[0] * m_VCodecCtx->height;
+ boost::uint8_t* srcptr = src->data[0];
+ boost::uint8_t* srcend = srcptr +
rgbpicture.linesize[0] * m_VCodecCtx->height;
boost::uint8_t* dstptr = video->m_data;
unsigned int srcwidth = m_VCodecCtx->width * 3;
@@ -1001,11 +1012,15 @@
while (srcptr < srcend) {
memcpy(dstptr, srcptr, srcwidth);
- srcptr += m_Frame->linesize[0];
+ srcptr += src->linesize[0];
dstptr += srcwidth;
video->m_size += srcwidth;
}
+ if (m_VCodecCtx->pix_fmt != PIX_FMT_RGB24) {
+ delete [] rgbpicture.data[0];
+ }
+
}
if (m_isFLV) m_qvideo.push(video);
Index: server/parser/video_stream_def.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/video_stream_def.cpp,v
retrieving revision 1.39.2.1
retrieving revision 1.39.2.2
diff -u -b -r1.39.2.1 -r1.39.2.2
--- server/parser/video_stream_def.cpp 22 Feb 2008 14:16:41 -0000 1.39.2.1
+++ server/parser/video_stream_def.cpp 27 Feb 2008 20:55:03 -0000 1.39.2.2
@@ -16,7 +16,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-// $Id: video_stream_def.cpp,v 1.39.2.1 2008/02/22 14:16:41 strk Exp $
+// $Id: video_stream_def.cpp,v 1.39.2.2 2008/02/27 20:55:03 bjacques Exp $
#include "video_stream_def.h"
#include "video_stream_instance.h"
@@ -44,25 +44,10 @@
{
}
-
-#ifdef SOUND_GST
-void myunref(GstBuffer* buf)
-{
- gst_buffer_unref(buf);
-}
-#endif
-
-
video_stream_definition::~video_stream_definition()
{
-#ifdef SOUND_GST
- std::for_each(_video_frames.begin(), _video_frames.end(), myunref);
-#elif defined(USE_FFMPEG)
- for ( int32_t size = _video_frames.size()-1; size >= 0; size-- ) {
- delete _video_frames[size];
- }
- _video_frames.clear();
-#endif
+ std::for_each(_video_frames.begin(), _video_frames.end(),
+ boost::checked_deleter<media::EncodedVideoFrame>());
}
@@ -104,17 +89,17 @@
}
#ifdef SOUND_GST
- _decoder.reset( new media::VideoDecoderGst(m_codec_id, _width, _height)
);
+# define VIDEO_DECODER_NAME VideoDecoderGst
#elif defined(USE_FFMPEG)
- _decoder.reset( new media::VideoDecoderFfmpeg() );
+# define VIDEO_DECODER_NAME VideoDecoderFfmpeg
#endif
+ _decoder.reset( new media::VIDEO_DECODER_NAME(m_codec_id, _width,
_height) );
+#undef VIDEO_DECODER_NAME
}
void
video_stream_definition::readDefineVideoFrame(stream* in, SWF::tag_type tag,
movie_definition* m)
{
-#ifdef SOUND_GST
-
// Character ID has been read already, and was loaded in the constructor
assert(tag == SWF::VIDEOFRAME);
@@ -131,25 +116,18 @@
unsigned int dataSize = in->get_tag_end_position() - in->get_position();
- GstBuffer* buffer = gst_buffer_new_and_alloc(dataSize+8);
- memset(GST_BUFFER_DATA(buffer)+dataSize, 0, 8);
- GST_BUFFER_SIZE (buffer) = dataSize;
-
- if (!buffer) {
- log_error(_("Failed to allocate a buffer of size %d advertised
by SWF."),
- dataSize);
- return;
- }
+ uint8_t* buffer = new uint8_t[dataSize + 8]; // FIXME: catch bad_alloc
- GST_BUFFER_OFFSET(buffer) = frameNum;
- GST_BUFFER_TIMESTAMP(buffer) = GST_CLOCK_TIME_NONE;
- GST_BUFFER_DURATION(buffer) = GST_CLOCK_TIME_NONE;
+ size_t bytesread = in->read((char*)buffer, dataSize);
+ memset(buffer+bytesread, 0, 8);
- in->read((char*)GST_BUFFER_DATA(buffer), dataSize);
+ using namespace media;
- _video_frames.push_back(buffer);
+ EncodedVideoFrame* frame = new EncodedVideoFrame(buffer, dataSize,
frameNum);
-#endif
+ boost::mutex::scoped_lock lock(_video_mutex);
+
+ _video_frames.push_back(frame);
}
@@ -160,20 +138,16 @@
return ch;
}
-#ifdef SOUND_GST
-
bool
-has_frame_number(GstBuffer* buf, boost::uint32_t frameNumber)
+has_frame_number(media::EncodedVideoFrame* frame, boost::uint32_t frameNumber)
{
- return GST_BUFFER_OFFSET(buf) == frameNumber;
+ return frame->frameNum() == frameNumber;
}
-#endif
-
std::auto_ptr<image::image_base>
video_stream_definition::get_frame_data(boost::uint32_t frameNum)
{
-#ifdef SOUND_GST
+ boost::mutex::scoped_lock lock(_video_mutex);
if (_video_frames.empty()) {
return std::auto_ptr<image::image_base>();
@@ -210,25 +184,18 @@
return std::auto_ptr<image::image_base>();
}
- gst_buffer_ref(*it); // make sure gstreamer doesn't delete the
buffer.
- _last_decoded_frame = GST_BUFFER_OFFSET(*it);
- _decoder->pushRawFrame(*it);
+ _last_decoded_frame = (*it)->frameNum();
+ _decoder->push(*(*it));
}
- std::auto_ptr<media::gnashGstBuffer> buffer =
_decoder->popDecodedFrame();
+ std::auto_ptr<image::rgb> buffer = _decoder->pop();
// If more data has arrived, replace the buffer with the next frame.
while (_decoder->peek()) {
- buffer = _decoder->popDecodedFrame();
+ buffer = _decoder->pop();
}
return std::auto_ptr<image::image_base>(buffer.release());
-
-#elif defined(USE_FFMPEG)
-
- return std::auto_ptr<image::image_base>( NULL );
-
-#endif
}
Index: server/parser/video_stream_def.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/video_stream_def.h,v
retrieving revision 1.22.2.1
retrieving revision 1.22.2.2
diff -u -b -r1.22.2.1 -r1.22.2.2
--- server/parser/video_stream_def.h 22 Feb 2008 14:16:41 -0000 1.22.2.1
+++ server/parser/video_stream_def.h 27 Feb 2008 20:55:03 -0000 1.22.2.2
@@ -16,7 +16,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-// $Id: video_stream_def.h,v 1.22.2.1 2008/02/22 14:16:41 strk Exp $
+// $Id: video_stream_def.h,v 1.22.2.2 2008/02/27 20:55:03 bjacques Exp $
#ifndef GNASH_VIDEO_STREAM_DEF_H
#define GNASH_VIDEO_STREAM_DEF_H
@@ -31,6 +31,7 @@
#include "swf.h"
#include "rect.h" // for composition
#include "ControlTag.h"
+#include "VideoDecoder.h"
#ifdef SOUND_GST
# include "VideoDecoderGst.h"
@@ -40,11 +41,12 @@
#include "image.h"
-#include <map>
#include <boost/shared_array.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+
namespace gnash {
@@ -163,11 +165,10 @@
/// Elements of this vector are owned by this instance, and will be
deleted
/// at instance destruction time.
///
-#ifdef SOUND_GST
- typedef std::vector<GstBuffer*> EmbedFrameVec;
-#elif defined(USE_FFMPEG)
- typedef std::vector<uint8_t*> EmbedFrameVec;
-#endif
+ typedef std::vector<media::EncodedVideoFrame*> EmbedFrameVec;
+
+ boost::mutex _video_mutex;
+
EmbedFrameVec _video_frames;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog libmedia/Makefile.am libmedia/V... [release_0_8_2_rc1],
Bastiaan Jacques <=