Changeset 226

Show
Ignore:
Timestamp:
05/27/06 08:30:20 (16 years ago)
Author:
pieterpalmers
Message:

- ported the more efficient buffer handling from libfreebob1.0

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/libfreebob-2.0/src/libstreaming/AmdtpStreamProcessor.cpp

    r225 r226  
    247247        debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 
    248248        // TODO: improve 
     249/* a naive implementation would look like this: 
    249250 
    250251        unsigned int write_size=m_period*sizeof(quadlet_t)*m_dimension; 
     
    258259 
    259260        free(dummybuffer); 
     261*/ 
     262/* but we're not that naive anymore... */ 
     263        int i; 
     264        int xrun; 
     265        unsigned int offset=0; 
     266         
     267        freebob_ringbuffer_data_t vec[2]; 
     268        // we received one period of frames 
     269        // this is period_size*dimension of events 
     270        int events2write=m_period*m_dimension; 
     271        int bytes2write=events2write*sizeof(quadlet_t); 
     272 
     273        /* write events2write bytes to the ringbuffer  
     274        *  first see if it can be done in one read. 
     275        *  if so, ok.  
     276        *  otherwise write up to a multiple of clusters directly to the buffer 
     277        *  then do the buffer wrap around using ringbuffer_write 
     278        *  then write the remaining data directly to the buffer in a third pass  
     279        *  Make sure that we cannot end up on a non-cluster aligned position! 
     280        */ 
     281        int cluster_size=m_dimension*sizeof(quadlet_t); 
     282 
     283        while(bytes2write>0) { 
     284                int byteswritten=0; 
     285                 
     286                unsigned int frameswritten=(m_period*cluster_size-bytes2write)/cluster_size; 
     287                offset=frameswritten; 
     288                 
     289                freebob_ringbuffer_get_write_vector(m_event_buffer, vec); 
     290                         
     291                if(vec[0].len==0) { // this indicates a full event buffer 
     292                        debugError("Event buffer overrun in processor %d\n",this); 
     293                        break; 
     294                } 
     295                         
     296                /* if we don't take care we will get stuck in an infinite loop 
     297                * because we align to a cluster boundary later 
     298                * the remaining nb of bytes in one write operation can be  
     299                * smaller than one cluster 
     300                * this can happen because the ringbuffer size is always a power of 2 
     301                */ 
     302                if(vec[0].len<cluster_size) { 
     303                         
     304                        // encode to the temporary buffer 
     305                        xrun = transmitBlock(m_cluster_buffer, 1, offset); 
     306                         
     307                        if(xrun<0) { 
     308                                // xrun detected 
     309                                debugError("Frame buffer underrun in processor %d\n",this); 
     310                                break; 
     311                        } 
     312                                 
     313                        // use the ringbuffer function to write one cluster  
     314                        // the write function handles the wrap around. 
     315                        freebob_ringbuffer_write(m_event_buffer, 
     316                                                 m_cluster_buffer, 
     317                                                 cluster_size); 
     318                                 
     319                        // we advanced one cluster_size 
     320                        bytes2write-=cluster_size; 
     321                                 
     322                } else { //  
     323                         
     324                        if(bytes2write>vec[0].len) { 
     325                                // align to a cluster boundary 
     326                                byteswritten=vec[0].len-(vec[0].len%cluster_size); 
     327                        } else { 
     328                                byteswritten=bytes2write; 
     329                        } 
     330                                 
     331                        xrun = transmitBlock(vec[0].buf, 
     332                                             byteswritten/cluster_size, 
     333                                             offset); 
     334                         
     335                        if(xrun<0) { 
     336                                        // xrun detected 
     337                                debugError("Frame buffer underrun in processor %d\n",this); 
     338                                break; 
     339                        } 
     340 
     341                        freebob_ringbuffer_write_advance(m_event_buffer, byteswritten); 
     342                        bytes2write -= byteswritten; 
     343                } 
     344                         
     345                // the bytes2write should always be cluster aligned 
     346                assert(bytes2write%cluster_size==0); 
     347                         
     348        } 
    260349 
    261350        return true; 
     
    266355 
    267356int AmdtpTransmitStreamProcessor::transmitBlock(char *data,  
    268                                            unsigned int nevents, unsigned int offset, unsigned int dbc
     357                                           unsigned int nevents, unsigned int offset
    269358{ 
    270359        int problem=0; 
     
    282371                switch(pinfo->getFormat()) { 
    283372                case AmdtpPortInfo::E_MBLA: 
    284                         if(encodePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents, dbc)) { 
     373                        if(encodePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
    285374                                debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str()); 
    286375                                problem=1; 
     
    301390 
    302391int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,  
    303                                            unsigned int offset, unsigned int nevents, unsigned int dbc
     392                                           unsigned int offset, unsigned int nevents
    304393{ 
    305394        unsigned int j=0; 
     
    523612 
    524613        debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 
    525 // TODO: implement 
    526        
     614         
     615/* another naive section:      
    527616        unsigned int read_size=m_period*sizeof(quadlet_t)*m_dimension; 
    528617        char *dummybuffer=(char *)calloc(sizeof(quadlet_t),m_period*m_dimension); 
     
    531620        } 
    532621 
    533         receiveBlock(dummybuffer, m_period, 0, 0); 
     622        receiveBlock(dummybuffer, m_period, 0); 
    534623 
    535624        free(dummybuffer); 
     625*/ 
     626        int i; 
     627        int xrun; 
     628        unsigned int offset=0; 
     629         
     630        freebob_ringbuffer_data_t vec[2]; 
     631        // we received one period of frames on each connection 
     632        // this is period_size*dimension of events 
     633 
     634        int events2read=m_period*m_dimension; 
     635        int bytes2read=events2read*sizeof(quadlet_t); 
     636        /* read events2read bytes from the ringbuffer  
     637        *  first see if it can be done in one read.  
     638        *  if so, ok.  
     639        *  otherwise read up to a multiple of clusters directly from the buffer 
     640        *  then do the buffer wrap around using ringbuffer_read 
     641        *  then read the remaining data directly from the buffer in a third pass  
     642        *  Make sure that we cannot end up on a non-cluster aligned position! 
     643        */ 
     644        int cluster_size=m_dimension*sizeof(quadlet_t); 
     645         
     646        while(bytes2read>0) { 
     647                unsigned int framesread=(m_period*cluster_size-bytes2read)/cluster_size; 
     648                offset=framesread; 
     649                 
     650                int bytesread=0; 
     651 
     652                freebob_ringbuffer_get_read_vector(m_event_buffer, vec); 
     653                         
     654                if(vec[0].len==0) { // this indicates an empty event buffer 
     655                        debugError("Frame buffer underrun in processor %d\n",this); 
     656                        break; 
     657                } 
     658                         
     659                /* if we don't take care we will get stuck in an infinite loop 
     660                * because we align to a cluster boundary later 
     661                * the remaining nb of bytes in one read operation can be smaller than one cluster 
     662                * this can happen because the ringbuffer size is always a power of 2 
     663                        */ 
     664                if(vec[0].len<cluster_size) { 
     665                        // use the ringbuffer function to read one cluster  
     666                        // the read function handles wrap around 
     667                        freebob_ringbuffer_read(m_event_buffer,m_cluster_buffer,cluster_size); 
     668 
     669                        xrun = receiveBlock(m_cluster_buffer, 1, offset); 
     670                                 
     671                        if(xrun<0) { 
     672                                // xrun detected 
     673                                debugError("Frame buffer underrun in processor %d\n",this); 
     674                                break; 
     675                        } 
     676                                 
     677                                // we advanced one cluster_size 
     678                        bytes2read-=cluster_size; 
     679                                 
     680                } else { //  
     681                         
     682                        if(bytes2read>vec[0].len) { 
     683                                        // align to a cluster boundary 
     684                                bytesread=vec[0].len-(vec[0].len%cluster_size); 
     685                        } else { 
     686                                bytesread=bytes2read; 
     687                        } 
     688                                 
     689                        xrun = receiveBlock(vec[0].buf, bytesread/cluster_size, offset); 
     690                                 
     691                        if(xrun<0) { 
     692                                        // xrun detected 
     693                                debugError("Frame buffer underrun in processor %d\n",this); 
     694                                break; 
     695                        } 
     696 
     697                        freebob_ringbuffer_read_advance(m_event_buffer, bytesread); 
     698                        bytes2read -= bytesread; 
     699                } 
     700                         
     701                        // the bytes2read should always be cluster aligned 
     702                assert(bytes2read%cluster_size==0); 
     703        } 
    536704 
    537705        return true; 
     
    543711 
    544712int AmdtpReceiveStreamProcessor::receiveBlock(char *data,  
    545                                            unsigned int nevents, unsigned int offset, unsigned int dbc
     713                                           unsigned int nevents, unsigned int offset
    546714{ 
    547715        int problem=0; 
     
    559727                switch(pinfo->getFormat()) { 
    560728                case AmdtpPortInfo::E_MBLA: 
    561                         if(decodeMBLAEventsToPort(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents, dbc)) { 
     729                        if(decodeMBLAEventsToPort(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
    562730                                debugWarning("Could not decode packet MBLA to port %s",(*it)->getName().c_str()); 
    563731                                problem=1; 
     
    578746 
    579747int AmdtpReceiveStreamProcessor::decodeMBLAEventsToPort(AmdtpAudioPort *p, quadlet_t *data,  
    580                                            unsigned int offset, unsigned int nevents, unsigned int dbc
     748                                           unsigned int offset, unsigned int nevents
    581749{ 
    582750        unsigned int j=0; 
  • branches/libfreebob-2.0/src/libstreaming/AmdtpStreamProcessor.h

    r225 r226  
    8989 
    9090        int transmitBlock(char *data, unsigned int nevents,  
    91                           unsigned int offset, unsigned int dbc); 
     91                          unsigned int offset); 
    9292        int encodePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 
    93                                    unsigned int offset, unsigned int nevents, 
    94                                    unsigned int dbc); 
     93                                   unsigned int offset, unsigned int nevents); 
    9594 
    9695    DECLARE_DEBUG_MODULE; 
     
    132131protected: 
    133132 
    134         int receiveBlock(char *data, unsigned int nevents, unsigned int offset, unsigned int dbc); 
    135         int decodeMBLAEventsToPort(AmdtpAudioPort *, quadlet_t *data, unsigned int offset, unsigned int nevents, unsigned int dbc); 
     133        int receiveBlock(char *data, unsigned int nevents, unsigned int offset); 
     134        int decodeMBLAEventsToPort(AmdtpAudioPort *, quadlet_t *data, unsigned int offset, unsigned int nevents); 
    136135 
    137136        freebob_ringbuffer_t * m_event_buffer;