CVSROOT: /sources/gnash Module name: gnash Changes by: Tomas Groth <tgc> 07/10/18 15:56:55
Modified files: . : ChangeLog libmedia : VideoDecoder.h libmedia/gst : VideoDecoderGst.cpp VideoDecoderGst.h libmedia/sdl : VideoDecoderFfmpeg.cpp VideoDecoderFfmpeg.h server : video_stream_instance.cpp video_stream_instance.h server/parser : video_stream_def.cpp video_stream_def.h Log message: * libmedia/VideoDecoder.h,libmedia/gst/VideoDecoder{Ffmpeg.Gst}.{h,cpp}: Changed decodeToImage to return a raw image::image_base pointer. * server/video_stream_instance.{cpp,h},server/parser/video_stream_def.{h,cpp}: Changed to do decoding of video stream on parsing, and not on demand. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4634&r2=1.4635 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/VideoDecoder.h?cvsroot=gnash&r1=1.4&r2=1.5 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.cpp?cvsroot=gnash&r1=1.2&r2=1.3 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.h?cvsroot=gnash&r1=1.4&r2=1.5 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/VideoDecoderFfmpeg.cpp?cvsroot=gnash&r1=1.5&r2=1.6 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/VideoDecoderFfmpeg.h?cvsroot=gnash&r1=1.4&r2=1.5 http://cvs.savannah.gnu.org/viewcvs/gnash/server/video_stream_instance.cpp?cvsroot=gnash&r1=1.40&r2=1.41 http://cvs.savannah.gnu.org/viewcvs/gnash/server/video_stream_instance.h?cvsroot=gnash&r1=1.22&r2=1.23 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.cpp?cvsroot=gnash&r1=1.18&r2=1.19 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.h?cvsroot=gnash&r1=1.12&r2=1.13 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.4634 retrieving revision 1.4635 diff -u -b -r1.4634 -r1.4635 --- ChangeLog 18 Oct 2007 14:38:09 -0000 1.4634 +++ ChangeLog 18 Oct 2007 15:56:54 -0000 1.4635 @@ -1,3 +1,10 @@ +2007-10-18 Tomas Groth Christensen <[EMAIL PROTECTED]> + + * libmedia/VideoDecoder.h,libmedia/gst/VideoDecoder{Ffmpeg.Gst}.{h,cpp}: + Changed decodeToImage to return a raw image::image_base pointer. + * server/video_stream_instance.{cpp,h},server/parser/video_stream_def.{h,cpp}: + Changed to do decoding of video stream on parsing, and not on demand. + 2007-10-18 Chad Musick <[EMAIL PROTECTED]> * testsuite/swfdec/PASSING: More than 20 newly passing tests. Index: libmedia/VideoDecoder.h =================================================================== RCS file: /sources/gnash/gnash/libmedia/VideoDecoder.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -b -r1.4 -r1.5 --- libmedia/VideoDecoder.h 4 Oct 2007 09:37:50 -0000 1.4 +++ libmedia/VideoDecoder.h 18 Oct 2007 15:56:54 -0000 1.5 @@ -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.4 2007/10/04 09:37:50 tgc Exp $ +// $Id: VideoDecoder.h,v 1.5 2007/10/18 15:56:54 tgc Exp $ #ifndef __VIDEODECODER_H__ #define __VIDEODECODER_H__ @@ -102,7 +102,7 @@ /// @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(uint8_t* /*input*/, uint32_t /*inputSize*/) { return std::auto_ptr<image::image_base>(NULL); } + virtual image::image_base* decodeToImage(uint8_t* /*input*/, uint32_t /*inputSize*/) { return NULL; } }; Index: libmedia/gst/VideoDecoderGst.cpp =================================================================== RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -u -b -r1.2 -r1.3 --- libmedia/gst/VideoDecoderGst.cpp 28 Sep 2007 00:33:30 -0000 1.2 +++ libmedia/gst/VideoDecoderGst.cpp 18 Oct 2007 15:56:54 -0000 1.3 @@ -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.2 2007/09/28 00:33:30 tgc Exp $ +// $Id: VideoDecoderGst.cpp,v 1.3 2007/10/18 15:56:54 tgc Exp $ #ifdef HAVE_CONFIG_H #include "config.h" @@ -185,13 +185,11 @@ // gnash calls this when it wants you to decode the given videoframe -std::auto_ptr<image::image_base> +image::image_base* VideoDecoderGst::decodeToImage(uint8_t* data, uint32_t size) { - std::auto_ptr<image::image_base> ret_image; - - ret_image.reset(new image::rgb(width, height)); + image::rgb* ret_image = new image::rgb(width, height); // If there is nothing to decode in the new frame // we just return the lastest. @@ -201,11 +199,9 @@ // auto pointer .. if ( ! decodedFrame.get() ) { - ret_image.reset(NULL); - return ret_image; + return NULL; } - // return decodedFrame->clone() ? ret_image->update(*decodedFrame); return ret_image; } @@ -221,8 +217,7 @@ // auto pointer .. if ( ! decodedFrame.get() ) { - ret_image.reset(NULL); - return ret_image; + return NULL; } // return decodedFrame->clone() ? @@ -230,6 +225,37 @@ return ret_image; } +// gnash calls this when it wants you to decode the given videoframe +/*uint8_t* +VideoDecoderGst::decode(uint8_t* data, uint32_t size, uint32_t& outputSize) +{ + // If there is nothing to decode in the new frame + // we just return the lastest. + if (data == NULL || size == 0 || !decoder) + { + outputSize = 0; + return NULL; + } + + frame = data; + frameSize = size; + + delete input_lock; + + output_lock = new boost::mutex::scoped_lock(output_mutex); + + // If we never decoded any frame return a NULL + // auto pointer .. + if ( ! decodedFrame.get() ) + { + outputSize = 0; + return NULL; + } + + outputSize = width * height * 3; + return decodedFrame->data(); +}*/ + // The callback function which refills the buffer with data void VideoDecoderGst::callback_handoff (GstElement * /*c*/, GstBuffer *buffer, GstPad* /*pad*/, gpointer user_data) Index: libmedia/gst/VideoDecoderGst.h =================================================================== RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -b -r1.4 -r1.5 --- libmedia/gst/VideoDecoderGst.h 4 Oct 2007 09:37:50 -0000 1.4 +++ libmedia/gst/VideoDecoderGst.h 18 Oct 2007 15:56:54 -0000 1.5 @@ -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.4 2007/10/04 09:37:50 tgc Exp $ +// $Id: VideoDecoderGst.h,v 1.5 2007/10/18 15:56:54 tgc Exp $ #ifndef __VIDEODECODERGST_H__ #define __VIDEODECODERGST_H__ @@ -51,9 +51,9 @@ videoCodecType /*format*/, int /*outputFormat*/); -// uint8_t* decode(uint8_t* input, uint32_t inputSize, uint32_t& outputSize); + //uint8_t* decode(uint8_t* input, uint32_t inputSize, uint32_t& outputSize); - std::auto_ptr<image::image_base> decodeToImage(uint8_t* /*input*/, uint32_t /*inputSize*/); + image::image_base* decodeToImage(uint8_t* /*input*/, uint32_t /*inputSize*/); static void callback_handoff (GstElement * /*c*/, GstBuffer *buffer, GstPad* /*pad*/, gpointer user_data); static void callback_output (GstElement * /*c*/, GstBuffer *buffer, GstPad* /*pad*/, gpointer user_data); Index: libmedia/sdl/VideoDecoderFfmpeg.cpp =================================================================== RCS file: /sources/gnash/gnash/libmedia/sdl/VideoDecoderFfmpeg.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -u -b -r1.5 -r1.6 --- libmedia/sdl/VideoDecoderFfmpeg.cpp 8 Oct 2007 11:00:06 -0000 1.5 +++ libmedia/sdl/VideoDecoderFfmpeg.cpp 18 Oct 2007 15:56:55 -0000 1.6 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: VideoDecoderFfmpeg.cpp,v 1.5 2007/10/08 11:00:06 tgc Exp $ +// $Id: VideoDecoderFfmpeg.cpp,v 1.6 2007/10/18 15:56:55 tgc Exp $ #include "VideoDecoderFfmpeg.h" @@ -69,7 +69,7 @@ codec_id = CODEC_ID_FLASHSV; break; default: - log_error(_("Unsupported audio codec %d"), static_cast<int>(format)); + log_error(_("Unsupported video codec %d"), static_cast<int>(format)); return false; } @@ -123,7 +123,7 @@ codec_id = CODEC_ID_FLASHSV; break; default: - log_error(_("Unsupported audio codec %d"), static_cast<int>(info->codec)); + log_error(_("Unsupported video codec %d"), static_cast<int>(info->codec)); return false; } _videoCodec = avcodec_find_decoder(static_cast<CodecID>(codec_id)); @@ -141,7 +141,7 @@ // Reuse the videoCodecCtx from the ffmpeg parser if exists/possible if (info->videoCodecCtx) { - printf("re-using the parsers videoCodecCtx\n"); + log_debug("re-using the parsers videoCodecCtx"); _videoCodecCtx = info->videoCodecCtx; } else { _videoCodecCtx = avcodec_alloc_context(); @@ -318,18 +318,17 @@ } } -std::auto_ptr<image::image_base> +image::image_base* VideoDecoderFfmpeg::decodeToImage(uint8_t* input, uint32_t inputSize) { uint32_t outputSize = 0; uint8_t* decodedData = decode(input, inputSize, outputSize); if (!decodedData || outputSize == 0) { - return std::auto_ptr<image::image_base>(NULL); + return NULL; } - std::auto_ptr<image::image_base> ret; - ret.reset(new image::rgb(_videoCodecCtx->width, _videoCodecCtx->height)); + image::image_base* ret = new image::rgb(_videoCodecCtx->width, _videoCodecCtx->height); ret->update(decodedData); delete [] decodedData; return ret; Index: libmedia/sdl/VideoDecoderFfmpeg.h =================================================================== RCS file: /sources/gnash/gnash/libmedia/sdl/VideoDecoderFfmpeg.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -b -r1.4 -r1.5 --- libmedia/sdl/VideoDecoderFfmpeg.h 4 Oct 2007 09:41:46 -0000 1.4 +++ libmedia/sdl/VideoDecoderFfmpeg.h 18 Oct 2007 15:56:55 -0000 1.5 @@ -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.4 2007/10/04 09:41:46 tgc Exp $ +// $Id: VideoDecoderFfmpeg.h,v 1.5 2007/10/18 15:56:55 tgc Exp $ #ifndef __VIDEODECODERFFMPEG_H__ #define __VIDEODECODERFFMPEG_H__ @@ -54,7 +54,7 @@ uint8_t* decode(uint8_t* input, uint32_t inputSize, uint32_t& outputSize); - std::auto_ptr<image::image_base> decodeToImage(uint8_t* /*input*/, uint32_t /*inputSize*/); + image::image_base* decodeToImage(uint8_t* /*input*/, uint32_t /*inputSize*/); static uint8_t* convertRGB24(AVCodecContext* srcCtx, AVFrame* srcFrame); Index: server/video_stream_instance.cpp =================================================================== RCS file: /sources/gnash/gnash/server/video_stream_instance.cpp,v retrieving revision 1.40 retrieving revision 1.41 diff -u -b -r1.40 -r1.41 --- server/video_stream_instance.cpp 27 Sep 2007 23:59:56 -0000 1.40 +++ server/video_stream_instance.cpp 18 Oct 2007 15:56:55 -0000 1.41 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: video_stream_instance.cpp,v 1.40 2007/09/27 23:59:56 tgc Exp $ +// $Id: video_stream_instance.cpp,v 1.41 2007/10/18 15:56:55 tgc Exp $ #include "sprite_instance.h" #include "video_stream_instance.h" @@ -160,12 +160,12 @@ m_def(def), //m_video_source(NULL), _ns(NULL), - m_decoder(NULL) // don't abort if m_def is null + _embeddedStream(false) { log_debug("video_stream_instance %p ctor", (void*)this); if ( m_def ) { - m_decoder = m_def->get_decoder(); + _embeddedStream = true; } set_prototype(getVideoInterface()); @@ -199,9 +199,7 @@ } // If this is a video from a VideoFrame tag, retrieve a video frame from there. - } else if (m_decoder.get()) { - uint8_t* data = 0; - int size = 0; + } else if (_embeddedStream) { character* parent = get_parent(); assert(parent); sprite_instance* sprite = parent->to_movie(); @@ -209,19 +207,14 @@ int current_frame = sprite->get_current_frame(); assert(m_def); - m_def->get_frame_data(current_frame, &data, &size); - if (size > 0 && data) { - - std::auto_ptr<image::image_base> i(m_decoder->decodeToImage(data, size)); - if (i.get()) + // The returned image is owned by "m_def" + image::image_base* img = m_def->get_frame_data(current_frame); + if (img) { - gnash::render::drawVideoFrame(i.get(), &m, &bounds); - } else { - log_error(_("An error occured while decoding video frame")); - } + gnash::render::drawVideoFrame(img, &m, &bounds); } else { - log_error(_("Video frame data is missing - skipping decoding")); + log_debug(_("Video frame data is missing in frame %d"),current_frame); } } Index: server/video_stream_instance.h =================================================================== RCS file: /sources/gnash/gnash/server/video_stream_instance.h,v retrieving revision 1.22 retrieving revision 1.23 diff -u -b -r1.22 -r1.23 --- server/video_stream_instance.h 27 Sep 2007 23:59:56 -0000 1.22 +++ server/video_stream_instance.h 18 Oct 2007 15:56:55 -0000 1.23 @@ -16,7 +16,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: video_stream_instance.h,v 1.22 2007/09/27 23:59:56 tgc Exp $ +// $Id: video_stream_instance.h,v 1.23 2007/10/18 15:56:55 tgc Exp $ #ifndef GNASH_VIDEO_STREAM_INSTANCE_H #define GNASH_VIDEO_STREAM_INSTANCE_H @@ -99,8 +99,8 @@ // Who owns this ? Should it be an intrusive ptr ? boost::intrusive_ptr<NetStream> _ns; - /// Decoder for embedded video - std::auto_ptr<VideoDecoder> m_decoder; + /// Playing an embbeded video stream ? + bool _embeddedStream; }; void video_class_init(as_object& global); Index: server/parser/video_stream_def.cpp =================================================================== RCS file: /sources/gnash/gnash/server/parser/video_stream_def.cpp,v retrieving revision 1.18 retrieving revision 1.19 diff -u -b -r1.18 -r1.19 --- server/parser/video_stream_def.cpp 27 Sep 2007 23:59:56 -0000 1.18 +++ server/parser/video_stream_def.cpp 18 Oct 2007 15:56:55 -0000 1.19 @@ -16,7 +16,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: video_stream_def.cpp,v 1.18 2007/09/27 23:59:56 tgc Exp $ +// $Id: video_stream_def.cpp,v 1.19 2007/10/18 15:56:55 tgc Exp $ #include "video_stream_def.h" #include "video_stream_instance.h" @@ -32,7 +32,10 @@ video_stream_definition::video_stream_definition(uint16_t char_id) : - m_char_id(char_id) + m_char_id(char_id), + _width(0), + _height(0), + _decoder(NULL) { } @@ -40,6 +43,7 @@ video_stream_definition::~video_stream_definition() { m_video_frames.clear(); + delete _decoder; } @@ -57,19 +61,28 @@ m_num_frames = in->read_u16(); - uint16_t width = in->read_u16(); - uint16_t height = in->read_u16(); + _width = in->read_u16(); + _height = in->read_u16(); m_bound.enclose_point(0, 0); - m_bound.expand_to_point(PIXELS_TO_TWIPS(width), PIXELS_TO_TWIPS(height)); + m_bound.expand_to_point(PIXELS_TO_TWIPS(_width), PIXELS_TO_TWIPS(_height)); m_reserved_flags = in->read_uint(5); m_deblocking_flags = in->read_uint(2); m_smoothing_flags = in->read_bit(); m_codec_id = static_cast<videoCodecType>(in->read_u8()); +#ifdef USE_FFMPEG + _decoder = new VideoDecoderFfmpeg(); +#elif defined(SOUND_GST) + _decoder = new VideoDecoderGst(); +#else + _decoder = new VideoDecoder(); +#endif + bool ret = _decoder->setup(_width, _height, m_deblocking_flags, m_smoothing_flags, m_codec_id, gnash::render::videoFrameFormat()); + if (!ret) delete _decoder; } - else if (tag == SWF::VIDEOFRAME) + else if (tag == SWF::VIDEOFRAME && _decoder) { // We don't use the videoframe number, but instead // each video frame is tied to the swf-frame where @@ -94,7 +107,14 @@ data[i] = in->read_u8(); } - m_video_frames[m->get_loading_frame()] = EmbedFrame(boost::shared_array<uint8_t>(data), size); + image::image_base* img = _decoder->decodeToImage(data, size); + + if (img) { + m_video_frames[m->get_loading_frame()] = img; + } else { + log_error(_("An error occured while decoding video frame in frame %d"), m->get_loading_frame()); + } + delete [] data; } } @@ -107,48 +127,16 @@ return ch; } -std::auto_ptr<VideoDecoder> -video_stream_definition::get_decoder() -{ - - std::auto_ptr<VideoDecoder> decoder; - - if (m_num_frames == 0) return decoder; - - -#ifdef USE_FFMPEG - decoder.reset( new VideoDecoderFfmpeg() ); -#elif defined(SOUND_GST) - decoder.reset( new VideoDecoderGst() ); -#else - decoder.reset( new VideoDecoder() ); -#endif - - bool ret = decoder->setup( - static_cast<int>(TWIPS_TO_PIXELS(m_bound.width())),// m_width, - static_cast<int>(TWIPS_TO_PIXELS(m_bound.height())), // m_height, - m_deblocking_flags, - m_smoothing_flags, - m_codec_id, - gnash::render::videoFrameFormat()); - if (!ret) log_error("The videodecoder cannot decode this video"); - return decoder; - -} - -void -video_stream_definition::get_frame_data(int frameNum, uint8_t** data, int* size) +image::image_base* +video_stream_definition::get_frame_data(int frameNum) { EmbedFrameMap::iterator it = m_video_frames.find(frameNum); if( it != m_video_frames.end() ) { - *data = it->second.first.get(); - *size = it->second.second; + return it->second; } else { - log_error(_("No video data available for frame %d."), frameNum); - *data = 0; - *size = 0; - return; + log_debug(_("No video data available for frame %d."), frameNum); + return NULL; } } Index: server/parser/video_stream_def.h =================================================================== RCS file: /sources/gnash/gnash/server/parser/video_stream_def.h,v retrieving revision 1.12 retrieving revision 1.13 diff -u -b -r1.12 -r1.13 --- server/parser/video_stream_def.h 27 Sep 2007 23:59:56 -0000 1.12 +++ server/parser/video_stream_def.h 18 Oct 2007 15:56:55 -0000 1.13 @@ -16,7 +16,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: video_stream_def.h,v 1.12 2007/09/27 23:59:56 tgc Exp $ +// $Id: video_stream_def.h,v 1.13 2007/10/18 15:56:55 tgc Exp $ #ifndef GNASH_VIDEO_STREAM_DEF_H #define GNASH_VIDEO_STREAM_DEF_H @@ -81,41 +81,14 @@ return m_bound; } - /// Return a newly created embedded-video decoder - // - /// The type of decoder returned currently depends - /// on compile-time defines (FFMPG/GST/none) - /// - /// The returned decoder will be initialized with - /// data kept as member of this class - /// (width/height/codec_id/videoFrameFormat) - /// Note that videoFrameFormat is fetched from the - /// current renderer. - /// - /// This function *never* returns a NULL pointer. - /// - std::auto_ptr<VideoDecoder> get_decoder(); - /// Get the Video frame associated with the given SWF frame number // /// @param frameNum /// 0-based SWF frame number of which we want to fetch associated Video frame. /// - /// @param data - /// Output parameter. If a video frame is available for the specified SWF frame, - /// then the given pointer (*data) will be set to point to a memory buffer owned - /// by this instance; otherwise (no video frame available) the given pointer will - /// be set to zero. - /// - /// @param size - /// Output parameter. If a video frame is available for the specified SWF frame, - /// then the given integer (*size) will be set to the size of the memory buffer - /// returned in the data parameter; otherwise (no video frame available) the given - /// integer will be set to zero. + /// @return pointer (possibly NULL) to an image. The ownership is with the callee /// - /// TODO: return pointer (possibly NULL) to a structure with data&size ? (simpler) - /// - void get_frame_data(int frameNum, uint8_t** data, int* size); + image::image_base* get_frame_data(int frameNum); private: @@ -150,8 +123,6 @@ /// 3: screen video (Flash 7+ only) /// 4: VP6 /// - /// TODO: define an enumeration for the above values - /// videoCodecType m_codec_id; /// Bounds of the video, as read from the DEFINEVIDEOSTREAM tag. @@ -162,10 +133,17 @@ /// Elements of this map are owned by this instance, and will be deleted /// at instance destruction time. /// - typedef std::pair< boost::shared_array<uint8_t>, uint32_t> EmbedFrame; - typedef std::map<uint32_t, EmbedFrame > EmbedFrameMap; + typedef std::map<uint32_t, image::image_base*> EmbedFrameMap; EmbedFrameMap m_video_frames; + /// Width of the video + uint32_t _width; + + /// Height of the video + uint32_t _height; + + /// The decoder used to decode the video frames + VideoDecoder* _decoder; }; } // end namespace gnash _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit