Rationalised and renamed buffer class.
git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@2657 e3e1d417-86f3-4887-817a-d78f3d33393f
This commit is contained in:
parent
0afd77907e
commit
a91d2a0697
|
@ -22,48 +22,48 @@
|
||||||
#include "zm.h"
|
#include "zm.h"
|
||||||
#include "zm_buffer.h"
|
#include "zm_buffer.h"
|
||||||
|
|
||||||
unsigned int Buffer::Assign( const unsigned char *p_storage, unsigned int p_size )
|
unsigned int Buffer::assign( const unsigned char *pStorage, unsigned int pSize )
|
||||||
{
|
{
|
||||||
if ( allocation < p_size )
|
if ( mAllocation < pSize )
|
||||||
{
|
{
|
||||||
delete[] storage;
|
delete[] mStorage;
|
||||||
allocation = p_size;
|
mAllocation = pSize;
|
||||||
head = storage = new unsigned char[p_size];
|
mHead = mStorage = new unsigned char[pSize];
|
||||||
}
|
}
|
||||||
size = p_size;
|
mSize = pSize;
|
||||||
memcpy( storage, p_storage, size );
|
memcpy( mStorage, pStorage, mSize );
|
||||||
head = storage;
|
mHead = mStorage;
|
||||||
tail = head + size;
|
mTail = mHead + mSize;
|
||||||
return( size );
|
return( mSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Buffer::Expand( unsigned int count )
|
unsigned int Buffer::expand( unsigned int count )
|
||||||
{
|
{
|
||||||
int spare = allocation - size;
|
int spare = mAllocation - mSize;
|
||||||
int head_space = head - storage;
|
int headSpace = mHead - mStorage;
|
||||||
int tail_space = spare - head_space;
|
int tailSpace = spare - headSpace;
|
||||||
int width = tail - head;
|
int width = mTail - mHead;
|
||||||
if ( spare > count )
|
if ( spare > count )
|
||||||
{
|
{
|
||||||
if ( tail_space < count )
|
if ( tailSpace < count )
|
||||||
{
|
{
|
||||||
memmove( storage, head, size );
|
memmove( mStorage, mHead, mSize );
|
||||||
head = storage;
|
mHead = mStorage;
|
||||||
tail = head + width;
|
mTail = mHead + width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
allocation += count;
|
mAllocation += count;
|
||||||
unsigned char *new_storage = new unsigned char[allocation];
|
unsigned char *newStorage = new unsigned char[mAllocation];
|
||||||
if ( storage )
|
if ( mStorage )
|
||||||
{
|
{
|
||||||
memcpy( new_storage, head, size );
|
memcpy( newStorage, mHead, mSize );
|
||||||
delete[] storage;
|
delete[] mStorage;
|
||||||
}
|
}
|
||||||
storage = new_storage;
|
mStorage = newStorage;
|
||||||
head = storage;
|
mHead = mStorage;
|
||||||
tail = head + width;
|
mTail = mHead + width;
|
||||||
}
|
}
|
||||||
return( size );
|
return( mSize );
|
||||||
}
|
}
|
||||||
|
|
177
src/zm_buffer.h
177
src/zm_buffer.h
|
@ -10,7 +10,7 @@
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more demTails.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -27,138 +27,143 @@
|
||||||
class Buffer
|
class Buffer
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
unsigned char *storage;
|
unsigned char *mStorage;
|
||||||
unsigned int allocation;
|
unsigned int mAllocation;
|
||||||
unsigned int size;
|
unsigned int mSize;
|
||||||
unsigned char *head;
|
unsigned char *mHead;
|
||||||
unsigned char *tail;
|
unsigned char *mTail;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Buffer() : storage( 0 ), allocation( 0 ), size( 0 ), head( 0 ), tail( 0 )
|
Buffer() : mStorage( 0 ), mAllocation( 0 ), mSize( 0 ), mHead( 0 ), mTail( 0 )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Buffer( unsigned int p_size ) : allocation( p_size ), size( 0 )
|
Buffer( unsigned int pSize ) : mAllocation( pSize ), mSize( 0 )
|
||||||
{
|
{
|
||||||
head = storage = new unsigned char[allocation];
|
mHead = mStorage = new unsigned char[mAllocation];
|
||||||
tail = head;
|
mTail = mHead;
|
||||||
}
|
}
|
||||||
Buffer( const unsigned char *p_storage, unsigned int p_size ) : allocation( p_size ), size( p_size )
|
Buffer( const unsigned char *pStorage, unsigned int pSize ) : mAllocation( pSize ), mSize( pSize )
|
||||||
{
|
{
|
||||||
head = storage = new unsigned char[size];
|
mHead = mStorage = new unsigned char[mSize];
|
||||||
memcpy( storage, p_storage, size );
|
memcpy( mStorage, pStorage, mSize );
|
||||||
tail = head + size;
|
mTail = mHead + mSize;
|
||||||
}
|
}
|
||||||
Buffer( const Buffer &buffer ) : allocation( buffer.size ), size( buffer.size )
|
Buffer( const Buffer &buffer ) : mAllocation( buffer.mSize ), mSize( buffer.mSize )
|
||||||
{
|
{
|
||||||
head = storage = new unsigned char[size];
|
mHead = mStorage = new unsigned char[mSize];
|
||||||
memcpy( storage, buffer.head, size );
|
memcpy( mStorage, buffer.mHead, mSize );
|
||||||
tail = head + size;
|
mTail = mHead + mSize;
|
||||||
}
|
}
|
||||||
~Buffer()
|
~Buffer()
|
||||||
{
|
{
|
||||||
delete[] storage;
|
delete[] mStorage;
|
||||||
}
|
}
|
||||||
unsigned char *Head() const { return( head ); }
|
unsigned char *head() const { return( mHead ); }
|
||||||
unsigned char *Tail() const { return( tail ); }
|
unsigned char *tail() const { return( mTail ); }
|
||||||
unsigned int Size() const { return( size ); }
|
unsigned int size() const { return( mSize ); }
|
||||||
unsigned int Size( unsigned int p_size )
|
bool empty() const { return( mSize == 0 ); }
|
||||||
|
unsigned int size( unsigned int pSize )
|
||||||
{
|
{
|
||||||
if ( size < p_size )
|
if ( mSize < pSize )
|
||||||
{
|
{
|
||||||
Expand( p_size-size );
|
expand( pSize-mSize );
|
||||||
}
|
}
|
||||||
return( size );
|
return( mSize );
|
||||||
}
|
}
|
||||||
//unsigned int Allocation() const { return( allocation ); }
|
//unsigned int Allocation() const { return( mAllocation ); }
|
||||||
|
|
||||||
void Empty()
|
void clear()
|
||||||
{
|
{
|
||||||
size = 0;
|
mSize = 0;
|
||||||
head = tail = storage;
|
mHead = mTail = mStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Assign( const unsigned char *p_storage, unsigned int p_size );
|
unsigned int assign( const unsigned char *pStorage, unsigned int pSize );
|
||||||
unsigned int Assign( const Buffer &buffer )
|
unsigned int assign( const Buffer &buffer )
|
||||||
{
|
{
|
||||||
return( Assign( buffer.head, buffer.size ) );
|
return( assign( buffer.mHead, buffer.mSize ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim from the front of the buffer
|
// Trim from the front of the buffer
|
||||||
unsigned int Consume( unsigned int count )
|
unsigned int consume( unsigned int count )
|
||||||
{
|
{
|
||||||
if ( count > size )
|
if ( count > mSize )
|
||||||
{
|
{
|
||||||
Warning( "Attempt to consume %d bytes of buffer, size is only %d bytes", count, size );
|
Warning( "Attempt to consume %d bytes of buffer, size is only %d bytes", count, mSize );
|
||||||
count = size;
|
count = mSize;
|
||||||
}
|
}
|
||||||
head += count;
|
mHead += count;
|
||||||
size -= count;
|
mSize -= count;
|
||||||
|
tidy( 0 );
|
||||||
return( count );
|
return( count );
|
||||||
}
|
}
|
||||||
// Trim from the end of the buffer
|
// Trim from the end of the buffer
|
||||||
unsigned int Shrink( unsigned int count )
|
unsigned int shrink( unsigned int count )
|
||||||
{
|
{
|
||||||
if ( count > size )
|
if ( count > mSize )
|
||||||
{
|
{
|
||||||
Warning( "Attempt to shrink buffer by %d bytes, size is only %d bytes", count, size );
|
Warning( "Attempt to shrink buffer by %d bytes, size is only %d bytes", count, mSize );
|
||||||
count = size;
|
count = mSize;
|
||||||
}
|
}
|
||||||
size -= count;
|
mSize -= count;
|
||||||
if ( tail > (head + size) )
|
if ( mTail > (mHead + mSize) )
|
||||||
tail = head + size;
|
mTail = mHead + mSize;
|
||||||
|
tidy( 0 );
|
||||||
return( count );
|
return( count );
|
||||||
}
|
}
|
||||||
// Add to the end of the buffer
|
// Add to the end of the buffer
|
||||||
unsigned int Expand( unsigned int count );
|
unsigned int expand( unsigned int count );
|
||||||
// Return pointer to the first p_size bytes and advance the head
|
|
||||||
unsigned char *Extract( unsigned int p_size )
|
// Return pointer to the first pSize bytes and advance the head
|
||||||
|
unsigned char *extract( unsigned int pSize )
|
||||||
{
|
{
|
||||||
if ( p_size > size )
|
if ( pSize > mSize )
|
||||||
{
|
{
|
||||||
Warning( "Attempt to extract %d bytes of buffer, size is only %d bytes", p_size, size );
|
Warning( "Attempt to extract %d bytes of buffer, size is only %d bytes", pSize, mSize );
|
||||||
p_size = size;
|
pSize = mSize;
|
||||||
}
|
}
|
||||||
unsigned char *old_head = head;
|
unsigned char *oldHead = mHead;
|
||||||
head += p_size;
|
mHead += pSize;
|
||||||
size -= p_size;
|
mSize -= pSize;
|
||||||
return( old_head );
|
tidy( 0 );
|
||||||
|
return( oldHead );
|
||||||
}
|
}
|
||||||
// Add bytes to the end of the buffer
|
// Add bytes to the end of the buffer
|
||||||
unsigned int Append( const unsigned char *p_storage, unsigned int p_size )
|
unsigned int append( const unsigned char *pStorage, unsigned int pSize )
|
||||||
{
|
{
|
||||||
Expand( p_size );
|
expand( pSize );
|
||||||
memcpy( tail, p_storage, p_size );
|
memcpy( mTail, pStorage, pSize );
|
||||||
tail += p_size;
|
mTail += pSize;
|
||||||
size += p_size;
|
mSize += pSize;
|
||||||
return( size );
|
return( mSize );
|
||||||
}
|
}
|
||||||
unsigned int Append( const char *p_storage, unsigned int p_size )
|
unsigned int append( const char *pStorage, unsigned int pSize )
|
||||||
{
|
{
|
||||||
return( Append( (const unsigned char *)p_storage, p_size ) );
|
return( append( (const unsigned char *)pStorage, pSize ) );
|
||||||
}
|
}
|
||||||
unsigned int Append( const Buffer &buffer )
|
unsigned int append( const Buffer &buffer )
|
||||||
{
|
{
|
||||||
return( Append( buffer.head, buffer.size ) );
|
return( append( buffer.mHead, buffer.mSize ) );
|
||||||
}
|
}
|
||||||
void Tidy( bool level=0 )
|
void tidy( bool level=0 )
|
||||||
{
|
{
|
||||||
if ( head != storage )
|
if ( mHead != mStorage )
|
||||||
{
|
{
|
||||||
if ( size == 0 )
|
if ( mSize == 0 )
|
||||||
head = tail = storage;
|
mHead = mTail = mStorage;
|
||||||
else if ( level >= 1 )
|
else if ( level >= 1 )
|
||||||
{
|
{
|
||||||
if ( (head-storage) > size )
|
if ( (mHead-mStorage) > mSize )
|
||||||
{
|
{
|
||||||
memcpy( storage, head, size );
|
memcpy( mStorage, mHead, mSize );
|
||||||
head = storage;
|
mHead = mStorage;
|
||||||
tail = head + size;
|
mTail = mHead + mSize;
|
||||||
}
|
}
|
||||||
else if ( level >= 2 )
|
else if ( level >= 2 )
|
||||||
{
|
{
|
||||||
memmove( storage, head, size );
|
memmove( mStorage, mHead, mSize );
|
||||||
head = storage;
|
mHead = mStorage;
|
||||||
tail = head + size;
|
mTail = mHead + mSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,43 +171,43 @@ public:
|
||||||
|
|
||||||
Buffer &operator=( const Buffer &buffer )
|
Buffer &operator=( const Buffer &buffer )
|
||||||
{
|
{
|
||||||
Assign( buffer );
|
assign( buffer );
|
||||||
return( *this );
|
return( *this );
|
||||||
}
|
}
|
||||||
Buffer &operator+=( const Buffer &buffer )
|
Buffer &operator+=( const Buffer &buffer )
|
||||||
{
|
{
|
||||||
Append( buffer );
|
append( buffer );
|
||||||
return( *this );
|
return( *this );
|
||||||
}
|
}
|
||||||
Buffer &operator+=( unsigned int count )
|
Buffer &operator+=( unsigned int count )
|
||||||
{
|
{
|
||||||
Expand( count );
|
expand( count );
|
||||||
return( *this );
|
return( *this );
|
||||||
}
|
}
|
||||||
Buffer &operator-=( unsigned int count )
|
Buffer &operator-=( unsigned int count )
|
||||||
{
|
{
|
||||||
Consume( count );
|
consume( count );
|
||||||
return( *this );
|
return( *this );
|
||||||
}
|
}
|
||||||
operator unsigned char *() const
|
operator unsigned char *() const
|
||||||
{
|
{
|
||||||
return( head );
|
return( mHead );
|
||||||
}
|
}
|
||||||
operator char *() const
|
operator char *() const
|
||||||
{
|
{
|
||||||
return( (char *)head );
|
return( (char *)mHead );
|
||||||
}
|
}
|
||||||
unsigned char *operator+(int offset) const
|
unsigned char *operator+(int offset) const
|
||||||
{
|
{
|
||||||
return( (unsigned char *)(head+offset) );
|
return( (unsigned char *)(mHead+offset) );
|
||||||
}
|
}
|
||||||
unsigned char operator[](int index) const
|
unsigned char operator[](int index) const
|
||||||
{
|
{
|
||||||
return( *(head+index) );
|
return( *(mHead+index) );
|
||||||
}
|
}
|
||||||
operator int () const
|
operator int () const
|
||||||
{
|
{
|
||||||
return( (int)size );
|
return( (int)mSize );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ void RemoteCameraHttp::Initialise()
|
||||||
|
|
||||||
int max_size = width*height*colours;
|
int max_size = width*height*colours;
|
||||||
|
|
||||||
buffer.Size( max_size );
|
buffer.size( max_size );
|
||||||
|
|
||||||
mode = SINGLE_IMAGE;
|
mode = SINGLE_IMAGE;
|
||||||
format = UNDEF;
|
format = UNDEF;
|
||||||
|
@ -193,7 +193,7 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
Debug( 3, "Read %d bytes", bytes_read );
|
Debug( 3, "Read %d bytes", bytes_read );
|
||||||
buffer.Append( temp_buffer, bytes_read );
|
buffer.append( temp_buffer, bytes_read );
|
||||||
total_bytes_read += bytes_read;
|
total_bytes_read += bytes_read;
|
||||||
total_bytes_to_read -= bytes_read;
|
total_bytes_to_read -= bytes_read;
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
}
|
}
|
||||||
if ( !header_expr )
|
if ( !header_expr )
|
||||||
header_expr = new RegExpr( "^(.+?\r?\n\r?\n)", PCRE_DOTALL );
|
header_expr = new RegExpr( "^(.+?\r?\n\r?\n)", PCRE_DOTALL );
|
||||||
if ( header_expr->Match( (char*)buffer, buffer.Size() ) == 2 )
|
if ( header_expr->Match( (char*)buffer, buffer.size() ) == 2 )
|
||||||
{
|
{
|
||||||
header = header_expr->MatchString( 1 );
|
header = header_expr->MatchString( 1 );
|
||||||
header_len = header_expr->MatchLength( 1 );
|
header_len = header_expr->MatchLength( 1 );
|
||||||
|
@ -335,7 +335,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
Error( "Unrecognised content type '%s'", content_type );
|
Error( "Unrecognised content type '%s'", content_type );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
buffer.Consume( header_len );
|
buffer.consume( header_len );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -378,7 +378,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
Debug( 3, "Got subcontent type '%s'", content_type );
|
Debug( 3, "Got subcontent type '%s'", content_type );
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.Consume( subheader_len );
|
buffer.consume( subheader_len );
|
||||||
state = CONTENT;
|
state = CONTENT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -414,7 +414,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
|
|
||||||
if ( content_length )
|
if ( content_length )
|
||||||
{
|
{
|
||||||
while ( buffer.Size() < content_length )
|
while ( buffer.size() < content_length )
|
||||||
{
|
{
|
||||||
int buffer_len = ReadData( buffer );
|
int buffer_len = ReadData( buffer );
|
||||||
if ( buffer_len < 0 )
|
if ( buffer_len < 0 )
|
||||||
|
@ -446,7 +446,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
snprintf( content_pattern, sizeof(content_pattern), "^(.+?)(?:\r?\n)*(?:--)?%s\r?\n", content_boundary );
|
snprintf( content_pattern, sizeof(content_pattern), "^(.+?)(?:\r?\n)*(?:--)?%s\r?\n", content_boundary );
|
||||||
content_expr = new RegExpr( content_pattern, PCRE_DOTALL );
|
content_expr = new RegExpr( content_pattern, PCRE_DOTALL );
|
||||||
}
|
}
|
||||||
if ( content_expr->Match( buffer, buffer.Size() ) == 2 )
|
if ( content_expr->Match( buffer, buffer.size() ) == 2 )
|
||||||
{
|
{
|
||||||
content_length = content_expr->MatchLength( 1 );
|
content_length = content_expr->MatchLength( 1 );
|
||||||
Debug( 3, "Got end of image by pattern, content-length = %d", content_length );
|
Debug( 3, "Got end of image by pattern, content-length = %d", content_length );
|
||||||
|
@ -455,7 +455,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
content_length = buffer.Size();
|
content_length = buffer.size();
|
||||||
Debug( 3, "Got end of image by closure, content-length = %d", content_length );
|
Debug( 3, "Got end of image by closure, content-length = %d", content_length );
|
||||||
if ( mode == SINGLE_IMAGE )
|
if ( mode == SINGLE_IMAGE )
|
||||||
{
|
{
|
||||||
|
@ -463,7 +463,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
{
|
{
|
||||||
content_expr = new RegExpr( "^(.+?)(?:\r?\n){1,2}?$", PCRE_DOTALL );
|
content_expr = new RegExpr( "^(.+?)(?:\r?\n){1,2}?$", PCRE_DOTALL );
|
||||||
}
|
}
|
||||||
if ( content_expr->Match( buffer, buffer.Size() ) == 2 )
|
if ( content_expr->Match( buffer, buffer.size() ) == 2 )
|
||||||
{
|
{
|
||||||
content_length = content_expr->MatchLength( 1 );
|
content_length = content_expr->MatchLength( 1 );
|
||||||
Debug( 3, "Trimmed end of image, new content-length = %d", content_length );
|
Debug( 3, "Trimmed end of image, new content-length = %d", content_length );
|
||||||
|
@ -481,7 +481,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
{
|
{
|
||||||
state = SUBHEADER;
|
state = SUBHEADER;
|
||||||
}
|
}
|
||||||
Debug( 3, "Returning %d (%d) bytes of captured content", content_length, buffer.Size() );
|
Debug( 3, "Returning %d (%d) bytes of captured content", content_length, buffer.size() );
|
||||||
return( content_length );
|
return( content_length );
|
||||||
}
|
}
|
||||||
case HEADERCONT :
|
case HEADERCONT :
|
||||||
|
@ -579,7 +579,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
|
|
||||||
char *crlf = 0;
|
char *crlf = 0;
|
||||||
char *header_ptr = (char *)buffer;
|
char *header_ptr = (char *)buffer;
|
||||||
int header_len = buffer.Size();
|
int header_len = buffer.size();
|
||||||
bool all_headers = false;
|
bool all_headers = false;
|
||||||
|
|
||||||
while( true )
|
while( true )
|
||||||
|
@ -591,7 +591,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
{
|
{
|
||||||
*header_ptr = '\0';
|
*header_ptr = '\0';
|
||||||
header_ptr += crlf_len;
|
header_ptr += crlf_len;
|
||||||
header_len -= buffer.Consume( header_ptr-(char *)buffer );
|
header_len -= buffer.consume( header_ptr-(char *)buffer );
|
||||||
all_headers = true;
|
all_headers = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -606,7 +606,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
{
|
{
|
||||||
*header_ptr = '\0';
|
*header_ptr = '\0';
|
||||||
header_ptr += crlf_len;
|
header_ptr += crlf_len;
|
||||||
header_len -= buffer.Consume( header_ptr-(char *)buffer );
|
header_len -= buffer.consume( header_ptr-(char *)buffer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,7 +640,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
Debug( 6, "Got ignored header '%s'", header_ptr );
|
Debug( 6, "Got ignored header '%s'", header_ptr );
|
||||||
}
|
}
|
||||||
header_ptr = crlf;
|
header_ptr = crlf;
|
||||||
header_len -= buffer.Consume( header_ptr-(char *)buffer );
|
header_len -= buffer.consume( header_ptr-(char *)buffer );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -790,7 +790,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
{
|
{
|
||||||
char *crlf = 0;
|
char *crlf = 0;
|
||||||
char *subheader_ptr = (char *)buffer;
|
char *subheader_ptr = (char *)buffer;
|
||||||
int subheader_len = buffer.Size();
|
int subheader_len = buffer.size();
|
||||||
bool all_headers = false;
|
bool all_headers = false;
|
||||||
|
|
||||||
while( true )
|
while( true )
|
||||||
|
@ -802,7 +802,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
{
|
{
|
||||||
*subheader_ptr = '\0';
|
*subheader_ptr = '\0';
|
||||||
subheader_ptr += crlf_len;
|
subheader_ptr += crlf_len;
|
||||||
subheader_len -= buffer.Consume( subheader_ptr-(char *)buffer );
|
subheader_len -= buffer.consume( subheader_ptr-(char *)buffer );
|
||||||
all_headers = true;
|
all_headers = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -817,7 +817,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
{
|
{
|
||||||
*subheader_ptr = '\0';
|
*subheader_ptr = '\0';
|
||||||
subheader_ptr += crlf_len;
|
subheader_ptr += crlf_len;
|
||||||
subheader_len -= buffer.Consume( subheader_ptr-(char *)buffer );
|
subheader_len -= buffer.consume( subheader_ptr-(char *)buffer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,7 +849,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
Debug( 6, "Got ignored subheader '%s' found", subheader_ptr );
|
Debug( 6, "Got ignored subheader '%s' found", subheader_ptr );
|
||||||
}
|
}
|
||||||
subheader_ptr = crlf;
|
subheader_ptr = crlf;
|
||||||
subheader_len -= buffer.Consume( subheader_ptr-(char *)buffer );
|
subheader_len -= buffer.consume( subheader_ptr-(char *)buffer );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -912,7 +912,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( format == JPEG && buffer.Size() >= 2 )
|
if ( format == JPEG && buffer.size() >= 2 )
|
||||||
{
|
{
|
||||||
if ( buffer[0] != 0xff || buffer[1] != 0xd8 )
|
if ( buffer[0] != 0xff || buffer[1] != 0xd8 )
|
||||||
{
|
{
|
||||||
|
@ -923,9 +923,9 @@ int RemoteCameraHttp::GetResponse()
|
||||||
|
|
||||||
if ( content_length )
|
if ( content_length )
|
||||||
{
|
{
|
||||||
while ( buffer.Size() < content_length )
|
while ( buffer.size() < content_length )
|
||||||
{
|
{
|
||||||
//int buffer_len = ReadData( buffer, content_length-buffer.Size() );
|
//int buffer_len = ReadData( buffer, content_length-buffer.size() );
|
||||||
int buffer_len = ReadData( buffer );
|
int buffer_len = ReadData( buffer );
|
||||||
if ( buffer_len < 0 )
|
if ( buffer_len < 0 )
|
||||||
{
|
{
|
||||||
|
@ -941,7 +941,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
while ( !content_length )
|
while ( !content_length )
|
||||||
{
|
{
|
||||||
int buffer_len = ReadData( buffer );
|
int buffer_len = ReadData( buffer );
|
||||||
int buffer_size = buffer.Size();
|
int buffer_size = buffer.size();
|
||||||
if ( buffer_len < 0 )
|
if ( buffer_len < 0 )
|
||||||
{
|
{
|
||||||
Error( "Unable to read content" );
|
Error( "Unable to read content" );
|
||||||
|
@ -991,7 +991,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
state = SUBHEADER;
|
state = SUBHEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( format == JPEG && buffer.Size() >= 2 )
|
if ( format == JPEG && buffer.size() >= 2 )
|
||||||
{
|
{
|
||||||
if ( buffer[0] != 0xff || buffer[1] != 0xd8 )
|
if ( buffer[0] != 0xff || buffer[1] != 0xd8 )
|
||||||
{
|
{
|
||||||
|
@ -1000,7 +1000,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug( 3, "Returning %d (%d) bytes of captured content", content_length, buffer.Size() );
|
Debug( 3, "Returning %d (%d) bytes of captured content", content_length, buffer.size() );
|
||||||
return( content_length );
|
return( content_length );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1020,7 +1020,7 @@ int RemoteCameraHttp::PreCapture()
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
mode = SINGLE_IMAGE;
|
mode = SINGLE_IMAGE;
|
||||||
buffer.Empty();
|
buffer.clear();
|
||||||
}
|
}
|
||||||
if ( mode == SINGLE_IMAGE )
|
if ( mode == SINGLE_IMAGE )
|
||||||
{
|
{
|
||||||
|
@ -1047,7 +1047,7 @@ int RemoteCameraHttp::PostCapture( Image &image )
|
||||||
{
|
{
|
||||||
case JPEG :
|
case JPEG :
|
||||||
{
|
{
|
||||||
if ( !image.DecodeJpeg( buffer.Extract( content_length ), content_length ) )
|
if ( !image.DecodeJpeg( buffer.extract( content_length ), content_length ) )
|
||||||
{
|
{
|
||||||
Error( "Unable to decode jpeg" );
|
Error( "Unable to decode jpeg" );
|
||||||
Disconnect();
|
Disconnect();
|
||||||
|
@ -1068,7 +1068,7 @@ int RemoteCameraHttp::PostCapture( Image &image )
|
||||||
}
|
}
|
||||||
case X_RGBZ :
|
case X_RGBZ :
|
||||||
{
|
{
|
||||||
if ( !image.Unzip( buffer.Extract( content_length ), content_length ) )
|
if ( !image.Unzip( buffer.extract( content_length ), content_length ) )
|
||||||
{
|
{
|
||||||
Error( "Unable to unzip RGB image" );
|
Error( "Unable to unzip RGB image" );
|
||||||
Disconnect();
|
Disconnect();
|
||||||
|
|
|
@ -63,7 +63,7 @@ void RemoteCameraRtsp::Initialise()
|
||||||
|
|
||||||
int max_size = width*height*colours;
|
int max_size = width*height*colours;
|
||||||
|
|
||||||
buffer.Size( max_size );
|
buffer.size( max_size );
|
||||||
|
|
||||||
if ( zm_dbg_level > ZM_DBG_INF )
|
if ( zm_dbg_level > ZM_DBG_INF )
|
||||||
av_log_set_level( AV_LOG_DEBUG );
|
av_log_set_level( AV_LOG_DEBUG );
|
||||||
|
@ -169,12 +169,12 @@ int RemoteCameraRtsp::PostCapture( Image &image )
|
||||||
{
|
{
|
||||||
while ( true )
|
while ( true )
|
||||||
{
|
{
|
||||||
buffer.Empty();
|
buffer.clear();
|
||||||
if ( rtspThread->getFrame( buffer ) )
|
if ( rtspThread->getFrame( buffer ) )
|
||||||
{
|
{
|
||||||
Debug( 3, "Read frame %d bytes", buffer.Size() );
|
Debug( 3, "Read frame %d bytes", buffer.size() );
|
||||||
Debug( 4, "Address %p", buffer.Head() );
|
Debug( 4, "Address %p", buffer.head() );
|
||||||
Hexdump( 4, buffer.Head(), 16 );
|
Hexdump( 4, buffer.head(), 16 );
|
||||||
|
|
||||||
static AVFrame *tmp_picture = NULL;
|
static AVFrame *tmp_picture = NULL;
|
||||||
|
|
||||||
|
@ -198,14 +198,14 @@ int RemoteCameraRtsp::PostCapture( Image &image )
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !buffer.Size() )
|
if ( !buffer.size() )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
int initialFrameCount = frameCount;
|
int initialFrameCount = frameCount;
|
||||||
while ( buffer.Size() > 0 )
|
while ( buffer.size() > 0 )
|
||||||
{
|
{
|
||||||
int got_picture = false;
|
int got_picture = false;
|
||||||
int len = avcodec_decode_video( codecContext, picture, &got_picture, buffer.Head(), buffer.Size() );
|
int len = avcodec_decode_video( codecContext, picture, &got_picture, buffer.head(), buffer.size() );
|
||||||
if ( len < 0 )
|
if ( len < 0 )
|
||||||
{
|
{
|
||||||
if ( frameCount > initialFrameCount )
|
if ( frameCount > initialFrameCount )
|
||||||
|
@ -214,12 +214,12 @@ int RemoteCameraRtsp::PostCapture( Image &image )
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
Error( "Error while decoding frame %d", frameCount );
|
Error( "Error while decoding frame %d", frameCount );
|
||||||
Hexdump( 0, buffer.Head(), buffer.Size() );
|
Hexdump( 0, buffer.head(), buffer.size() );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
Debug( 2, "Frame: %d: %d/%d", frameCount, len, buffer.Size() );
|
Debug( 2, "Frame: %d: %d/%d", frameCount, len, buffer.size() );
|
||||||
//if ( buffer.Size() < 400 )
|
//if ( buffer.size() < 400 )
|
||||||
//Hexdump( 0, buffer.Head(), buffer.Size() );
|
//Hexdump( 0, buffer.head(), buffer.size() );
|
||||||
|
|
||||||
if ( got_picture )
|
if ( got_picture )
|
||||||
{
|
{
|
||||||
|
|
|
@ -258,14 +258,14 @@ bool RtpSource::handlePacket( const unsigned char *packet, size_t packetLen )
|
||||||
{
|
{
|
||||||
Hexdump( 4, packet+sizeof(RtpDataHeader), 16 );
|
Hexdump( 4, packet+sizeof(RtpDataHeader), 16 );
|
||||||
if ( mFrameGood )
|
if ( mFrameGood )
|
||||||
mFrame.Append( packet+sizeof(RtpDataHeader), packetLen-sizeof(RtpDataHeader) );
|
mFrame.append( packet+sizeof(RtpDataHeader), packetLen-sizeof(RtpDataHeader) );
|
||||||
Hexdump( 4, mFrame.Head(), 16 );
|
Hexdump( 4, mFrame.head(), 16 );
|
||||||
|
|
||||||
if ( rtpHeader->m )
|
if ( rtpHeader->m )
|
||||||
{
|
{
|
||||||
if ( mFrameGood )
|
if ( mFrameGood )
|
||||||
{
|
{
|
||||||
Debug( 2, "Got new frame %d, %d bytes", mFrameCount, mFrame.Size() );
|
Debug( 2, "Got new frame %d, %d bytes", mFrameCount, mFrame.size() );
|
||||||
|
|
||||||
mFrameProcessed.setValueImmediate( false );
|
mFrameProcessed.setValueImmediate( false );
|
||||||
mFrameReady.updateValueSignal( true );
|
mFrameReady.updateValueSignal( true );
|
||||||
|
@ -279,23 +279,23 @@ bool RtpSource::handlePacket( const unsigned char *packet, size_t packetLen )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Warning( "Discarding incomplete frame %d, %d bytes", mFrameCount, mFrame.Size() );
|
Warning( "Discarding incomplete frame %d, %d bytes", mFrameCount, mFrame.size() );
|
||||||
}
|
}
|
||||||
mFrame.Empty();
|
mFrame.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( mFrame.Size() )
|
if ( mFrame.size() )
|
||||||
{
|
{
|
||||||
Warning( "Discarding partial frame %d, %d bytes", mFrameCount, mFrame.Size() );
|
Warning( "Discarding partial frame %d, %d bytes", mFrameCount, mFrame.size() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Warning( "Discarding frame %d", mFrameCount );
|
Warning( "Discarding frame %d", mFrameCount );
|
||||||
}
|
}
|
||||||
mFrameGood = false;
|
mFrameGood = false;
|
||||||
mFrame.Empty();
|
mFrame.clear();
|
||||||
}
|
}
|
||||||
if ( rtpHeader->m )
|
if ( rtpHeader->m )
|
||||||
{
|
{
|
||||||
|
@ -320,6 +320,6 @@ bool RtpSource::getFrame( Buffer &buffer )
|
||||||
buffer = mFrame;
|
buffer = mFrame;
|
||||||
mFrameReady.setValueImmediate( false );
|
mFrameReady.setValueImmediate( false );
|
||||||
mFrameProcessed.updateValueSignal( true );
|
mFrameProcessed.updateValueSignal( true );
|
||||||
Debug( 3, "Copied %d bytes", buffer.Size() );
|
Debug( 3, "Copied %d bytes", buffer.size() );
|
||||||
return( true );
|
return( true );
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,25 +500,25 @@ int RtspThread::run()
|
||||||
|
|
||||||
static char tempBuffer[10*BUFSIZ];
|
static char tempBuffer[10*BUFSIZ];
|
||||||
ssize_t nBytes = mRtspSocket.recv( tempBuffer, sizeof(tempBuffer) );
|
ssize_t nBytes = mRtspSocket.recv( tempBuffer, sizeof(tempBuffer) );
|
||||||
buffer.Append( tempBuffer, nBytes );
|
buffer.append( tempBuffer, nBytes );
|
||||||
Debug( 4, "Read %d bytes on sd %d, %d total", nBytes, mRtspSocket.getReadDesc(), buffer.Size() );
|
Debug( 4, "Read %d bytes on sd %d, %d total", nBytes, mRtspSocket.getReadDesc(), buffer.size() );
|
||||||
|
|
||||||
while( buffer.Size() > 0 )
|
while( buffer.size() > 0 )
|
||||||
{
|
{
|
||||||
if ( buffer[0] == '$' )
|
if ( buffer[0] == '$' )
|
||||||
{
|
{
|
||||||
unsigned char channel = buffer[1];
|
unsigned char channel = buffer[1];
|
||||||
unsigned short len = ntohs( *((unsigned short *)(buffer+2)) );
|
unsigned short len = ntohs( *((unsigned short *)(buffer+2)) );
|
||||||
|
|
||||||
Debug( 4, "Got %d bytes left, expecting %d byte packet on channel %d", buffer.Size(), len, channel );
|
Debug( 4, "Got %d bytes left, expecting %d byte packet on channel %d", buffer.size(), len, channel );
|
||||||
if ( buffer.Size() < (len+4) )
|
if ( buffer.size() < (len+4) )
|
||||||
{
|
{
|
||||||
Debug( 4, "Missing %d bytes, rereading", (len+4)-nBytes );
|
Debug( 4, "Missing %d bytes, rereading", (len+4)-nBytes );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( channel == remoteChannels[0] )
|
if ( channel == remoteChannels[0] )
|
||||||
{
|
{
|
||||||
Debug( 4, "Got %d bytes on data channel %d, packet length is %d", buffer.Size(), channel, len );
|
Debug( 4, "Got %d bytes on data channel %d, packet length is %d", buffer.size(), channel, len );
|
||||||
Hexdump( 4, (char *)buffer, 16 );
|
Hexdump( 4, (char *)buffer, 16 );
|
||||||
rtpDataThread.recvPacket( buffer+4, len );
|
rtpDataThread.recvPacket( buffer+4, len );
|
||||||
Debug( 4, "Received" );
|
Debug( 4, "Received" );
|
||||||
|
@ -532,10 +532,10 @@ int RtspThread::run()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Error( "Unexpected channel selector %d in RTSP interleaved data", buffer[1] );
|
Error( "Unexpected channel selector %d in RTSP interleaved data", buffer[1] );
|
||||||
buffer.Empty();
|
buffer.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buffer.Consume( len+4 );
|
buffer.consume( len+4 );
|
||||||
nBytes -= len+4;
|
nBytes -= len+4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -543,20 +543,20 @@ int RtspThread::run()
|
||||||
if ( keepaliveResponse.compare( 0, keepaliveResponse.size(), (char *)buffer, keepaliveResponse.size() ) == 0 )
|
if ( keepaliveResponse.compare( 0, keepaliveResponse.size(), (char *)buffer, keepaliveResponse.size() ) == 0 )
|
||||||
{
|
{
|
||||||
Debug( 4, "Got keepalive response '%s'", (char *)buffer );
|
Debug( 4, "Got keepalive response '%s'", (char *)buffer );
|
||||||
//buffer.Consume( keepaliveResponse.size() );
|
//buffer.consume( keepaliveResponse.size() );
|
||||||
if ( char *charPtr = (char *)memchr( (char *)buffer, '$', buffer.Size() ) )
|
if ( char *charPtr = (char *)memchr( (char *)buffer, '$', buffer.size() ) )
|
||||||
{
|
{
|
||||||
int discardBytes = charPtr-(char *)buffer;
|
int discardBytes = charPtr-(char *)buffer;
|
||||||
buffer -= discardBytes;
|
buffer -= discardBytes;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffer.Empty();
|
buffer.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( char *charPtr = (char *)memchr( (char *)buffer, '$', buffer.Size() ) )
|
if ( char *charPtr = (char *)memchr( (char *)buffer, '$', buffer.size() ) )
|
||||||
{
|
{
|
||||||
int discardBytes = charPtr-(char *)buffer;
|
int discardBytes = charPtr-(char *)buffer;
|
||||||
Warning( "Unexpected format RTSP interleaved data, resyncing by %d bytes", discardBytes );
|
Warning( "Unexpected format RTSP interleaved data, resyncing by %d bytes", discardBytes );
|
||||||
|
@ -565,9 +565,9 @@ int RtspThread::run()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Warning( "Unexpected format RTSP interleaved data, dumping %d bytes", buffer.Size() );
|
Warning( "Unexpected format RTSP interleaved data, dumping %d bytes", buffer.size() );
|
||||||
Hexdump( -1, (char *)buffer, 32 );
|
Hexdump( -1, (char *)buffer, 32 );
|
||||||
buffer.Empty();
|
buffer.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -578,7 +578,7 @@ int RtspThread::run()
|
||||||
return( -1 );
|
return( -1 );
|
||||||
lastKeepalive = time(NULL);
|
lastKeepalive = time(NULL);
|
||||||
}
|
}
|
||||||
buffer.Tidy( 1 );
|
buffer.tidy( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
message = "PAUSE "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n";
|
message = "PAUSE "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n";
|
||||||
|
|
Loading…
Reference in New Issue