CVSROOT: /sources/gnash Module name: gnash Changes by: Tomas Groth <tgc> 07/10/26 18:43:37
Modified files: . : ChangeLog libmedia : FLVParser.h MediaParser.h VideoDecoder.h libmedia/gst : VideoDecoderGst.cpp VideoDecoderGst.h libmedia/sdl : VideoDecoderFfmpeg.cpp VideoDecoderFfmpeg.h server : video_stream_instance.cpp server/parser : video_stream_def.cpp video_stream_def.h Log message: * libmedia/FLVParser.h, libmedia/MediaParser.h: Move the videoFrameType definition from FLVParser.h to MediaParser.h. * libmedia/VideoDecoder.h, libmedia/gst/VideoDecoder{Gst,ffmpeg}.{h,cpp}: Make decodeToImage return a auto_ptr (again). * server/video_stream_instance.cpp: We now receive the decoded image in a auto_ptr. * server/parser/video_stream_def.{h,cpp}: Changed decoding of embedded video to be on-demand, instead of at-parse. If asked to decode a random frame, we rewind to the lastest keyframe (or the last decoded frame) and decode all the frames needed to produce the requested frame. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4720&r2=1.4721 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/FLVParser.h?cvsroot=gnash&r1=1.1&r2=1.2 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/MediaParser.h?cvsroot=gnash&r1=1.6&r2=1.7 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/VideoDecoder.h?cvsroot=gnash&r1=1.6&r2=1.7 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.cpp?cvsroot=gnash&r1=1.3&r2=1.4 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.h?cvsroot=gnash&r1=1.5&r2=1.6 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/VideoDecoderFfmpeg.cpp?cvsroot=gnash&r1=1.6&r2=1.7 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/VideoDecoderFfmpeg.h?cvsroot=gnash&r1=1.6&r2=1.7 http://cvs.savannah.gnu.org/viewcvs/gnash/server/video_stream_instance.cpp?cvsroot=gnash&r1=1.41&r2=1.42 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.cpp?cvsroot=gnash&r1=1.23&r2=1.24 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.h?cvsroot=gnash&r1=1.15&r2=1.16 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.4720 retrieving revision 1.4721 diff -u -b -r1.4720 -r1.4721 --- ChangeLog 26 Oct 2007 15:43:01 -0000 1.4720 +++ ChangeLog 26 Oct 2007 18:43:35 -0000 1.4721 @@ -1,3 +1,16 @@ +2007-10-26 Tomas Groth Christensen <[EMAIL PROTECTED]> + + * libmedia/FLVParser.h, libmedia/MediaParser.h: Move the videoFrameType + definition from FLVParser.h to MediaParser.h. + * libmedia/VideoDecoder.h, libmedia/gst/VideoDecoder{Gst,ffmpeg}.{h,cpp}: + Make decodeToImage return a auto_ptr (again). + * server/video_stream_instance.cpp: We now receive the decoded image in a + auto_ptr. + * server/parser/video_stream_def.{h,cpp}: Changed decoding of embedded video + to be on-demand, instead of at-parse. If asked to decode a random frame, we + rewind to the lastest keyframe (or the last decoded frame) and decode all + the frames needed to produce the requested frame. + 2007-10-26 Markus Gothe <[EMAIL PROTECTED]> * configure.ac: Added quotation-marks around $extensions_list. Index: libmedia/FLVParser.h =================================================================== RCS file: /sources/gnash/gnash/libmedia/FLVParser.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -b -r1.1 -r1.2 --- libmedia/FLVParser.h 27 Sep 2007 23:59:53 -0000 1.1 +++ libmedia/FLVParser.h 26 Oct 2007 18:43:35 -0000 1.2 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: FLVParser.h,v 1.1 2007/09/27 23:59:53 tgc Exp $ +// $Id: FLVParser.h,v 1.2 2007/10/26 18:43:35 tgc Exp $ // Information about the FLV format can be found at http://osflash.org/flv @@ -33,13 +33,6 @@ namespace gnash { -enum videoFrameType -{ - KEY_FRAME = 1, - INTER_FRAME = 2, - DIS_INTER_FRAME = 3 -}; - enum { CONTAINS_VIDEO = 1, CONTAINS_AUDIO = 4, Index: libmedia/MediaParser.h =================================================================== RCS file: /sources/gnash/gnash/libmedia/MediaParser.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -b -r1.6 -r1.7 --- libmedia/MediaParser.h 23 Oct 2007 18:13:59 -0000 1.6 +++ libmedia/MediaParser.h 26 Oct 2007 18:43:36 -0000 1.7 @@ -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: MediaParser.h,v 1.6 2007/10/23 18:13:59 strk Exp $ +// $Id: MediaParser.h,v 1.7 2007/10/26 18:43:36 tgc Exp $ #ifndef __MEDIAPARSER_H__ #define __MEDIAPARSER_H__ @@ -38,6 +38,19 @@ namespace gnash { +/// Video frame types +enum videoFrameType +{ + /// Key frames + KEY_FRAME = 1, + + /// Interlaced frames + INTER_FRAME = 2, + + /// Disposable interlaced frames + DIS_INTER_FRAME = 3 +}; + /// The type of the codec id passed in the AudioInfo or VideoInfo class enum codecType { Index: libmedia/VideoDecoder.h =================================================================== RCS file: /sources/gnash/gnash/libmedia/VideoDecoder.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -b -r1.6 -r1.7 --- libmedia/VideoDecoder.h 19 Oct 2007 13:50:25 -0000 1.6 +++ libmedia/VideoDecoder.h 26 Oct 2007 18:43:36 -0000 1.7 @@ -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.6 2007/10/19 13:50:25 strk Exp $ +// $Id: VideoDecoder.h,v 1.7 2007/10/26 18:43:36 tgc Exp $ #ifndef __VIDEODECODER_H__ #define __VIDEODECODER_H__ @@ -108,7 +108,7 @@ /// @return a pointer to the image with the decoded data, or NULL if decoding fails. /// The caller owns the decoded data. /// - virtual image::image_base* decodeToImage(uint8_t* /*input*/, uint32_t /*inputSize*/) { return NULL; } + virtual std::auto_ptr<image::image_base> decodeToImage(uint8_t* /*input*/, uint32_t /*inputSize*/) { return std::auto_ptr<image::image_base>(NULL); } }; Index: libmedia/gst/VideoDecoderGst.cpp =================================================================== RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -u -b -r1.3 -r1.4 --- libmedia/gst/VideoDecoderGst.cpp 18 Oct 2007 15:56:54 -0000 1.3 +++ libmedia/gst/VideoDecoderGst.cpp 26 Oct 2007 18:43:36 -0000 1.4 @@ -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.3 2007/10/18 15:56:54 tgc Exp $ +// $Id: VideoDecoderGst.cpp,v 1.4 2007/10/26 18:43:36 tgc Exp $ #ifdef HAVE_CONFIG_H #include "config.h" @@ -185,11 +185,11 @@ // gnash calls this when it wants you to decode the given videoframe -image::image_base* +std::auto_ptr<image::image_base> VideoDecoderGst::decodeToImage(uint8_t* data, uint32_t size) { - image::rgb* ret_image = new image::rgb(width, height); + std::auto_ptr<image::image_base> ret_image(new image::rgb(width, height)); // If there is nothing to decode in the new frame // we just return the lastest. @@ -199,7 +199,7 @@ // auto pointer .. if ( ! decodedFrame.get() ) { - return NULL; + return std::auto_ptr<image::image_base>(NULL); } ret_image->update(*decodedFrame); @@ -217,7 +217,7 @@ // auto pointer .. if ( ! decodedFrame.get() ) { - return NULL; + return std::auto_ptr<image::image_base>(NULL); } // return decodedFrame->clone() ? Index: libmedia/gst/VideoDecoderGst.h =================================================================== RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -b -r1.5 -r1.6 --- libmedia/gst/VideoDecoderGst.h 18 Oct 2007 15:56:54 -0000 1.5 +++ libmedia/gst/VideoDecoderGst.h 26 Oct 2007 18:43:36 -0000 1.6 @@ -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.5 2007/10/18 15:56:54 tgc Exp $ +// $Id: VideoDecoderGst.h,v 1.6 2007/10/26 18:43:36 tgc Exp $ #ifndef __VIDEODECODERGST_H__ #define __VIDEODECODERGST_H__ @@ -53,7 +53,7 @@ //uint8_t* decode(uint8_t* input, uint32_t inputSize, uint32_t& outputSize); - image::image_base* decodeToImage(uint8_t* /*input*/, uint32_t /*inputSize*/); + std::auto_ptr<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.6 retrieving revision 1.7 diff -u -b -r1.6 -r1.7 --- libmedia/sdl/VideoDecoderFfmpeg.cpp 18 Oct 2007 15:56:55 -0000 1.6 +++ libmedia/sdl/VideoDecoderFfmpeg.cpp 26 Oct 2007 18:43:36 -0000 1.7 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: VideoDecoderFfmpeg.cpp,v 1.6 2007/10/18 15:56:55 tgc Exp $ +// $Id: VideoDecoderFfmpeg.cpp,v 1.7 2007/10/26 18:43:36 tgc Exp $ #include "VideoDecoderFfmpeg.h" @@ -318,17 +318,17 @@ } } -image::image_base* +std::auto_ptr<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 NULL; + return std::auto_ptr<image::image_base>(NULL); } - image::image_base* ret = new image::rgb(_videoCodecCtx->width, _videoCodecCtx->height); + std::auto_ptr<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.6 retrieving revision 1.7 diff -u -b -r1.6 -r1.7 --- libmedia/sdl/VideoDecoderFfmpeg.h 19 Oct 2007 13:50:25 -0000 1.6 +++ libmedia/sdl/VideoDecoderFfmpeg.h 26 Oct 2007 18:43:36 -0000 1.7 @@ -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.6 2007/10/19 13:50:25 strk Exp $ +// $Id: VideoDecoderFfmpeg.h,v 1.7 2007/10/26 18:43:36 tgc Exp $ #ifndef __VIDEODECODERFFMPEG_H__ #define __VIDEODECODERFFMPEG_H__ @@ -56,7 +56,7 @@ uint8_t* decode(uint8_t* input, uint32_t inputSize, uint32_t& outputSize); - image::image_base* decodeToImage(uint8_t* /*input*/, uint32_t /*inputSize*/); + std::auto_ptr<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.41 retrieving revision 1.42 diff -u -b -r1.41 -r1.42 --- server/video_stream_instance.cpp 18 Oct 2007 15:56:55 -0000 1.41 +++ server/video_stream_instance.cpp 26 Oct 2007 18:43:36 -0000 1.42 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: video_stream_instance.cpp,v 1.41 2007/10/18 15:56:55 tgc Exp $ +// $Id: video_stream_instance.cpp,v 1.42 2007/10/26 18:43:36 tgc Exp $ #include "sprite_instance.h" #include "video_stream_instance.h" @@ -209,10 +209,10 @@ assert(m_def); // The returned image is owned by "m_def" - image::image_base* img = m_def->get_frame_data(current_frame); - if (img) + std::auto_ptr<image::image_base> img = m_def->get_frame_data(current_frame); + if (img.get()) { - gnash::render::drawVideoFrame(img, &m, &bounds); + gnash::render::drawVideoFrame(img.get(), &m, &bounds); } else { log_debug(_("Video frame data is missing in frame %d"),current_frame); } Index: server/parser/video_stream_def.cpp =================================================================== RCS file: /sources/gnash/gnash/server/parser/video_stream_def.cpp,v retrieving revision 1.23 retrieving revision 1.24 diff -u -b -r1.23 -r1.24 --- server/parser/video_stream_def.cpp 19 Oct 2007 13:50:25 -0000 1.23 +++ server/parser/video_stream_def.cpp 26 Oct 2007 18:43:36 -0000 1.24 @@ -16,11 +16,12 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: video_stream_def.cpp,v 1.23 2007/10/19 13:50:25 strk Exp $ +// $Id: video_stream_def.cpp,v 1.24 2007/10/26 18:43:36 tgc Exp $ #include "video_stream_def.h" #include "video_stream_instance.h" #include "render.h" +#include "BitsReader.h" #ifdef USE_FFMPEG #include "VideoDecoderFfmpeg.h" @@ -33,6 +34,7 @@ video_stream_definition::video_stream_definition(uint16_t char_id) : m_char_id(char_id), + m_last_decoded_frame(-1), _width(0), _height(0), _decoder(NULL) @@ -42,11 +44,6 @@ video_stream_definition::~video_stream_definition() { - for (EmbedFrameMap::iterator i=m_video_frames.begin(), e=m_video_frames.end(); - i!=e; ++i) - { - delete i->second; - } } @@ -65,6 +62,7 @@ _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)); @@ -106,28 +104,43 @@ unsigned int dataSize = in->get_tag_end_position() - in->get_position(); unsigned int totSize = dataSize+padding; - boost::scoped_array<uint8_t> data ( new uint8_t[totSize] ); + boost::shared_array<uint8_t> data ( new uint8_t[totSize] ); for (unsigned int i = 0; i < dataSize; ++i) { data[i] = in->read_u8(); } if ( padding ) memset(&data[dataSize], 0, padding); // pad with zeroes if needed - // TODO: should we pass dataSize instead of totSize to decodeToImage ? - std::auto_ptr<image::image_base> img ( _decoder->decodeToImage(data.get(), totSize) ); - if ( img.get() ) - { - // TODO: why don't we use the frame number specified - // in the tag instead of skipping it ? - size_t frameNum = m->get_loading_frame(); + // Check what kind of frame this is + videoFrameType ft; + if (m_codec_id == VIDEO_CODEC_H263) { + // Parse the h263 header to determine the frame type. The position of the + // info varies if the frame size is custom. + std::auto_ptr<BitsReader> br (new BitsReader(data.get(), totSize)); + uint32_t tmp = br->read_uint(30); + tmp = br->read_uint(3); + if (tmp == 0) tmp = br->read_uint(32); + else if (tmp == 1) tmp = br->read_uint(16); + + // Finally we're at the info, read and use + videoFrameType ft; + tmp = br->read_uint(3); + if (tmp == 0) ft = KEY_FRAME; + else if (tmp == 1) ft = INTER_FRAME; + else ft = DIS_INTER_FRAME; + + } else if (m_codec_id == VIDEO_CODEC_VP6 || m_codec_id == VIDEO_CODEC_VP6A) { + // Get the info from the VP6 header + if (!(data.get()[0] & 0x80)) ft = KEY_FRAME; + else ft = INTER_FRAME; - setFrameData(frameNum, img); - } - else - { - log_error(_("An error occured while decoding video frame in frame %d"), m->get_loading_frame()); + } else { + ft = KEY_FRAME; } + + setFrameData(m->get_loading_frame(), data, totSize, ft); + } @@ -138,31 +151,55 @@ return ch; } -image::image_base* -video_stream_definition::get_frame_data(int frameNum) +std::auto_ptr<image::image_base> +video_stream_definition::get_frame_data(uint32_t frameNum) { + + // Check if the requested frame hold any video data. EmbedFrameMap::iterator it = m_video_frames.find(frameNum); - if( it != m_video_frames.end() ) + if( it == m_video_frames.end() ) { - return it->second; - } else { log_debug(_("No video data available for frame %d."), frameNum); - return NULL; + return std::auto_ptr<image::image_base>(NULL); } + + // rewind to the nearest keyframe, or the last frame we decoded + while (static_cast<uint32_t>(m_last_decoded_frame+1) != it->first && it->second->frameType != KEY_FRAME && it != m_video_frames.begin()) it--; + + std::auto_ptr<image::image_base> ret; + + // Decode all the frames needed to produce the requested one + while (it->first <= frameNum && it != m_video_frames.end()) { + // If this is a disposable interlaced frame, and it is not the + // last one to be decoded, we skip the decoding. + if (!(it->second->frameType == DIS_INTER_FRAME && it->first != frameNum)) { + ret.reset(NULL); + ret = _decoder->decodeToImage(it->second->videoData.get(), it->second->dataSize); + } + it++; + } + + m_last_decoded_frame = frameNum; + + return ret; + } void -video_stream_definition::setFrameData(uint32_t frameNum, std::auto_ptr<image::image_base> image) +video_stream_definition::setFrameData(uint32_t frameNum, boost::shared_array<uint8_t> data, uint32_t size, videoFrameType ft) { - image::image_base*& ptr = m_video_frames[frameNum]; - if ( ptr ) + EmbedFrameMap::iterator it = m_video_frames.find(frameNum); + if( it != m_video_frames.end() ) { IF_VERBOSE_MALFORMED_SWF( log_swferror(_("Mulitple video frames defined for frame %u"), frameNum); ); return; } - ptr = image.release(); + + boost::shared_ptr<VideoData> vd (new VideoData(data, size,ft)); + m_video_frames[frameNum] = vd; + } } // namespace gnash Index: server/parser/video_stream_def.h =================================================================== RCS file: /sources/gnash/gnash/server/parser/video_stream_def.h,v retrieving revision 1.15 retrieving revision 1.16 diff -u -b -r1.15 -r1.16 --- server/parser/video_stream_def.h 19 Oct 2007 12:17:28 -0000 1.15 +++ server/parser/video_stream_def.h 26 Oct 2007 18:43:36 -0000 1.16 @@ -16,7 +16,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -// $Id: video_stream_def.h,v 1.15 2007/10/19 12:17:28 strk Exp $ +// $Id: video_stream_def.h,v 1.16 2007/10/26 18:43:36 tgc Exp $ #ifndef GNASH_VIDEO_STREAM_DEF_H #define GNASH_VIDEO_STREAM_DEF_H @@ -36,10 +36,33 @@ #include <map> #include <boost/shared_array.hpp> +#include <boost/shared_ptr.hpp> #include <boost/scoped_ptr.hpp> namespace gnash { + +/// Class used to store data for the undecoded embedded video frames. +/// Contains the data, the data size and the type of the frame +class VideoData { +public: + VideoData(boost::shared_array<uint8_t> data, uint32_t size, videoFrameType ft) + : + videoData(data), + dataSize(size), + frameType(ft) + { + } + + ~VideoData() + { + } + + boost::shared_array<uint8_t> videoData; + uint32_t dataSize; + videoFrameType frameType; +}; + class video_stream_definition : public character_def { public: @@ -89,7 +112,7 @@ /// /// @return pointer (possibly NULL) to an image. The ownership is with the callee /// - image::image_base* get_frame_data(int frameNum); + std::auto_ptr<image::image_base> get_frame_data(uint32_t frameNum); private: @@ -134,9 +157,12 @@ /// Elements of this map are owned by this instance, and will be deleted /// at instance destruction time. /// - typedef std::map<uint32_t, image::image_base*> EmbedFrameMap; + typedef std::map<uint32_t, boost::shared_ptr<VideoData> > EmbedFrameMap; EmbedFrameMap m_video_frames; + /// Last decoded frame number + int32_t m_last_decoded_frame; + /// Set data for the given frame // /// If a frame image is already known for the given frame number @@ -151,7 +177,7 @@ /// @param img /// Frame data. Ownership is transferred. /// - void setFrameData(uint32_t frameNum, std::auto_ptr<image::image_base> img); + void setFrameData(uint32_t frameNum, boost::shared_array<uint8_t> data, uint32_t size, videoFrameType ft); /// Width of the video uint32_t _width; _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit