[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog libbase/FLVParser.cpp libbase/F... [gnash
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog libbase/FLVParser.cpp libbase/F... [gnash_0_8_3_branch] |
Date: |
Sat, 10 May 2008 11:05:44 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Branch: gnash_0_8_3_branch
Changes by: Sandro Santilli <strk> 08/05/10 11:05:44
Modified files:
. : ChangeLog
libbase : FLVParser.cpp FLVParser.h utility.h
Log message:
* libbase/utility.h: add smallestMultipleContaining
utility function.
* libbase/FLVParser.{cpp,h}: always allocate a multiple
of 64 (READ_CHUNK) greater or equal the actual frame
size augmented by 64 bytes (PADDING_BYTES): the multiple
thing was suggested by bjacques, the PADDING_BYTES I found
by myself (for h264 parser in ffmpeg...). Always check
return from tu_file::read_bytes to catch premature end
of input. Merge duplicated code into makeAudioFrame and
makeVideoFrame static functions.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&only_with_tag=gnash_0_8_3_branch&r1=1.6573.2.2&r2=1.6573.2.3
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/FLVParser.cpp?cvsroot=gnash&only_with_tag=gnash_0_8_3_branch&r1=1.29.2.1&r2=1.29.2.2
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/FLVParser.h?cvsroot=gnash&only_with_tag=gnash_0_8_3_branch&r1=1.24.2.1&r2=1.24.2.2
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/utility.h?cvsroot=gnash&only_with_tag=gnash_0_8_3_branch&r1=1.49&r2=1.49.2.1
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6573.2.2
retrieving revision 1.6573.2.3
diff -u -b -r1.6573.2.2 -r1.6573.2.3
--- ChangeLog 9 May 2008 17:27:25 -0000 1.6573.2.2
+++ ChangeLog 10 May 2008 11:05:42 -0000 1.6573.2.3
@@ -1,3 +1,16 @@
+2008-05-10 Sandro Santilli <address@hidden>
+
+ * libbase/utility.h: add smallestMultipleContaining
+ utility function.
+ * libbase/FLVParser.{cpp,h}: always allocate a multiple
+ of 64 (READ_CHUNK) greater or equal the actual frame
+ size augmented by 64 bytes (PADDING_BYTES): the multiple
+ thing was suggested by bjacques, the PADDING_BYTES I found
+ by myself (for h264 parser in ffmpeg...). Always check
+ return from tu_file::read_bytes to catch premature end
+ of input. Merge duplicated code into makeAudioFrame and
+ makeVideoFrame static functions.
+
2008-05-09 Sandro Santilli <address@hidden>
* libmedia/: Makefile.cm, FLVParser.{cpp,h}: drop unused FLVParser
Index: libbase/FLVParser.cpp
===================================================================
RCS file: /sources/gnash/gnash/libbase/FLVParser.cpp,v
retrieving revision 1.29.2.1
retrieving revision 1.29.2.2
diff -u -b -r1.29.2.1 -r1.29.2.2
--- libbase/FLVParser.cpp 9 May 2008 16:48:10 -0000 1.29.2.1
+++ libbase/FLVParser.cpp 10 May 2008 11:05:43 -0000 1.29.2.2
@@ -23,16 +23,76 @@
#include "FLVParser.h"
#include "amf.h"
#include "log.h"
+#include "utility.h"
using namespace std;
#define PADDING_BYTES 64
+#define READ_CHUNKS 64
// Define the following macro the have seek() operations printed
//#define GNASH_DEBUG_SEEK 1
namespace gnash {
+static std::auto_ptr<FLVFrame>
+makeVideoFrame(tu_file& in, const FLVVideoFrame& frameInfo)
+{
+ std::auto_ptr<FLVFrame> frame ( new FLVFrame );
+
+ frame->dataSize = frameInfo.dataSize;
+ frame->timestamp = frameInfo.timestamp;
+ frame->tag = 9;
+
+ if ( in.set_position(frameInfo.dataPosition) )
+ {
+ log_error(_("Failed seeking to videoframe in FLV input"));
+ frame.reset();
+ return frame;
+ }
+
+ unsigned long int dataSize = frameInfo.dataSize;
+ unsigned long int chunkSize = smallestMultipleContaining(READ_CHUNKS,
dataSize+PADDING_BYTES);
+
+ frame->data = new boost::uint8_t[chunkSize];
+ size_t bytesread = in.read_bytes(frame->data, dataSize);
+
+ unsigned long int padding = chunkSize-dataSize;
+ assert(padding);
+ memset(frame->data + bytesread, 0, padding);
+
+ return frame;
+}
+
+static std::auto_ptr<FLVFrame>
+makeAudioFrame(tu_file& in, const FLVAudioFrame& frameInfo)
+{
+ std::auto_ptr<FLVFrame> frame ( new FLVFrame );
+ frame->dataSize = frameInfo.dataSize;
+ frame->timestamp = frameInfo.timestamp;
+
+ if ( in.set_position(frameInfo.dataPosition) )
+ {
+ log_error(_("Failed seeking to audioframe in FLV input"));
+ frame.reset();
+ return frame;
+ }
+
+ unsigned long int dataSize = frameInfo.dataSize;
+ unsigned long int chunkSize = smallestMultipleContaining(READ_CHUNKS,
dataSize+PADDING_BYTES);
+
+ frame->data = new boost::uint8_t[chunkSize];
+ size_t bytesread = in.read_bytes(frame->data, dataSize);
+
+ unsigned long int padding = chunkSize-dataSize;
+ assert(padding);
+ memset(frame->data + bytesread, 0, padding);
+
+ frame->tag = 8;
+
+ return frame;
+}
+
FLVParser::FLVParser(tu_file& lt)
:
_lt(lt),
@@ -162,32 +222,30 @@
if (useAudio) {
- FLVFrame* frame = new FLVFrame;
- frame->dataSize = _audioFrames[_nextAudioFrame]->dataSize;
- frame->timestamp = _audioFrames[_nextAudioFrame]->timestamp;
-
- _lt.set_position(_audioFrames[_nextAudioFrame]->dataPosition);
// TODO: check return code...
- frame->data = new boost::uint8_t[frame->dataSize +
PADDING_BYTES];
- size_t bytesread = _lt.read_bytes(frame->data, frame->dataSize);
- memset(frame->data + bytesread, 0, PADDING_BYTES);
+ FLVAudioFrame* frameInfo = _audioFrames[_nextAudioFrame];
+
+ std::auto_ptr<FLVFrame> frame = makeAudioFrame(_lt, *frameInfo);
+ if ( ! frame.get() )
+ {
+ log_error("Could not make audio frame %d",
_nextAudioFrame);
+ return 0;
+ }
- frame->tag = 8;
_nextAudioFrame++;
- return frame;
+ return frame.release(); // TODO: return by auto_ptr
} else {
- FLVFrame* frame = new FLVFrame;
- frame->dataSize = _videoFrames[_nextVideoFrame]->dataSize;
- frame->timestamp = _videoFrames[_nextVideoFrame]->timestamp;
-
- _lt.set_position(_videoFrames[_nextVideoFrame]->dataPosition);
// TODO: check return code
- frame->data = new boost::uint8_t[frame->dataSize +
PADDING_BYTES];
- size_t bytesread = _lt.read_bytes(frame->data,
frame->dataSize);
- memset(frame->data + bytesread, 0, PADDING_BYTES);
- frame->tag = 9;
+ FLVVideoFrame* frameInfo = _videoFrames[_nextVideoFrame];
+ std::auto_ptr<FLVFrame> frame = makeVideoFrame(_lt, *frameInfo);
+ if ( ! frame.get() )
+ {
+ log_error("Could not make video frame %d",
_nextVideoFrame);
+ return 0;
+ }
+
_nextVideoFrame++;
- return frame;
+ return frame.release(); // TODO: return by auto_ptr
}
@@ -208,20 +266,16 @@
// If the needed frame can't be parsed (EOF reached) return NULL
if (_audioFrames.size() <= _nextAudioFrame || _audioFrames.size() == 0)
return NULL;
- FLVFrame* frame = new FLVFrame;
- frame->dataSize = _audioFrames[_nextAudioFrame]->dataSize;
- frame->timestamp = _audioFrames[_nextAudioFrame]->timestamp;
- frame->tag = 8;
-
- _lt.set_position(_audioFrames[_nextAudioFrame]->dataPosition); // TODO:
check return code
- frame->data = new
boost::uint8_t[_audioFrames[_nextAudioFrame]->dataSize +
- PADDING_BYTES];
- size_t bytesread = _lt.read_bytes(frame->data,
- _audioFrames[_nextAudioFrame]->dataSize);
- memset(frame->data + bytesread, 0, PADDING_BYTES);
+ FLVAudioFrame* frameInfo = _audioFrames[_nextAudioFrame];
+ std::auto_ptr<FLVFrame> frame = makeAudioFrame(_lt, *frameInfo);
+ if ( ! frame.get() )
+ {
+ log_error("Could not make audio frame %d", _nextAudioFrame);
+ return 0;
+ }
_nextAudioFrame++;
- return frame;
+ return frame.release(); // TODO: return by auto_ptr
}
@@ -249,21 +303,17 @@
return NULL;
}
-
- FLVFrame* frame = new FLVFrame;
- frame->dataSize = _videoFrames[_nextVideoFrame]->dataSize;
- frame->timestamp = _videoFrames[_nextVideoFrame]->timestamp;
- frame->tag = 9;
-
- _lt.set_position(_videoFrames[_nextVideoFrame]->dataPosition); // TODO:
check return code
- frame->data = new
boost::uint8_t[_videoFrames[_nextVideoFrame]->dataSize +
- PADDING_BYTES];
- size_t bytesread = _lt.read_bytes(frame->data,
- _videoFrames[_nextVideoFrame]->dataSize);
- memset(frame->data + bytesread, 0, PADDING_BYTES);
+ // TODO: let a function do this
+ FLVVideoFrame* frameInfo = _videoFrames[_nextVideoFrame];
+ std::auto_ptr<FLVFrame> frame = makeVideoFrame(_lt, *frameInfo);
+ if ( ! frame.get() )
+ {
+ log_error("Could not make video frame %d", _nextVideoFrame);
+ return 0;
+ }
_nextVideoFrame++;
- return frame;
+ return frame.release(); // TODO: return by auto_ptr
}
@@ -528,7 +578,12 @@
// Read the tag info
boost::uint8_t tag[12];
- _lt.read_bytes(tag, 12);
+ int actuallyRead = _lt.read_bytes(tag, 12);
+ if ( actuallyRead < 12 )
+ {
+ log_error("FLVParser::parseNextFrame: can't read tag info
(needed 12 bytes, only got %d)", actuallyRead);
+ return false;
+ }
// Extract length and timestamp
boost::uint32_t bodyLength = getUInt24(&tag[1]);
@@ -590,7 +645,12 @@
return false;
}
boost::uint8_t videohead[12];
- _lt.read_bytes(videohead, 12); // TODO: use
return code
+ int actuallyRead = _lt.read_bytes(videohead,
12);
+ if ( actuallyRead < 12 )
+ {
+ log_error("FLVParser::parseNextFrame: can't read H263 video
header (needed 12 bytes, only got %d)", actuallyRead);
+ return false;
+ }
bool sizebit1 = (videohead[3] & 0x02);
bool sizebit2 = (videohead[3] & 0x01);
@@ -633,6 +693,7 @@
}
} else if (tag[0] == META_TAG) {
+ LOG_ONCE( log_unimpl("FLV MetaTag parser") );
// Extract information from the meta tag
/*_lt.seek(_lastParsedPosition+16);
char* metaTag = new char[bodyLength];
@@ -691,3 +752,4 @@
} // end of gnash namespace
#undef PADDING_BYTES
+#undef READ_CHUNKS
Index: libbase/FLVParser.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/FLVParser.h,v
retrieving revision 1.24.2.1
retrieving revision 1.24.2.2
diff -u -b -r1.24.2.1 -r1.24.2.2
--- libbase/FLVParser.h 9 May 2008 16:48:10 -0000 1.24.2.1
+++ libbase/FLVParser.h 10 May 2008 11:05:43 -0000 1.24.2.2
@@ -91,14 +91,21 @@
};
+/// Information about an FLV Audio Frame
class FLVVideoFrame
{
public:
+
+ /// Type of this frame (should likely be videoFrameType)
boost::uint16_t frameType;
+
+ /// Size of the frame in bytes
boost::uint32_t dataSize;
+
+ /// Start of frame data in stream
boost::uint64_t dataPosition;
- /// in milliseconds
+ /// Timestamp in milliseconds
boost::uint32_t timestamp;
/// Return true if this video frame is a key frame
@@ -109,13 +116,17 @@
};
+/// Information about an FLV Audio Frame
class FLVAudioFrame
{
public:
+ /// Size of the frame in bytes
boost::uint32_t dataSize;
+
+ /// Start of frame data in stream
boost::uint64_t dataPosition;
- /// in milliseconds
+ /// Timestamp in milliseconds
boost::uint32_t timestamp;
};
@@ -307,11 +318,17 @@
/// The interface to the file, externally owned
tu_file& _lt;
+ // NOTE: FLVVideoFrame is a relatively small structure,
+ // chances are keeping by value here would reduce
+ // memory fragmentation with no big cost
typedef std::vector<FLVVideoFrame*> VideoFrames;
/// list of videoframes, does no contain the frame data.
VideoFrames _videoFrames;
+ // NOTE: FLVAudioFrame is a relatively small structure,
+ // chances are keeping by value here would reduce
+ // memory fragmentation with no big cost
typedef std::vector<FLVAudioFrame*> AudioFrames;
/// list of audioframes, does no contain the frame data.
Index: libbase/utility.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/utility.h,v
retrieving revision 1.49
retrieving revision 1.49.2.1
diff -u -b -r1.49 -r1.49.2.1
--- libbase/utility.h 29 Apr 2008 17:35:42 -0000 1.49
+++ libbase/utility.h 10 May 2008 11:05:43 -0000 1.49.2.1
@@ -132,6 +132,18 @@
inline double trunc(double x) { return (x < 0 ? -(std::floor(-x)) :
std::floor(x)); }
#endif
+
+/// \brief
+/// Return the smallest multiple of given base greater or equal
+/// given limit
+inline unsigned int
+smallestMultipleContaining(unsigned int base, unsigned int x)
+{
+ int f=x/base;
+ if ( x%base ) f++;
+ return base*f;
+}
+
// Handy macro to quiet compiler warnings about unused parameters/variables.
#define UNUSED(x) (x) = (x)