Configuration parameter added "-merger-distance"
[u/mrichter/AliRoot.git] / HLT / TPCLib / HWCFemulator / AliHLTTPCHWCFEmulatorComponent.cxx
CommitLineData
33861fe0 1// $Id$
c012881c 2//****************************************************************************
3//* This file is property of and copyright by the ALICE HLT Project *
4//* ALICE Experiment at CERN, All rights reserved. *
5//* *
6//* Primary Authors: Sergey Gorbunov, Torsten Alt *
7//* Developers: Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de> *
8//* Torsten Alt <talt@cern.ch> *
9//* for The ALICE HLT Project. *
10//* *
11//* Permission to use, copy, modify and distribute this software and its *
12//* documentation strictly for non-commercial purposes is hereby granted *
13//* without fee, provided that the above copyright notice appears in all *
14//* copies and that both the copyright notice and this permission notice *
15//* appear in the supporting documentation. The authors make no claims *
16//* about the suitability of this software for any purpose. It is *
17//* provided "as is" without express or implied warranty. *
18//****************************************************************************
19
20// @file AliHLTTPCHWCFEmulatorComponent.cxx
21// @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de>
22// @author Torsten Alt <talt@cern.ch>
23// @brief HLT Component interface for for FPGA ClusterFinder Emulator for TPC
24// @brief ( see AliHLTTPCHWCFEmulator class )
25// @note
26
27
28#if __GNUC__>= 3
29using namespace std;
30#endif
31#include "AliHLTTPCHWCFEmulatorComponent.h"
32
33#include "AliHLTTPCDefinitions.h"
34#include "AliHLTTPCHWCFDataTypes.h"
35#include "AliHLTTPCClusterMCData.h"
33861fe0 36#include "AliHLTTPCHWCFData.h"
c012881c 37
38#include "AliGRPObject.h"
39#include "AliCDBEntry.h"
40#include "AliCDBManager.h"
41#include "AliRawDataHeader.h"
42#include <cstdlib>
43#include <cerrno>
44#include "TString.h"
45#include "TObjString.h"
46#include "TObjArray.h"
47
48
49#include <sys/time.h>
50#include "TFile.h"
51
52AliHLTTPCHWCFEmulatorComponent::AliHLTTPCHWCFEmulatorComponent()
53 :
54 AliHLTProcessor(),
55 fDoDeconvTime(1),
56 fDoDeconvPad(1),
57 fDoMC(1),
58 fDoFlowControl(0),
59 fDoSinglePadSuppression(1),
60 fBypassMerger(0),
61 fClusterLowerLimit(0),
62 fSingleSeqLimit(0),
eb62889b 63 fMergerDistance(3),
c012881c 64 fDebug(0),
65 fCFSupport(),
66 fCFEmulator(),
67 fBenchmark("TPCHWClusterFinderEmulator")
68{
69 // see header file for class documentation
70 // or
71 // refer to README to build package
72 // or
73 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
74}
75
76
77AliHLTTPCHWCFEmulatorComponent::AliHLTTPCHWCFEmulatorComponent(const AliHLTTPCHWCFEmulatorComponent&)
78 :
79 AliHLTProcessor(),
80 fDoDeconvTime(1),
81 fDoDeconvPad(1),
82 fDoMC(1),
83 fDoFlowControl(0),
84 fDoSinglePadSuppression(1),
85 fBypassMerger(0),
86 fClusterLowerLimit(0),
87 fSingleSeqLimit(0),
eb62889b 88 fMergerDistance(3),
c012881c 89 fDebug(0),
90 fCFSupport(),
91 fCFEmulator(),
92 fBenchmark("TPCHWClusterFinderEmulator")
93{
94 // dummy
95}
96
97AliHLTTPCHWCFEmulatorComponent& AliHLTTPCHWCFEmulatorComponent::operator=(const AliHLTTPCHWCFEmulatorComponent&)
98{
99 // dummy
100 return *this;
101}
102
103AliHLTTPCHWCFEmulatorComponent::~AliHLTTPCHWCFEmulatorComponent()
104{
105 // see header file for class documentation
106}
107
108// Public functions to implement AliHLTComponent's interface.
109// These functions are required for the registration process
110
111const char* AliHLTTPCHWCFEmulatorComponent::GetComponentID()
112{
113 // see header file for class documentation
114 return "TPCHWClusterFinderEmulator";
115}
116
117void AliHLTTPCHWCFEmulatorComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
118{
119 // see header file for class documentation
120 list.clear();
121 list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );
122 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
123}
124
125AliHLTComponentDataType AliHLTTPCHWCFEmulatorComponent::GetOutputDataType()
126{
127 // see header file for class documentation
128 return kAliHLTMultipleDataType;
129}
130
131int AliHLTTPCHWCFEmulatorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
132{
133 // see header file for class documentation
134 tgtList.clear();
135 tgtList.push_back(AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC );
136 tgtList.push_back(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC );
137 return tgtList.size();
138}
139
140
141void AliHLTTPCHWCFEmulatorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
142{
143 // see header file for class documentation
144 // XXX TODO: Find more realistic values.
145 constBase = 0;
146 inputMultiplier = (6 * 0.4);
147}
148
149
150AliHLTComponent* AliHLTTPCHWCFEmulatorComponent::Spawn()
151{
152 // see header file for class documentation
153 return new AliHLTTPCHWCFEmulatorComponent();
154}
155
156void AliHLTTPCHWCFEmulatorComponent::GetOCDBObjectDescription( TMap* const targetMap){
157// Get a list of OCDB object description needed for the particular component
158
159 if (!targetMap) return;
160
161 // OCDB entries for component arguments
162 targetMap->Add(new TObjString("HLT/ConfigTPC/TPCHWClusterFinder"), new TObjString("component arguments, empty at the moment"));
163}
164
165
166int AliHLTTPCHWCFEmulatorComponent::DoInit( int argc, const char** argv )
167{
168 // see header file for class documentation
169
170 TString arguments = "";
171 for ( int i = 0; i < argc; i++ ) {
172 if ( !arguments.IsNull() ) arguments += " ";
173 arguments += argv[i];
174 }
175
176 return Configure( NULL, NULL, arguments.Data() );
177}
178
179int AliHLTTPCHWCFEmulatorComponent::Reconfigure( const char* cdbEntry, const char* chainId )
180{
181 // Reconfigure the component from OCDB
182
183 return Configure( cdbEntry, chainId, NULL );
184}
185
186int AliHLTTPCHWCFEmulatorComponent::ScanConfigurationArgument(int argc, const char** argv)
187{
188 // see header file for class documentation
189 TString arguments = "";
190 for ( int i = 0; i < argc; i++ ) {
191 if ( !arguments.IsNull() ) arguments += " ";
192 arguments += argv[i];
193 }
194 return ReadConfigurationString(arguments);
195}
196
197
198
199void AliHLTTPCHWCFEmulatorComponent::SetDefaultConfiguration()
200{
201 // Set default configuration for the FPGA ClusterFinder Emulator component
202 // Some parameters can be later overwritten from the OCDB
203
204 fDoDeconvTime = 0;
205 fDoDeconvPad = 0;
206 fDoMC = 1;
207 fDoFlowControl = 0;
208 fDoSinglePadSuppression = 1;
209 fBypassMerger = 0;
210 fClusterLowerLimit = 0;
211 fSingleSeqLimit = 0;
eb62889b 212 fMergerDistance = 3;
b7ea7fe9 213 fDebug = 0;
c012881c 214 fBenchmark.Reset();
215 fBenchmark.SetTimer(0,"total");
216 fBenchmark.SetTimer(1,"reco");
217}
218
219int AliHLTTPCHWCFEmulatorComponent::ReadConfigurationString( const char* arguments )
220{
221 // Set configuration parameters for the FPGA ClusterFinder Emulator component
222 // from the string
223
224 int iResult = 0;
225 if ( !arguments ) return iResult;
226
227 TString allArgs = arguments;
228 TString argument;
229 int bMissingParam = 0;
230
231 TObjArray* pTokens = allArgs.Tokenize( " " );
232
233 int nArgs = pTokens ? pTokens->GetEntries() : 0;
234
235 for ( int i = 0; i < nArgs; i++ ) {
236 argument = ( ( TObjString* )pTokens->At( i ) )->GetString();
237 if ( argument.IsNull() ) continue;
238
239 if ( argument.CompareTo( "-deconvolute-time" ) == 0 ) {
240 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
241 fDoDeconvTime = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
242 HLTInfo( "Time deconvolution is set to: %d", fDoDeconvTime );
243 continue;
244 }
245
246 if ( argument.CompareTo( "-deconvolute-pad" ) == 0 ) {
247 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
248 fDoDeconvPad = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
249 HLTInfo( "Pad deconvolution is set to: %d", fDoDeconvPad );
250 continue;
251 }
252
253 if ( argument.CompareTo( "-deconvolute" ) == 0 ) {
254 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
255 fDoDeconvTime = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
256 fDoDeconvPad = fDoDeconvTime;
257 HLTInfo( "Time and pad deconvolution is set to: %d", fDoDeconvPad );
258 continue;
259 }
260
261 if ( argument.CompareTo( "-do-mc" ) == 0 ) {
262 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
263 fDoMC = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
264 HLTInfo( "MC processing is set to: %d", fDoMC );
265 continue;
266 }
267
268 if ( argument.CompareTo( "-flow-control" ) == 0 ) {
269 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
270 fDoFlowControl = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
271 HLTInfo( "Flow control is set to: %d", fDoFlowControl );
272 continue;
273 }
274
275 if ( argument.CompareTo( "-single-pad-suppression" ) == 0 ) {
276 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
277 fDoSinglePadSuppression = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
278 HLTInfo( "Single pad suppression is set to: %d", fDoSinglePadSuppression );
279 continue;
280 }
281
282 if ( argument.CompareTo( "-bypass-merger" ) == 0 ) {
283 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
284 fBypassMerger = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
285 HLTInfo( "Bypassing merger is set to: %d", fBypassMerger );
286 continue;
287 }
288
289 if ( argument.CompareTo( "-cluster-lower-limit" ) == 0 ) {
290 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
291 fClusterLowerLimit = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
292 HLTInfo( "Cluster lower limit is set to: %d", fClusterLowerLimit );
293 continue;
294 }
295
296 if ( argument.CompareTo( "-single-sequence-limit" ) == 0 ) {
297 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
298 fSingleSeqLimit = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
299 HLTInfo( "Single sequence limit is set to: %d", fSingleSeqLimit );
300 continue;
301 }
302
eb62889b 303 if ( argument.CompareTo( "-merger-distance" ) == 0 ) {
304 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
305 fMergerDistance = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
306 HLTInfo( "Merger distance is set to: %d", fMergerDistance );
307 continue;
308 }
309
c012881c 310 if ( argument.CompareTo( "-debug-level" ) == 0 ) {
311 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
312 fDebug = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
313 HLTInfo( "Debug level is set to: %d", fDebug );
314 continue;
315 }
316
317 HLTError( "Unknown option \"%s\"", argument.Data() );
318 iResult = -EINVAL;
319 }
320 delete pTokens;
321
322 if ( bMissingParam ) {
323 HLTError( "Specifier missed for parameter \"%s\"", argument.Data() );
324 iResult = -EINVAL;
325 }
326
327 return iResult;
328}
329
330
331int AliHLTTPCHWCFEmulatorComponent::ReadCDBEntry( const char* cdbEntry, const char* chainId )
332{
333 // Read configuration from OCDB
334
335 const char* defaultNotify = "";
336
337 if ( !cdbEntry ){
338 cdbEntry = "HLT/ConfigTPC/TPCHWClusterFinder";
339 defaultNotify = " (default)";
340 chainId = 0;
341 }
342
343 HLTInfo( "configure from entry \"%s\"%s, chain id %s", cdbEntry, defaultNotify, ( chainId != NULL && chainId[0] != 0 ) ? chainId : "<none>" );
344 AliCDBEntry *pEntry = AliCDBManager::Instance()->Get( cdbEntry );//,GetRunNo());
345
346 if ( !pEntry ) {
347 HLTError( "cannot fetch object \"%s\" from CDB", cdbEntry );
348 return -EINVAL;
349 }
350
351 TObjString* pString = dynamic_cast<TObjString*>( pEntry->GetObject() );
352
353 if ( !pString ) {
354 HLTError( "configuration object \"%s\" has wrong type, required TObjString", cdbEntry );
355 return -EINVAL;
356 }
357
358 HLTInfo( "received configuration object string: \"%s\"", pString->GetString().Data() );
359
360 return ReadConfigurationString( pString->GetString().Data() );
361}
362
363
364int AliHLTTPCHWCFEmulatorComponent::Configure( const char* cdbEntry, const char* chainId, const char *commandLine )
365{
366 // Configure the component
367 // There are few levels of configuration,
368 // parameters which are set on one step can be overwritten on the next step
369
370 //* read hard-coded values
371
372 SetDefaultConfiguration();
373
374 //* read the default CDB entry
375
376 int iResult1 = ReadCDBEntry( NULL, chainId );
377
378 //* read the actual CDB entry if required
379
380 int iResult2 = ( cdbEntry ) ? ReadCDBEntry( cdbEntry, chainId ) : 0;
381
382 //* read extra parameters from input (if they are)
383
384 int iResult3 = 0;
385
386 if ( commandLine && commandLine[0] != '\0' ) {
387 HLTInfo( "received configuration string from HLT framework: \"%s\"", commandLine );
388 iResult3 = ReadConfigurationString( commandLine );
389 }
b7ea7fe9 390
391 if( fDebug>1 ) fCFEmulator.SetDebugLevel( fDebug );
392 else fCFEmulator.SetDebugLevel(0);
c012881c 393
394 return iResult1 ? iResult1 : ( iResult2 ? iResult2 : iResult3 );
395}
396
397
398int AliHLTTPCHWCFEmulatorComponent::DoDeinit()
399{
400 // see header file for class documentation
401 return 0;
402}
403
404
405int AliHLTTPCHWCFEmulatorComponent::DoEvent( const AliHLTComponentEventData& evtData,
406 const AliHLTComponentBlockData* blocks,
407 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
408 AliHLTUInt32_t& size,
409 vector<AliHLTComponentBlockData>& outputBlocks )
410{
411 // see header file for class documentation
412
413 int iResult=0;
414 AliHLTUInt32_t maxSize = size;
415 size = 0;
416
417 if(!IsDataEvent()){
418 return 0;
419 }
420
421 fBenchmark.StartNewEvent();
422 fBenchmark.Start(0);
423
eb62889b 424 AliHLTUInt32_t configWord1=0, configWord2=0;
425 AliHLTTPCHWCFEmulator::CreateConfiguration
426 ( fDoDeconvTime, fDoDeconvPad, fDoFlowControl, fDoSinglePadSuppression, fBypassMerger, fClusterLowerLimit, fSingleSeqLimit, fMergerDistance, configWord1, configWord2 );
c012881c 427
428 for ( unsigned long ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
429 {
430 const AliHLTComponentBlockData* iter = blocks+ndx;
431
432 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC)
433 && iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
434
435 int slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
436 int patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
437
438 const char *str=Form("slice %d patch %d:", slice, patch);
439
440 fBenchmark.AddInput(iter->fSize);
441
442 if (!iter->fPtr) continue;
443
444 // create input block for the HW cluster finder
445
446 const AliHLTUInt32_t *rawEvent=0;
447 const AliHLTTPCClusterMCLabel *mcLabels = 0;
448 AliHLTUInt32_t rawEventSize32 = 0;
449 AliHLTUInt32_t nMCLabels = 0;
450
451 if( fCFSupport.CreateRawEvent( iter, rawEvent, rawEventSize32, mcLabels, nMCLabels )<0 ) continue;
452 if( !fDoMC ){
453 mcLabels = 0;
454 nMCLabels = 0;
455 }
456
457 // book memory for the output
458
459 AliHLTUInt32_t maxNClusters = rawEventSize32 + 1; // N 32-bit words in input
33861fe0 460 AliHLTUInt32_t clustersSize32 = maxNClusters*AliHLTTPCHWCFData::fgkAliHLTTPCHWClusterSize;
c012881c 461 AliHLTUInt32_t nOutputMC = maxNClusters;
462
463 AliHLTUInt32_t headerSize = sizeof(AliRawDataHeader);
464 AliHLTUInt8_t *outBlock = new AliHLTUInt8_t[ headerSize+clustersSize32*sizeof(AliHLTUInt32_t) ];
465
466 AliHLTTPCClusterMCData *outMC = reinterpret_cast<AliHLTTPCClusterMCData *>(new AliHLTTPCClusterMCLabel[nOutputMC+1]);
467
468 if( !outBlock || !outMC ){
469 HLTWarning("%s Not enouth memory!!!", str);
470 delete[] outBlock;
471 delete[] outMC;
472 continue;
473 }
474
475 // fill CDH header here, since the HW clusterfinder does not receive it
476
477 AliRawDataHeader *cdhHeader = reinterpret_cast<AliRawDataHeader*>(iter->fPtr);
478 AliRawDataHeader *outCDHHeader = reinterpret_cast<AliRawDataHeader*>(outBlock);
479 *outCDHHeader = *cdhHeader;
480 outCDHHeader->fSize = 0xFFFFFFFF;
481
482 AliHLTUInt32_t *outClusters = reinterpret_cast<AliHLTUInt32_t*> (outBlock + headerSize);
483
484 fBenchmark.Start(1);
485 fCFEmulator.Init
eb62889b 486 ( fCFSupport.GetMapping(slice,patch), configWord1, configWord2 );
c012881c 487
488 int err = fCFEmulator.FindClusters( rawEvent, rawEventSize32,
489 outClusters, clustersSize32,
490 mcLabels, nMCLabels,
491 outMC );
492 fBenchmark.Stop(1);
493 if( err==-1 ){ HLTWarning("NULL input pointer (warning %d)",err);}
494 else if( err==-2 ){ HLTWarning("No space left in the output buffer (warning %d)",err); }
495 else if( err<0 ){ HLTWarning("HWCF emulator finished with error code %d",err); }
496 if( err<0 ){
497 delete[] outBlock;
498 delete[] outMC;
499 continue;
500 }
501
502 if( fDebug ){
33861fe0 503 int elsize=AliHLTTPCHWCFData::fgkAliHLTTPCHWClusterSize;
c012881c 504 printf("\nHWCF Emulator: output clusters for slice%d patch %d:\n",slice,patch);
33861fe0 505 for( AliHLTUInt32_t i=0; i<clustersSize32; i+=elsize ){
c012881c 506 AliHLTUInt32_t *c = outClusters+i;
507 AliHLTUInt32_t flag = (c[0]>>30);
508 if( flag == 0x3){ //beginning of a cluster
509 int padRow = (c[0]>>24)&0x3f;
510 int q = (c[0]&0xFFFFFF)>>6;
511 double p = *((AliHLTFloat32_t*)&c[1]);
512 double t = *((AliHLTFloat32_t*)&c[2]);
513 AliHLTFloat32_t p2 = *((AliHLTFloat32_t*)&c[3]);
514 AliHLTFloat32_t t2 = *((AliHLTFloat32_t*)&c[4]);
515 printf("N: %3d R: %3d C: %4d P: %7.4f T: %8.4f DP: %6.4f DT: %6.4f\n",
33861fe0 516 i/elsize+1, padRow, q, p, t, sqrt(fabs(p2-p*p)), sqrt(fabs(t2-t*t)));
c012881c 517
518 if( outMC && outMC->fCount>0 ){
519 printf(" MC: (%3d,%6.1f) (%3d,%6.1f) (%3d,%6.1f)\n",
33861fe0 520 outMC->fLabels[i/elsize].fClusterID[0].fMCID,outMC->fLabels[i/elsize].fClusterID[0].fWeight,
521 outMC->fLabels[i/elsize].fClusterID[1].fMCID,outMC->fLabels[i/elsize].fClusterID[1].fWeight,
522 outMC->fLabels[i/elsize].fClusterID[2].fMCID,outMC->fLabels[i/elsize].fClusterID[2].fWeight
c012881c 523 );
524 }
525 }
526 }
527 }
528
529
530 AliHLTUInt32_t outSize = headerSize + clustersSize32*sizeof(AliHLTUInt32_t);
531
532 if( size + outSize <= maxSize ){
533
534 memcpy( outputPtr, outBlock, outSize );
535
536 AliHLTComponentBlockData bd;
537 FillBlockData( bd );
538 bd.fOffset = size;
539 bd.fSize = outSize;
540 bd.fSpecification = iter->fSpecification;
541 bd.fDataType = AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC;
542 outputBlocks.push_back( bd );
543 fBenchmark.AddOutput(bd.fSize);
544 size+= bd.fSize;
545 outputPtr+=bd.fSize;
546 } else {
547 HLTWarning( "Output buffer (%db) is too small, required %db", maxSize, size+outSize);
548 iResult=-ENOSPC;
549 }
550
551 if( fDoMC && outMC && outMC->fCount>0 ){
552 int s = sizeof(AliHLTTPCClusterMCData) + outMC->fCount*sizeof(AliHLTTPCClusterMCLabel);
553 if( size + s <= maxSize ){
554 memcpy( outputPtr, outMC, s );
555 AliHLTComponentBlockData bdMCInfo;
556 FillBlockData( bdMCInfo );
557 bdMCInfo.fOffset = size;
558 bdMCInfo.fSize = s;
559 bdMCInfo.fSpecification = iter->fSpecification;
560 bdMCInfo.fDataType = AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC;
561 outputBlocks.push_back( bdMCInfo );
562 fBenchmark.AddOutput(bdMCInfo.fSize);
563 size+=bdMCInfo.fSize;
564 outputPtr+=bdMCInfo.fSize;
565 } else {
566 HLTWarning( "Output buffer (%db) is too small, required %db", maxSize, size+s);
567 iResult=-ENOSPC;
568 }
569 }
570
571 delete[] outBlock;
572 delete[] outMC;
573 }
574
575 fBenchmark.Stop(0);
576 HLTInfo(fBenchmark.GetStatistics());
577 return iResult;
578}
579
580