Presentation is loading. Please wait.

Presentation is loading. Please wait.

Implementing A FAT Based 64 Bit DVR Peter VanOudenaren, President, EBS Inc.

Similar presentations


Presentation on theme: "Implementing A FAT Based 64 Bit DVR Peter VanOudenaren, President, EBS Inc."— Presentation transcript:

1 Implementing A FAT Based 64 Bit DVR Peter VanOudenaren, President, EBS Inc.

2 DVR System Requirements  Must minimize latencies  Must minimize CPU utilization.  Must have predictable execution times  Must support contiguous files  Must be DMA friendly

3 DVR System Requirements Continued…..  Must guarantee volume integrity.  Must guarantee session integrity.  Must monitor resource utilization and block placement

4 DVR Application Requirements  Must support files over 4 Gigabytes  Must continuously collect incoming video to a disk buffer.

5 DVR Application Requirements Continued…..  Must simultaneously record and display data from the disk buffer.  Must archive data from the disk buffer.  Must navigate the disk buffer.

6 RTFSProPlus Achieves DVR System and Application Requirements  Extremely fast command executions speeds  Failsafe III maintains volume integrity  Failsafe III maintains session integrity  Failsafe III extends the “real time” interval

7 RTFSProPlus Achieves DVR System and Application Requirements  Asynchronous operation  FAT64 64 bit metafiles  Contiguous files  Real time read  Real time write  Real time seek

8 DVR Solutions With RTFSProPlus  Remote diagnostics tool Network attached remote debugger Real time performance monitoring Real time monitoring of resource usage Inspect FAT regions and file chains Browse file directories Identify corrupted files Produce quality assurance reports

9 DVR Solutions With RTFSProPlus  No copy extracts of linear segments from the circular buffer  Circular file writes and reads process extract regions appropriately  Extracted regions appear simultaneously in a linear data file and the circular data buffer

10 DVR Solutions With RTFSProPlus  Circular (ring buffer) files for continuous collection of incoming video  Separate read and write file pointer  “Stream view” file pointers  “File view” file pointers

11 DVR Solutions With RTFSProPlus API designed specifically for DVR and high speed data acquisition applications API designed specifically for DVR and high speed data acquisition applications pc_cfilio_open - Create a circular buffer pc_cfilio_close- Close a circular buffer pc_cfilio_read- Read data from circular buffer pc_cfilio_write- Write to circular buffer pc_cfilio_lseek- Seek read or write pointer pc_cstreamio _lseek- Seek read or write stream pointer pc_cfilio_extract- Create an archive file from a section of the circular buffer

12 – pc_cfilio_open – Open a circular file. DVR Solutions With RTFSProPlus Select file wrap-around point Select 32 bit or 64 bit file Select block allocation policy Provide extract region buffering

13 – pc_cfilio_read – Read from a circular file. DVR Solutions With RTFSProPlus DMA friendly Guaranteed to access disk only for file data Wraps at file wrap point Stops when read catches write file pointer Reads extract file regions appropriately

14 – pc_cfilio_write – Write to a circular file. DVR Solutions With RTFSProPlus DMA friendly Guaranteed to access disk only for writing file data Wraps at file wrap point Programmable to stop when it catches read file pointer Overtakes extract file regions appropriately

15 – pc_cfilio_lseek – Seek in a circular file. DVR Solutions With RTFSProPlus Maintains separate read an write pointers Uses full 64 bit arguments Extremely fast, guaranteed zero disk accesses File pointers represents a linear view of the underlying file Seeks within extract file regions appropriately

16 – C pc_cstreamio_lseek – Circular file seek. DVR Solutions With RTFSProPlus Maintains separate read an write pointers Uses full 64 bit arguments Extremely fast, guaranteed zero disk accesses File pointers represent 64 bit bite offsets in the incoming data stream Seeks within extract file regions appropriately Eases mapping time offsets to video content in the buffer

17 – pc_cfilio_extract – Extract video from the buffer to archive files DVR Solutions With RTFSProPlus Extract N bytes from the current read file pointer. Real time, requires zero data copying in most cases. Minimal copying for non-cluster aligned extract regions Establishes soft link between the extract file and ring buffer Extracts to and from either FAT64 files or FAT32 files. Allocates clusters to be used when the regions is overwritten

18 DVR Programming Examples   Creating a circular file   Buffering incoming video   Displaying buffered video   Accessing frames in the buffer   Buffering at steady state   Archiving buffered video   Displaying archived video The following slides present the source code and run time behavior of typical DVR algorithm implemented with RtfsProPlus.

19 Creating a Circular File int VideoBufferFd; int DisplayFromFd; int ArchiveVideoBufferFd; char *VideoBufferFileName = "dvr.demo"; char *VideoBufferDrive = "A:"; /* Create a circular buffer file that wraps at 16 Gigabytes and keeps writing even if the write pointer overtakes the read pointer */ BOOLEAN InitializeVideoBuffer(dword FrameNumber) { dword cluster_size_bytes; EFILEOPTIONS Options; rtfs_memset(&Options, 0, sizeof(Options));

20 Creating a Circular File Options.allocation_policy = PCE_CIRCULAR_BUFFER; /* Since the file is over 4 gigabytes, Use FAT64 */ Options.allocation_policy |= PCE_64BIT_META_FILE; Options.circular_file_size_hi = 4; /* 4 X 4 gigabytes */ Options.circular_file_size_lo = 0; /* Wrap point */ /* Force it to be contiguous and preallocate all clusters*/ Options.allocation_policy |= PCE_FORCE_CONTIGUOUS; /* How many cluster in 16 Gigabytes */ cluster_size_bytes = pc_cluster_size(VideoBufferDrive); Options.min_clusters_per_allocation = 16 * (1073741823/cluster_size_bytes); VideoBufferFd = pc_cfilio_open ((byte *)VideoBufferFileName, (PO_BINARY|PO_RDWR| PO_CREAT|PO_TRUNC), &Options); DisplayFromFd = VideoBufferedFd; if(VideoBufferedFd >= 0) // Return the Status return(TRUE); else return(FALSE); }

21 Buffering Incoming Video Background thread cycles continuously, waits for a Framebuffer to be captured then writes to the circular file and releases the Framebuffer memory for future capture

22 Buffering Incoming Video void VideoInputThread(void) { int FrameSize; dword FrameAddress, nWritten; for(;;) { WaitForFrame(&FrameSize, &FrameAddress); pc_cfilio_write(VideoBufferFd, (byte*)FrameAddress, FrameSize, &nWritten); ReleaseFrameMemory(FrameAddress, FrameSize); }

23 Displaying Buffered Video Background thread cycles continuously, acquires an available video display page, then reads data from the circular file into the video memory and alerts the video processor that the frame may now be displayed

24 Displaying Buffered Video void DisplayFromVideoBuffer(void) { for(;;) { VideoPage = GetNextFreeVideoPage(&PageAddress, &PageSize); ClaimVideoProcessor(); // Display from the circular file unless we are displaying a saved video clip if (DisplayFromFd == VideoBufferedFd) pc_cfilio_read (VideoBufferFd, PageAddress, PageSize, &BytesRead); else { // Displaying an archive pc_efilio_read(DisplayFromFd, PageAddress, PageSize, &BytesRead); if (!BytesRead) { // The clip finished. resume displaying from the video buffer pc_efilio_close(DisplayFromFd); DisplayFromFd = VideoBufferedFd; pc_cfilio_read (VideoBufferFd, PageAddress, PageSize, &BytesRead); } QueueDisplayVideoPage (VideoPage); ReleaseVideoProcessor (); }

25 Accessing Frames In The Buffer Seek to a specific Frame in the video buffer where DisplayFromVideoBuffer() will resume displaying data from.

26 Accessing Frames In The Buffer BOOLEAN SetVideoBufferDisplayLocation(dword FrameNumber) { ddword stream_offset; dword CurrLPtrHi, CurrLPtrLo, newFramePtrHi, newFramePtrLo; ClaimVideoProcessor(); // save the current display location if (DisplayFromFd == VideoBufferedFd) pc_cfilio_lseek (VideoBufferFd, CFREAD_POINTER, 0, 0, PSEEK_CUR, &CurrLPtrHi, &CurrLPtrLo); else pc_efilio_lseek (DisplayFromFd, 0, 0, PSEEK_CUR, &CurrLPtrHi, &CurrLPtrLo); // Now seek to the byte location of the frame stream_offset = FrameNumber * BYTES_PER_FRAME; if (DisplayFromFd == VideoBufferedFd) SeekOk = pc_cstreamio_lseek (VideoBufferFd, CFREAD_POINTER, M64HIGHDW(stream_offset), M64LOWDW(stream_offset), PSEEK_SET, &newFramePtrHi, &newFramePtrLo); else SeekOk = pc_efilio_lseek (DisplayFromFd, M64HIGHDW(stream_offset), M64LOWDW(stream_offset), PSEEK_SET, &newFramePtrHi, &newFramePtrLo);

27 Accessing Frames In The Buffer if (SeekOk) { // The read pointer has been moved to this frame allow the display process // to resume from here ReleaseVideoProcessor(); return(TRUE); } else { // Seek failed make sure the pointer is at the original location if (DisplayFromFd == VideoBufferedFd) // This frame number is not buffered in the 16 gigabyte circular pc_cfilio_lseek (VideoBufferFd, CFREAD_POINTER, &CurrLPtrHi, &CurrLPtrLo, PSEEK_SET, &CurrLPtrHi, &CurrLPtrLo); else // This frame number is not buffered in the video clip pc_efilio_lseek (DisplayFromFd, &CurrLPtrHi, &CurrLPtrLo, PSEEK_SET, &CurrLPtrHi, &CurrLPtrLo); ReleaseVideoProcessor(); return(FALSE); }

28 Buffering At Steady State Demonstrate using circular files for a burst data collection application with deep buffering requirements. Data retention is critical so if the application loses any data it is a critical error and must be restarted with more buffering, faster processing or slower collection rates.

29 Buffering At Steady State void CollectBurstInput() { EFILEOPTIONS Options; dword cluster_size_bytes,nWritten,nRead,nBurstdata; int CFileFd; byte *PburstData, Buffer[4096]; rtfs_memset(&Options, 0, sizeof(Options)); /* Create a circular file that wraps at 16Gigabytes and stops writing if the write pointer overtakes the read pointer */ Options.allocation_policy = PCE_CIRCULAR_FILE; /* Since the file is over 4 gigabytes, Use FAT64 */ Options.allocation_policy |= PCE_64BIT_META_FILE; Options.circular_file_size_hi = 4; /* 4 X 4 gigabytes */ Options.circular_file_size_lo = 0; /* Wrap point */ /* Force it to be contiguous and preallocate all clusters*/ Options.allocation_policy |= PCE_FORCE_CONTIGUOUS; /* Make it a temp file since there's no need to ever flush the file's metadata to disk Options.allocation_policy != PCE_TEMP_FILE; /* How many cluster in 16 Gigabytes */ cluster_size_bytes = pc_cluster_size(DataBufferDrive); Options.min_clusters_per_allocation = 16 * (1073741823/cluster_size_bytes); CFileFd = pc_cfilio_open ("DataCollectBufferFIle", PO_BINARY|PO_RDWR|PO_CREAT|PO_TRUNC, &Options); if(CFileFd < 0) return;

30 Buffering At Steady State /*Enter a loop, accepting variable amount of data from a fictitious data collection routine and put the data in a ring buffer. Read the data in 4096 byte chunks from the ring buffer and pass it to a fictitious processing routine. If the processing loop empties the buffer, wait for more data. If the write operation can't write all of the data that the data collection routine provides that indicates it would overwrite data that has not yet been collected, so warn the user and halt the process*/ for (;;) { if (BurstDataAvailable(&PburstData, &nBurstdata) { pc_cfilio_write(CFileFd, PburstData, nBurstdata, &nWritten); if (nWritten != nBurstdata) { printf("File buffer is too small, lost data\n"); pc_cfilio_close(CFileFd); return; } pc_cfilio_read(CFileFd, Buffer, 4096, &nRead);

31 Buffering At Steady State if (nRead) ProcessData(Buffer,nRead); else WaitForMoreData(); }

32 Archiving Buffered Video Extract some number of frames from the video buffer to an archive file. The extracted data will be stored in a linear file, but it will also be part of the video buffer file.

33 Archiving Buffered Video /* Callback function that closes the archive file when it is no longer needed by the circular file. This occurs when the write pointer reaches and overtakes the region in the buffer where the data was extracted from. */ void CBArchiveOverwritten(int fd, BOOLEAN Success) { //Start an asynchronous close, the background async handler will complete it for us pc_efilio_async_close(fd); } BOOLEAN ArchiveFromVideoBuffer(char *ArchiveFileName, dword StartFrame, dword nFrames, BOOLEAN DoFlush) { int ExtractFd; ddword stream_offset,extract_bytes; EFILEOPTIONS ArchiveFileOptions; BOOLEAN Result = FALSE; /* open a special REMAP file for archiving */ rtfs_memset(&ArchiveFileOptions, 0, sizeof(ArchiveFileOptions)); ArchiveFileOptions.allocation_policy = PCE_REMAP_FILE; ArchiveFileOptions.allocation_policy |= PCE_64BIT_META_FILE; ExtractFd = pc_efilio_open(ArchiveFileName, PO_RDWR|PO_TRUNC|PO_CREAT, PS_IWRITE | PS_IREAD, &ArchiveFileOptions); if (ExtractFd < 0) return(FALSE);

34 Archiving Buffered Video // This moves the read pointer but happens very quickly, so wait for retrace WaitForVideoRetrace(); ClaimVideoProcessor(); //save current display location pc_cfilio_lseek (VideoBufferFd, CFREAD_POINTER, 0, 0, PSEEK_CUR, &CurrLPtrHi, &CurrLPtrLo); // Now seek to the byte location of the frames to archive stream_offset = StartFrame * BYTES_PER_FRAME; if(pc_cstreamio_lseek (VideoBufferFd, CFREAD_POINTER, M64HIGHDW(stream_offset), M64LOWDW(stream_offset), PSEEK_SET, &newFramePtrHi, &newFramePtrLo)) { extract_bytes = nFrames * BYTES_PER_FRAME; /* link the two files together with little or no copying */ Result = pc_cfilio_extract(VideoBufferFd, ExtractFd, M64HIGHDW(extract_bytes), M64HIGHDW(extract_bytes)); }

35 Archiving Buffered Video // restore the pointer to the original location and resume display pc_cfilio_lseek (VideoBufferFd, CFREAD_POINTER, &CurrLPtrHi, &CurrLPtrLo, PSEEK_CUR, &newFramePtrHi, &newFramePtrLo); ReleaseVideoProcessor(); // If success, start an async flush process to put it to disk if (Result) pc_efilio_async_flush(ExtractFd); else { // Otherwise delete the empty extract file pc_efilio_close(ExtractFd); pc_efilio_async_delete(ArchiveFileName); } return (Result); }

36 Displaying Archived Video Open a saved video clip for display by the display thread.

37 Displaying Archived Video int CurrentDisplayngArchiveFd; void DisplayFromVideoArchive(char *ArchiveFileName) { int ArchiveFd; EFILEOPTIONS ArchiveFileOptions; // Reopen the archive file, the file will automatically detect FAT64 or FAT32 rtfs_memset(&ArchiveFileOptions, 0, sizeof(ArchiveFileOptions)); ArchiveFd = pc_efilio_open(ArchiveFileName, PO_RDWR,0, &ArchiveFileOptions); if (ArchiveFd >= 0) { // Set the file descriptor for the display task ClaimVideoProcessor(); DisplayFromFd = ArchiveFd; ReleaseVideoProcessor(); }

38 Completing Asynchronous Requests This background thread cycles continuously and waits for a time window when it can safely access the drive without affecting foreground operations. It then performs one or more cycles of the asynchronous processing.

39 Completing Asynchronous Requests void AsynchronousCompletionThread(void) { int AsyncState, StepPerPass, DriveNumber; dword FrameAddress, nWritten; DriveNumber = GetVideoDriveNumber(); for (;;) { // Steal cycles for asynchronous processing during a retrace WaitForVideoRetrace(); StepsPerPass = 1; /* Do asynchronous processing, on Files, buffers, journal flushes and journal to volume restores. We could also choose to process only up to an earlier state, such as Journal flush completion by specifying DRV_ASYNC_DONE_JOURNALFLUSH. We could then in a less time critical period complete the whole process. */ AsyncState = pc_async_continue(DriveNumber, DRV_ASYNC_DONE_RESTORE, 1);

40 Completing Asynchronous Requests if (AsyncState == PC_ASYNC_COMPLETE) { // All done, set a fictitious VolumeUptoDate variable needs to be done VolumeUptoDate = TRUE; } else if (AsyncState = PC_ASYNC_CONTINUE) { /* We know that we'll only perform on single multi-block read or one single multi-block write, and we know we can do this in less than 10 miliseconds, so if we have more than 10 miliseconds left take another pass */ if (TimeLeftInRetrace() > 10) AsyncState = pc_async_continue (DriveNumber, DRV_ASYNC_DONE_RESTORE,1); } if (AsyncState = PC_ASYNC_ERROR) { printf ("Error in processing, halt...\n"); halt (); }

41 RTFSProPlus Porting Ports - LinuxVxWorks Signalingpthread_mutex_init()pthread_mutex_lock()pthread_mutex_unlock()semBCreate()semTake()semDelete() Timingusleep()gettimeofday()sleep()tickGet() Kernelpthread_self()taskIdSelf()

42 RTFSProPlus RAM Footprint Journal Restore Buffer32K up to no limit Journal Block Remap Buffer32K is essentially infinite Cluster Management Buffer32K up to no limit Fat table Buffer1K is min, 10K is practical Fragment Buffer12 bytes/fragment, 120K is essentially infinite FAT32 Extended Files200 bytes per file FAT64 Metafiles3200 bytes per file FAT64 Circular Files4000 bytes per file

43 RTFSProPlus Code Size 220K (approx) with all features enabled, non-optimized, full debug support

44


Download ppt "Implementing A FAT Based 64 Bit DVR Peter VanOudenaren, President, EBS Inc."

Similar presentations


Ads by Google