Show
Ignore:
Timestamp:
02/01/07 15:02:24 (17 years ago)
Author:
pieterpalmers
Message:

- fixed issues with SYT timestamp processing
- SYT based sync works if syncing to the received stream

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/streaming-rework/src/libstreaming/IsoHandlerManager.cpp

    r384 r385  
    3131#include "IsoStream.h" 
    3232#include <assert.h> 
     33 
     34#define MINIMUM_INTERRUPTS_PER_PERIOD  4U 
     35#define PACKETS_PER_INTERRUPT          4U 
    3336 
    3437namespace FreebobStreaming 
     
    285288                unsigned int packets_per_period=stream->getPacketsPerPeriod(); 
    286289                 
     290#if 0 
    287291                // hardware interrupts occur when one DMA block is full, and the size of one DMA 
    288292                // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq is  
    289293                // occurs at a period boundary (optimal CPU use) 
    290294                 
    291                 // NOTE: try and use 4 hardware interrupts per period for better latency. 
    292                 unsigned int max_packet_size=4 * getpagesize() / packets_per_period; 
     295                // NOTE: try and use MINIMUM_INTERRUPTS_PER_PERIOD hardware interrupts 
     296                //       per period for better latency. 
     297                unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period; 
    293298                if (max_packet_size < stream->getMaxPacketSize()) { 
    294299                        max_packet_size=stream->getMaxPacketSize(); 
     
    300305                        max_packet_size = getpagesize(); 
    301306 
    302                 int irq_interval=packets_per_period / 4; 
    303         if(irq_interval <= 0) irq_interval=1; 
    304  
    305                 /* the receive buffer size doesn't matter for the latency, 
    306                    but it has a minimal value in order for libraw to operate correctly (300) */ 
    307                 int buffers=400; 
    308                  
    309                 // create the actual handler 
    310                 IsoRecvHandler *h = new IsoRecvHandler(stream->getPort(), buffers, 
    311                                                        max_packet_size, irq_interval); 
    312  
    313                 debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n"); 
    314  
    315                 if(!h) { 
    316                         debugFatal("Could not create IsoRecvHandler\n"); 
    317                         return false; 
    318                 } 
    319  
    320                 h->setVerboseLevel(getDebugLevel()); 
    321  
    322                 // init the handler 
    323                 if(!h->init()) { 
    324                         debugFatal("Could not initialize receive handler\n"); 
    325                         return false; 
    326                 } 
    327  
    328                 // register the stream with the handler 
    329                 if(!h->registerStream(stream)) { 
    330                         debugFatal("Could not register receive stream with handler\n"); 
    331                         return false; 
    332                 } 
    333  
    334                 // register the handler with the manager 
    335                 if(!registerHandler(h)) { 
    336                         debugFatal("Could not register receive handler with manager\n"); 
    337                         return false; 
    338                 } 
    339                 debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h); 
    340         } 
    341          
    342         if (stream->getType()==IsoStream::EST_Transmit) { 
    343          
    344                 // setup the optimal parameters for the raw1394 ISO buffering 
    345                 unsigned int packets_per_period=stream->getPacketsPerPeriod(); 
     307                unsigned int irq_interval=packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 
     308                if(irq_interval <= 0) irq_interval=1; 
     309#else 
    346310                // hardware interrupts occur when one DMA block is full, and the size of one DMA 
    347                 // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq   
    348                 // occurs at a period boundary (optimal CPU use) 
    349                 // NOTE: try and use 4 interrupts per period for better latency. 
    350                 unsigned int max_packet_size=4 * getpagesize() / packets_per_period; 
     311                // block = PAGE_SIZE. Setting the max_packet_size enables control over the IRQ 
     312                // frequency, as the controller uses max_packet_size, and not the effective size 
     313                // when writing to the DMA buffer. 
     314                 
     315                // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets 
     316                unsigned int irq_interval=PACKETS_PER_INTERRUPT; 
     317                 
     318                // unless the period size doesn't allow this 
     319                if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) { 
     320                        irq_interval=1; 
     321                } 
     322                 
     323                // FIXME: test 
     324                irq_interval=1; 
     325                 
     326                unsigned int max_packet_size=getpagesize() / irq_interval; 
     327 
    351328                if (max_packet_size < stream->getMaxPacketSize()) { 
    352329                        max_packet_size=stream->getMaxPacketSize(); 
     
    358335                        max_packet_size = getpagesize(); 
    359336 
    360                 int irq_interval=packets_per_period / 4; 
     337#endif 
     338                /* the receive buffer size doesn't matter for the latency, 
     339                   but it has a minimal value in order for libraw to operate correctly (300) */ 
     340                int buffers=400; 
     341                 
     342                // create the actual handler 
     343                IsoRecvHandler *h = new IsoRecvHandler(stream->getPort(), buffers, 
     344                                                       max_packet_size, irq_interval); 
     345 
     346                debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n"); 
     347 
     348                if(!h) { 
     349                        debugFatal("Could not create IsoRecvHandler\n"); 
     350                        return false; 
     351                } 
     352 
     353                h->setVerboseLevel(getDebugLevel()); 
     354 
     355                // init the handler 
     356                if(!h->init()) { 
     357                        debugFatal("Could not initialize receive handler\n"); 
     358                        return false; 
     359                } 
     360 
     361                // register the stream with the handler 
     362                if(!h->registerStream(stream)) { 
     363                        debugFatal("Could not register receive stream with handler\n"); 
     364                        return false; 
     365                } 
     366 
     367                // register the handler with the manager 
     368                if(!registerHandler(h)) { 
     369                        debugFatal("Could not register receive handler with manager\n"); 
     370                        return false; 
     371                } 
     372                debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h); 
     373        } 
     374         
     375        if (stream->getType()==IsoStream::EST_Transmit) { 
     376                // setup the optimal parameters for the raw1394 ISO buffering 
     377                unsigned int packets_per_period=stream->getPacketsPerPeriod(); 
     378 
     379#if 0 
     380                // hardware interrupts occur when one DMA block is full, and the size of one DMA 
     381                // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq   
     382                // occurs at a period boundary (optimal CPU use) 
     383                // NOTE: try and use MINIMUM_INTERRUPTS_PER_PERIOD interrupts per period 
     384                //       for better latency. 
     385                unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period; 
     386                if (max_packet_size < stream->getMaxPacketSize()) { 
     387                        max_packet_size=stream->getMaxPacketSize(); 
     388                } 
     389 
     390                // Ensure we don't request a packet size bigger than the 
     391                // kernel-enforced maximum which is currently 1 page. 
     392                if (max_packet_size > (unsigned int)getpagesize()) 
     393                        max_packet_size = getpagesize(); 
     394 
     395                unsigned int irq_interval=packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 
    361396                if(irq_interval <= 0) irq_interval=1; 
    362          
     397#else 
     398                // hardware interrupts occur when one DMA block is full, and the size of one DMA 
     399                // block = PAGE_SIZE. Setting the max_packet_size enables control over the IRQ 
     400                // frequency, as the controller uses max_packet_size, and not the effective size 
     401                // when writing to the DMA buffer. 
     402                 
     403                // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets 
     404                unsigned int irq_interval=PACKETS_PER_INTERRUPT; 
     405                 
     406                // unless the period size doesn't allow this 
     407                if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) { 
     408                        irq_interval=1; 
     409                } 
     410                 
     411                // FIXME: test 
     412                irq_interval=1; 
     413 
     414                unsigned int max_packet_size=getpagesize() / irq_interval; 
     415 
     416                if (max_packet_size < stream->getMaxPacketSize()) { 
     417                        max_packet_size=stream->getMaxPacketSize(); 
     418                } 
     419 
     420                // Ensure we don't request a packet size bigger than the 
     421                // kernel-enforced maximum which is currently 1 page. 
     422                if (max_packet_size > (unsigned int)getpagesize()) 
     423                        max_packet_size = getpagesize(); 
     424#endif 
    363425                // the transmit buffer size should be as low as possible for latency.  
    364426                // note however that the raw1394 subsystem tries to keep this buffer 
    365427                // full, so we have to make sure that we have enough events in our 
    366428                // event buffers 
    367                 int buffers=packets_per_period; 
     429                 
     430                // every irq_interval packets an interrupt will occur. that is when 
     431                // buffers get transfered, meaning that we should have at least some 
     432                // margin here 
     433//              int buffers=irq_interval * 2; 
     434 
     435                // half a period. the xmit handler will take care of this 
     436                int buffers=packets_per_period/2; 
    368437                 
    369438                // NOTE: this is dangerous: what if there is not enough prefill?