Commit ba3c22cf authored by Laurent Aimar's avatar Laurent Aimar

Cleaned up the way BDA store data from the sample grabber.

parent 9861cd7b
...@@ -565,25 +565,5 @@ static int Control( access_t *p_access, int i_query, va_list args ) ...@@ -565,25 +565,5 @@ static int Control( access_t *p_access, int i_query, va_list args )
*****************************************************************************/ *****************************************************************************/
static block_t *Block( access_t *p_access ) static block_t *Block( access_t *p_access )
{ {
block_t *p_block; return dvb_Pop( p_access );
long l_buffer_len;
if( !vlc_object_alive (p_access) )
return NULL;
l_buffer_len = dvb_GetBufferSize( p_access );
if( l_buffer_len < 0 )
{
p_access->info.b_eof = true;
return NULL;
}
p_block = block_New( p_access, l_buffer_len );
if( dvb_ReadBuffer( p_access, &l_buffer_len, p_block->p_buffer ) < 0 )
{
p_access->info.b_eof = true;
return NULL;
}
return p_block;
} }
...@@ -67,8 +67,7 @@ int dvb_SubmitATSCTuneRequest( access_t* p_access ); ...@@ -67,8 +67,7 @@ int dvb_SubmitATSCTuneRequest( access_t* p_access );
int dvb_SubmitDVBTTuneRequest( access_t* p_access ); int dvb_SubmitDVBTTuneRequest( access_t* p_access );
int dvb_SubmitDVBCTuneRequest( access_t* p_access ); int dvb_SubmitDVBCTuneRequest( access_t* p_access );
int dvb_SubmitDVBSTuneRequest( access_t* p_access ); int dvb_SubmitDVBSTuneRequest( access_t* p_access );
long dvb_GetBufferSize( access_t* p_access ); block_t *dvb_Pop( access_t* p_access );
long dvb_ReadBuffer( access_t* p_access, long* l_buffer_len, BYTE* p_buff );
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -69,22 +69,60 @@ extern "C" { ...@@ -69,22 +69,60 @@ extern "C" {
return VLC_EGENERIC; return VLC_EGENERIC;
}; };
long dvb_GetBufferSize( access_t* p_access ) block_t *dvb_Pop( access_t* p_access )
{ {
if( p_access->p_sys->p_bda_module ) if( p_access->p_sys->p_bda_module )
return p_access->p_sys->p_bda_module->GetBufferSize(); return p_access->p_sys->p_bda_module->Pop();
return -1; return NULL;
};
long dvb_ReadBuffer( access_t* p_access, long* l_buffer_len, BYTE* p_buff )
{
if( p_access->p_sys->p_bda_module )
return p_access->p_sys->p_bda_module->ReadBuffer( l_buffer_len,
p_buff );
return -1;
}; };
}; };
/*****************************************************************************
* BDAOutput
*****************************************************************************/
BDAOutput::BDAOutput( access_t *p_access ) :
p_access(p_access), p_first(NULL), pp_next(&p_first)
{
vlc_mutex_init( &lock );
vlc_cond_init( &wait );
}
BDAOutput::~BDAOutput()
{
Empty();
vlc_mutex_destroy( &lock );
vlc_cond_destroy( &wait );
}
void BDAOutput::Push( block_t *p_block )
{
vlc_mutex_locker l( &lock );
block_ChainLastAppend( &pp_next, p_block );
vlc_cond_signal( &wait );
}
block_t *BDAOutput::Pop()
{
vlc_mutex_locker l( &lock );
if( !p_first )
vlc_cond_timedwait( &wait, &lock, mdate() + 250*1000 );
block_t *p_ret = p_first;
p_first = NULL;
pp_next = &p_first;
return p_ret;
}
void BDAOutput::Empty()
{
vlc_mutex_locker l( &lock );
if( p_first )
block_ChainRelease( p_first );
p_first = NULL;
pp_next = &p_first;
}
/***************************************************************************** /*****************************************************************************
* Constructor * Constructor
*****************************************************************************/ *****************************************************************************/
...@@ -92,9 +130,9 @@ BDAGraph::BDAGraph( access_t* p_this ): ...@@ -92,9 +130,9 @@ BDAGraph::BDAGraph( access_t* p_this ):
p_access( p_this ), p_access( p_this ),
guid_network_type(GUID_NULL), guid_network_type(GUID_NULL),
l_tuner_used(-1), l_tuner_used(-1),
d_graph_register( 0 ) d_graph_register( 0 ),
output( p_this )
{ {
b_ready = false;
p_tuning_space = NULL; p_tuning_space = NULL;
p_tune_request = NULL; p_tune_request = NULL;
p_media_control = NULL; p_media_control = NULL;
...@@ -1746,76 +1784,34 @@ HRESULT BDAGraph::Start() ...@@ -1746,76 +1784,34 @@ HRESULT BDAGraph::Start()
} }
/***************************************************************************** /*****************************************************************************
* Read the stream of data - query the buffer size required * Pop the stream of data
*****************************************************************************/ *****************************************************************************/
long BDAGraph::GetBufferSize() block_t *BDAGraph::Pop()
{ {
long l_buffer_size = 0; return output.Pop();
long l_queue_size;
b_ready = true;
for( int i_timer = 0; queue_sample.empty() && i_timer < 200; i_timer++ )
Sleep( 10 );
l_queue_size = queue_sample.size();
if( l_queue_size <= 0 )
{
msg_Warn( p_access, "BDA GetBufferSize: Timed Out waiting for sample" );
return -1;
}
/* Establish the length of the queue as it grows quickly. If the queue
* size is checked dynamically there is a risk of not exiting the loop */
for( long l_queue_count=0; l_queue_count < l_queue_size; l_queue_count++ )
{
l_buffer_size += queue_sample.front()->GetActualDataLength();
queue_buffer.push( queue_sample.front() );
queue_sample.pop();
}
return l_buffer_size;
} }
/***************************************************************************** /******************************************************************************
* Read the stream of data - Retrieve from the buffer queue * SampleCB - Callback when the Sample Grabber has a sample
******************************************************************************/ ******************************************************************************/
long BDAGraph::ReadBuffer( long* pl_buffer_len, BYTE* p_buffer ) STDMETHODIMP BDAGraph::SampleCB( double d_time, IMediaSample *p_sample )
{ {
HRESULT hr = S_OK; if( p_sample->IsDiscontinuity() == S_OK )
msg_Warn( p_access, "BDA SampleCB: Sample Discontinuity.");
*pl_buffer_len = 0; const size_t i_sample_size = p_sample->GetActualDataLength();
BYTE *p_buff_temp; BYTE *p_sample_data;
p_sample->GetPointer( &p_sample_data );
while( !queue_buffer.empty() ) if( i_sample_size > 0 && p_sample_data )
{ {
queue_buffer.front()->GetPointer( &p_buff_temp ); block_t *p_block = block_New( p_access, i_sample_size );
hr = queue_buffer.front()->IsDiscontinuity();
if( hr == S_OK )
msg_Warn( p_access,
"BDA ReadBuffer: Sample Discontinuity. 0x%8lx", hr );
memcpy( p_buffer + *pl_buffer_len, p_buff_temp,
queue_buffer.front()->GetActualDataLength() );
*pl_buffer_len += queue_buffer.front()->GetActualDataLength();
queue_buffer.front()->Release();
queue_buffer.pop();
}
return *pl_buffer_len;
}
/****************************************************************************** if( p_block )
* SampleCB - Callback when the Sample Grabber has a sample
******************************************************************************/
STDMETHODIMP BDAGraph::SampleCB( double d_time, IMediaSample *p_sample )
{
if( b_ready )
{ {
p_sample->AddRef(); memcpy( p_block->p_buffer, p_sample_data, i_sample_size );
queue_sample.push( p_sample ); output.Push( p_block );
} }
else
{
msg_Warn( p_access, "BDA SampleCB: Not ready - dropped sample" );
} }
return S_OK; return S_OK;
} }
...@@ -1842,23 +1838,8 @@ HRESULT BDAGraph::Destroy() ...@@ -1842,23 +1838,8 @@ HRESULT BDAGraph::Destroy()
Deregister(); Deregister();
} }
/* We need to empty the buffers of any unprocessed data */ output.Empty();
msg_Dbg( p_access, "Queue sample size = %d", queue_sample.size() );
while( !queue_sample.empty() )
{
ul_refcount = queue_sample.front()->Release();
queue_sample.pop();
if( ul_refcount )
msg_Warn( p_access, "BDAGraph: Non-zero Ref: %d", ul_refcount );
}
msg_Dbg( p_access, "Queue buffer size = %d", queue_buffer.size() );
while( !queue_buffer.empty() )
{
ul_refcount = queue_buffer.front()->Release();
queue_buffer.pop();
if( ul_refcount )
msg_Warn( p_access, "BDAGraph: Non-zero Ref: %d", ul_refcount );
}
if( p_grabber ) if( p_grabber )
{ {
p_grabber->Release(); p_grabber->Release();
......
...@@ -52,6 +52,24 @@ using namespace std; ...@@ -52,6 +52,24 @@ using namespace std;
#include "bdadefs.h" #include "bdadefs.h"
#include "bda.h" #include "bda.h"
class BDAOutput
{
public:
BDAOutput( access_t * );
~BDAOutput();
void Push( block_t * );
block_t *Pop();
void Empty();
private:
access_t *p_access;
vlc_mutex_t lock;
vlc_cond_t wait;
block_t *p_first;
block_t **pp_next;
};
/* The main class for building the filter graph */ /* The main class for building the filter graph */
class BDAGraph : public ISampleGrabberCB class BDAGraph : public ISampleGrabberCB
{ {
...@@ -59,12 +77,14 @@ public: ...@@ -59,12 +77,14 @@ public:
BDAGraph( access_t* p_access ); BDAGraph( access_t* p_access );
virtual ~BDAGraph(); virtual ~BDAGraph();
/* */
int SubmitATSCTuneRequest(); int SubmitATSCTuneRequest();
int SubmitDVBTTuneRequest(); int SubmitDVBTTuneRequest();
int SubmitDVBCTuneRequest(); int SubmitDVBCTuneRequest();
int SubmitDVBSTuneRequest(); int SubmitDVBSTuneRequest();
long GetBufferSize();
long ReadBuffer( long* l_buffer_len, BYTE* p_buff ); /* */
block_t *Pop();
private: private:
/* ISampleGrabberCB methods */ /* ISampleGrabberCB methods */
...@@ -82,9 +102,7 @@ private: ...@@ -82,9 +102,7 @@ private:
/* registration number for the RunningObjectTable */ /* registration number for the RunningObjectTable */
DWORD d_graph_register; DWORD d_graph_register;
queue<IMediaSample*> queue_sample; BDAOutput output;
queue<IMediaSample*> queue_buffer;
BOOL b_ready;
IMediaControl* p_media_control; IMediaControl* p_media_control;
IGraphBuilder* p_filter_graph; IGraphBuilder* p_filter_graph;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment