win32_avi_reader.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "win32_avi_reader.h"
  2. #include <strsafe.h>
  3. const int _BUFFER_SIZE_ = 16384;
  4. AVIReaderWin32::AVIReaderWin32()
  5. {
  6. hFile = 0;
  7. _ring_buffer.reserve( _BUFFER_SIZE_ );
  8. end_of_file = false;
  9. position.QuadPart = 0;
  10. local_filename = 0;
  11. }
  12. AVIReaderWin32::~AVIReaderWin32()
  13. {
  14. free( local_filename );
  15. }
  16. void AVIReaderWin32::Close()
  17. {
  18. if ( hFile && hFile != INVALID_HANDLE_VALUE )
  19. {
  20. //CancelIo(hFile);
  21. CloseHandle( hFile );
  22. }
  23. }
  24. uint64_t AVIReaderWin32::GetContentLength()
  25. {
  26. LARGE_INTEGER position;
  27. position.QuadPart = 0;
  28. position.LowPart = GetFileSize( hFile, (LPDWORD)&position.HighPart );
  29. if ( position.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR )
  30. return 0;
  31. else
  32. return position.QuadPart;
  33. }
  34. void AVIReaderWin32::GetFilename( wchar_t *fn, size_t len )
  35. {
  36. StringCchCopyW( fn, len, local_filename );
  37. }
  38. int AVIReaderWin32::Open( const wchar_t *filename )
  39. {
  40. free( local_filename );
  41. local_filename = _wcsdup( filename );
  42. hFile = CreateFile( filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0 );
  43. if ( hFile == INVALID_HANDLE_VALUE )
  44. return nsavi::READ_NOT_FOUND;
  45. return nsavi::READ_OK;
  46. }
  47. /* used by RingBuffer::fill() */
  48. size_t AVIReaderWin32::Read( void *dest, size_t len )
  49. {
  50. // TODO: use overlapped I/O so can we wait on the read simultaneously with the killswitch and seek_event
  51. DWORD bytes_read = 0;
  52. if ( ReadFile( hFile, dest, (DWORD)len, &bytes_read, NULL ) && bytes_read != len )
  53. end_of_file = true;
  54. return bytes_read;
  55. }
  56. int AVIReaderWin32::Read( void *p_read_buffer, uint32_t read_length, uint32_t *bytes_read )
  57. {
  58. if ( end_of_file && _ring_buffer.empty() )
  59. return nsavi::READ_EOF;
  60. size_t total_bytes_read = 0;
  61. while ( read_length && !( end_of_file && _ring_buffer.empty() ) )
  62. {
  63. // read what we can from the buffer
  64. size_t bytes_read = _ring_buffer.read( p_read_buffer, read_length );
  65. p_read_buffer = (uint8_t *)p_read_buffer + bytes_read;
  66. read_length -= (uint32_t)bytes_read;
  67. total_bytes_read += bytes_read;
  68. position.QuadPart += bytes_read;
  69. if ( read_length > _BUFFER_SIZE_ )
  70. {
  71. // read directly from the file if we have a large read
  72. bytes_read = Read( p_read_buffer, read_length );
  73. p_read_buffer = (uint8_t *)p_read_buffer + bytes_read;
  74. read_length -= (uint32_t)bytes_read;
  75. total_bytes_read += bytes_read;
  76. position.QuadPart += bytes_read;
  77. }
  78. else
  79. {
  80. // refill buffer if necessary
  81. _ring_buffer.fill( this, _BUFFER_SIZE_ );
  82. }
  83. }
  84. *bytes_read = (uint32_t)total_bytes_read;
  85. return nsavi::READ_OK;
  86. }
  87. int AVIReaderWin32::Peek( void *read_buffer, uint32_t read_length, uint32_t *bytes_read )
  88. {
  89. if ( end_of_file && _ring_buffer.empty() )
  90. return nsavi::READ_EOF;
  91. // refill buffer if necessary
  92. if ( _ring_buffer.size() < read_length )
  93. _ring_buffer.fill( this, _BUFFER_SIZE_ );
  94. *bytes_read = (uint32_t)_ring_buffer.peek( read_buffer, read_length );
  95. return nsavi::READ_OK;
  96. }
  97. static LONGLONG Seek64( HANDLE hf, __int64 distance, DWORD MoveMethod )
  98. {
  99. LARGE_INTEGER li;
  100. li.QuadPart = distance;
  101. li.LowPart = SetFilePointer( hf, li.LowPart, &li.HighPart, MoveMethod );
  102. if ( li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR )
  103. {
  104. li.QuadPart = -1;
  105. }
  106. return li.QuadPart;
  107. }
  108. int AVIReaderWin32::Seek( uint64_t new_position )
  109. {
  110. _ring_buffer.clear();
  111. position.QuadPart = Seek64( hFile, new_position, SEEK_SET );
  112. end_of_file = ( position.QuadPart != new_position );
  113. return nsavi::READ_OK;
  114. }
  115. uint64_t AVIReaderWin32::Tell()
  116. {
  117. return position.QuadPart;
  118. }
  119. int AVIReaderWin32::Skip( uint32_t skip_bytes )
  120. {
  121. if ( end_of_file && _ring_buffer.empty() )
  122. return nsavi::READ_EOF;
  123. if ( skip_bytes < _ring_buffer.size() )
  124. {
  125. _ring_buffer.advance( skip_bytes );
  126. position.QuadPart += skip_bytes;
  127. return nsavi::READ_OK;
  128. }
  129. else
  130. {
  131. return Seek( position.QuadPart + skip_bytes );
  132. }
  133. }
  134. void AVIReaderWin32::OverlappedHint( uint32_t read_length )
  135. {
  136. if ( read_length > _ring_buffer.size() )
  137. _ring_buffer.fill( this, _BUFFER_SIZE_ );
  138. }