[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10033: Some more refactoring of lar
From: |
Bastiaan Jacques |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10033: Some more refactoring of large blobs of code. |
Date: |
Tue, 21 Oct 2008 17:15:10 +0200 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10033
committer: Bastiaan Jacques <address@hidden>
branch nick: trunk
timestamp: Tue 2008-10-21 17:15:10 +0200
message:
Some more refactoring of large blobs of code.
modified:
libmedia/FLVParser.cpp
libmedia/FLVParser.h
=== modified file 'libmedia/FLVParser.cpp'
--- a/libmedia/FLVParser.cpp 2008-10-20 17:32:02 +0000
+++ b/libmedia/FLVParser.cpp 2008-10-21 15:15:10 +0000
@@ -149,69 +149,13 @@
FLVParser::parseNextChunk()
{
bool indexOnly = bufferFull(); // won't lock, but our caller locked...
- if ( indexOnly ) return indexNextTag();
- else return parseNextTag();
+ return parseNextTag(indexOnly);
}
// would be called by parser thread
bool
-FLVParser::indexNextTag()
+FLVParser::indexTag(const boost::uint8_t* tag, boost::uint32_t timestamp,
boost::uint32_t thisTagPos)
{
- //GNASH_REPORT_FUNCTION;
-
- // lock the stream while reading from it, so actionscript
- // won't mess with the parser on seek or on getBytesLoaded
- boost::mutex::scoped_lock streamLock(_streamMutex);
-
- if ( _indexingCompleted ) return false;
-
- unsigned long thisTagPos = _nextPosToIndex;
-
- if ( _stream->seek(thisTagPos+4) )
- {
- log_debug("FLVParser::indexNextTag failed seeking to %d: %s",
thisTagPos+4);
- _indexingCompleted=true;
- //_parsingComplete=true; // better let ::parseNextTag set this
- return false;
- }
-
- // Read the tag info - NOTE: will block... (should we avoid the block
here ?)
- boost::uint8_t tag[12];
- int actuallyRead = _stream->read(tag, 12);
- if ( actuallyRead < 12 )
- {
- if ( actuallyRead )
- log_error("FLVParser::indexNextTag: can't read tag info
(needed 12 bytes, only got %d)", actuallyRead);
- // else { assert(_stream->eof(); } ?
- //log_debug("%d bytes read from input stream, when %d were
requested", actuallyRead, 12);
- _indexingCompleted=true;
- //_parsingComplete=true; // better let ::parseNextTag set this
-
- // update bytes loaded
- boost::mutex::scoped_lock lock(_bytesLoadedMutex);
- _bytesLoaded = _stream->tell();
-
- return false;
- }
-
- // Extract length and timestamp
- boost::uint32_t bodyLength = getUInt24(&tag[1]);
- boost::uint32_t timestamp = getUInt24(&tag[4]);
-
- _nextPosToIndex += 15 + bodyLength;
-
- if ( _nextPosToIndex > _bytesLoaded ) {
- boost::mutex::scoped_lock lock(_bytesLoadedMutex);
- _bytesLoaded = _nextPosToIndex;
- }
-
- // check for empty tag
- if (bodyLength == 0)
- {
- log_debug("Empty tag, no index");
- return false;
- }
-
if (tag[0] == FLV_AUDIO_TAG)
{
if ( ! _video) // if we have video we let that drive cue points
@@ -246,8 +190,130 @@
return true;
}
+std::auto_ptr<EncodedAudioFrame>
+FLVParser::parseAudioTag(boost::uint32_t bodyLength, boost::uint32_t
timestamp, boost::uint32_t thisTagPos, const boost::uint8_t* tag)
+{
+ std::auto_ptr<EncodedAudioFrame> frame;
+
+ if ( ! _audio ) {
+ log_error(_("Unexpected audio tag found at offset %d FLV stream
advertising no audio in header. We'll warn only once for each FLV, expecting
any further audio tag."), thisTagPos);
+ _audio = true; // TOCHECK: is this safe ?
+ }
+
+ boost::uint8_t codec = (tag[11] & 0xf0) >> 4;
+
+ bool header = false;
+
+ if (codec == AUDIO_CODEC_AAC) {
+ boost::uint8_t packettype = _stream->read_byte();
+ header = (packettype == 0);
+ --bodyLength;
+ }
+
+ frame = readAudioFrame(bodyLength-1, timestamp);
+ if ( ! frame.get() ) {
+ log_error("could not read audio frame?");
+ }
+
+ // If this is the first audioframe no info about the
+ // audio format has been noted, so we do that now
+ if ( !_audioInfo.get() )
+ {
+ int samplerate = (tag[11] & 0x0C) >> 2;
+ if (samplerate == 0) samplerate = 5500;
+ else if (samplerate == 1) samplerate = 11000;
+ else if (samplerate == 2) samplerate = 22050;
+ else if (samplerate == 3) samplerate = 44100;
+
+ int samplesize = (tag[11] & 0x02) >> 1;
+ if (samplesize == 0) samplesize = 1;
+ else samplesize = 2;
+
+ _audioInfo.reset( new AudioInfo(codec, samplerate, samplesize,
(tag[11] & 0x01) >> 0, 0, FLASH) );
+ if (header) {
+ boost::uint8_t* newbuf = new
boost::uint8_t[frame->dataSize];
+ memcpy(newbuf, frame->data.get(), frame->dataSize);
+
+ _audioInfo->extra.reset(
+ new ExtraAudioInfoFlv(newbuf, frame->dataSize)
+ );
+
+ // The FAAD decoder will reject us if we pass the
header buffer.
+ // It will receive the header via the extra audio info
anyway.
+ frame.reset();
+ }
+ }
+
+ return frame;
+}
+
+std::auto_ptr<EncodedVideoFrame>
+FLVParser::parseVideoTag(boost::uint32_t bodyLength, boost::uint32_t
timestamp, boost::uint32_t thisTagPos, const boost::uint8_t* tag)
+{
+ if ( ! _video ) {
+ log_error(_("Unexpected video tag found at offset %d of FLV
stream advertising no video in header. We'll warn only once per FLV, expecting
any further video tag."), thisTagPos);
+ _video = true; // TOCHECK: is this safe ?
+ }
+ // 1:keyframe, 2:interlacedFrame, 3:disposableInterlacedFrame
+ int frameType = (tag[11] & 0xf0) >> 4;
+
+ boost::uint16_t codec = (tag[11] & 0x0f) >> 0;
+
+ if (codec == VIDEO_CODEC_VP6 || codec == VIDEO_CODEC_VP6A)
+ {
+ _stream->read_byte();
+ --bodyLength;
+ }
+
+ bool header = false;
+
+ if (codec == VIDEO_CODEC_H264) {
+ boost::uint8_t packettype = _stream->read_byte();
+ IF_VERBOSE_PARSE( log_debug(_("AVC packet type: %d"),
(unsigned)packettype) );
+
+ header = (packettype == 0);
+
+ // 24-bits value for composition time offset ignored for now.
+ boost::uint8_t tmp[3];
+ _stream->read(tmp, 3);
+
+ bodyLength -= 4;
+ }
+
+ size_t dataPosition = _stream->tell();
+
+ std::auto_ptr<EncodedVideoFrame> frame = readVideoFrame(bodyLength-1,
timestamp);
+ if ( ! frame.get() )
+ {
+ log_error("could not read video frame?");
+ }
+
+ // If this is the first videoframe no info about the
+ // video format has been noted, so we do that now
+ if ( ! _videoInfo.get() )
+ {
+ _videoInfo.reset( new VideoInfo(codec, 0 /* width */, 0 /*
height */, 0 /*frameRate*/, 0 /*duration*/, FLASH /*codec type*/) );
+
+ if (header) {
+ boost::uint8_t* newbuf = new
boost::uint8_t[frame->dataSize()];
+ memcpy(newbuf, frame->data(), frame->dataSize());
+
+ _videoInfo->extra.reset(
+ new ExtraVideoInfoFlv(newbuf, frame->dataSize())
+ );
+ // Don't bother emitting the header buffer.
+ frame.reset();
+ }
+ }
+ return frame;
+}
+
+
+
+
+
// would be called by parser thread
-bool FLVParser::parseNextTag()
+bool FLVParser::parseNextTag(bool index_only)
{
//GNASH_REPORT_FUNCTION;
@@ -293,7 +359,7 @@
_lastParsedPosition += 15 + bodyLength;
- bool doIndex = _lastParsedPosition+4 > _nextPosToIndex;
+ bool doIndex = (_lastParsedPosition+4 > _nextPosToIndex) || index_only;
if ( doIndex )
{
//log_debug("::parseNextTag setting _nextPosToIndex=%d",
_lastParsedPosition+4);
@@ -309,70 +375,19 @@
// check for empty tag
if (bodyLength == 0) return true;
+ if (doIndex) {
+ indexTag(tag, timestamp, thisTagPos);
+ if (index_only) {
+ return true;
+ }
+ }
+
if (tag[0] == FLV_AUDIO_TAG)
{
- if ( ! _audio ) {
- log_error(_("Unexpected audio tag found at offset %d
FLV stream advertising no audio in header. We'll warn only once for each FLV,
expecting any further audio tag."), thisTagPos);
- _audio = true; // TOCHECK: is this safe ?
- }
-
- if ( doIndex && ! _video ) // if we have video we let that
drive cue points
- {
- // we can theoretically seek anywhere, but
- // let's just keep 5 seconds of distance
- CuePointsMap::iterator it =
_cuePoints.lower_bound(timestamp);
- if ( it == _cuePoints.end() || it->first - timestamp >=
5000)
- {
- log_debug("Added cue point at timestamp %d and
position %d (audio frame)", timestamp, thisTagPos);
- _cuePoints[timestamp] = thisTagPos;
- }
- }
-
- boost::uint8_t codec = (tag[11] & 0xf0) >> 4;
-
- bool header = false;
-
- if (codec == AUDIO_CODEC_AAC) {
- boost::uint8_t packettype = _stream->read_byte();
- header = (packettype == 0);
- --bodyLength;
- }
-
- std::auto_ptr<EncodedAudioFrame> frame =
readAudioFrame(bodyLength-1, timestamp);
- if ( ! frame.get() ) {
- log_error("could not read audio frame?");
- return true;
- }
-
- // If this is the first audioframe no info about the
- // audio format has been noted, so we do that now
- if ( !_audioInfo.get() )
- {
- int samplerate = (tag[11] & 0x0C) >> 2;
- if (samplerate == 0) samplerate = 5500;
- else if (samplerate == 1) samplerate = 11000;
- else if (samplerate == 2) samplerate = 22050;
- else if (samplerate == 3) samplerate = 44100;
-
- int samplesize = (tag[11] & 0x02) >> 1;
- if (samplesize == 0) samplesize = 1;
- else samplesize = 2;
-
- _audioInfo.reset( new AudioInfo(codec, samplerate,
samplesize, (tag[11] & 0x01) >> 0, 0, FLASH) );
- if (header) {
- boost::uint8_t* newbuf = new
boost::uint8_t[frame->dataSize];
- memcpy(newbuf, frame->data.get(),
frame->dataSize);
-
- _audioInfo->extra.reset(
- new ExtraAudioInfoFlv(newbuf,
frame->dataSize)
- );
-
- // The FAAD decoder will reject us if we pass
the header buffer.
- // It will receive the header via the extra
audio info anyway.
- return true;
- }
- }
-
+ std::auto_ptr<EncodedAudioFrame> frame =
parseAudioTag(bodyLength, timestamp, thisTagPos, tag);
+ if (!frame.get()) {
+ return false;
+ }
// Release the stream lock
// *before* pushing the frame as that
// might block us waiting for buffers flush
@@ -383,71 +398,9 @@
}
else if (tag[0] == FLV_VIDEO_TAG)
{
- if ( ! _video ) {
- log_error(_("Unexpected video tag found at offset %d of
FLV stream advertising no video in header. We'll warn only once per FLV,
expecting any further video tag."), thisTagPos);
- _video = true; // TOCHECK: is this safe ?
- }
- // 1:keyframe, 2:interlacedFrame, 3:disposableInterlacedFrame
- int frameType = (tag[11] & 0xf0) >> 4;
-
- boost::uint16_t codec = (tag[11] & 0x0f) >> 0;
-
- if (codec == VIDEO_CODEC_VP6 || codec == VIDEO_CODEC_VP6A)
- {
- _stream->read_byte();
- --bodyLength;
- }
-
- bool header = false;
-
- if (codec == VIDEO_CODEC_H264) {
- boost::uint8_t packettype = _stream->read_byte();
- IF_VERBOSE_PARSE( log_debug(_("AVC packet type: %d"),
(unsigned)packettype) );
-
- header = (packettype == 0);
-
- // 24-bits value for composition time offset ignored
for now.
- boost::uint8_t tmp[3];
- _stream->read(tmp, 3);
-
- bodyLength -= 4;
- }
-
- if ( doIndex )
- {
- bool isKeyFrame = (frameType == 1);
- if ( isKeyFrame )
- {
- log_debug("Added cue point at timestamp %d and
position %d (key video frame)", timestamp, thisTagPos);
- _cuePoints[timestamp] = thisTagPos;
- }
- }
-
- size_t dataPosition = _stream->tell();
-
- std::auto_ptr<EncodedVideoFrame> frame =
readVideoFrame(bodyLength-1, timestamp);
- if ( ! frame.get() )
- {
- log_error("could not read video frame?");
- return true;
- }
-
- // If this is the first videoframe no info about the
- // video format has been noted, so we do that now
- if ( ! _videoInfo.get() )
- {
- _videoInfo.reset( new VideoInfo(codec, 0 /* width */, 0
/* height */, 0 /*frameRate*/, 0 /*duration*/, FLASH /*codec type*/) );
-
- if (header) {
- boost::uint8_t* newbuf = new
boost::uint8_t[frame->dataSize()];
- memcpy(newbuf, frame->data(),
frame->dataSize());
-
- _videoInfo->extra.reset(
- new ExtraVideoInfoFlv(newbuf,
frame->dataSize())
- );
- // Don't bother emitting the header buffer.
- return true;
- }
+ std::auto_ptr<EncodedVideoFrame> frame =
parseVideoTag(bodyLength, timestamp, thisTagPos, tag);
+ if (!frame.get()) {
+ return false;
}
// Release the stream lock
@@ -525,7 +478,7 @@
const size_t probeBytes = PROBE_BYTES;
while ( !_parsingComplete && _lastParsedPosition < probeBytes )
{
- parseNextTag();
+ parseNextTag(false);
// Early-out if we found both video and audio tags
if ( _videoInfo.get() && _audioInfo.get() ) break;
=== modified file 'libmedia/FLVParser.h'
--- a/libmedia/FLVParser.h 2008-10-19 23:23:53 +0000
+++ b/libmedia/FLVParser.h 2008-10-21 15:15:10 +0000
@@ -121,14 +121,21 @@
/// Returns true if something was parsed, false otherwise.
/// Sets _parsingComplete=true on end of file.
///
- bool parseNextTag();
-
- bool indexNextTag();
+ bool parseNextTag(bool index_only);
+
+ std::auto_ptr<EncodedAudioFrame> parseAudioTag(boost::uint32_t
bodyLength, boost::uint32_t timestamp, boost::uint32_t thisTagPos,
+ const boost::uint8_t* tag);
+ std::auto_ptr<EncodedVideoFrame> parseVideoTag(boost::uint32_t
bodyLength, boost::uint32_t timestamp, boost::uint32_t thisTagPos,
+ const boost::uint8_t* tag);
+
+ bool indexTag(const boost::uint8_t* tag, boost::uint32_t timestamp,
boost::uint32_t thisTagPos);
/// Parses the header of the file
bool parseHeader();
- // Functions used to extract numbers from the file
+ /// Reads three bytes in FLV (big endian) byte order.
+ /// @param in Pointer to read 3 bytes from.
+ /// @return 24-bit integer.
inline boost::uint32_t getUInt24(boost::uint8_t* in);
/// The position where the parsing should continue from.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10033: Some more refactoring of large blobs of code.,
Bastiaan Jacques <=