vid_data.dart 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import 'dart:typed_data';
  2. import 'package:flutter/foundation.dart';
  3. import 'package:vid/us/vid_us_data_http_reader.dart';
  4. import 'package:vid/us/vid_us_data_reader.dart';
  5. import 'package:vid/us/vid_us_image.dart';
  6. import 'package:vid/us/vid_us_image_data.dart';
  7. import 'package:vid/us/vid_us_probe.dart';
  8. import 'reader.dart';
  9. abstract class AsyncVidImageDataBase {
  10. late AsyncVidDataReaderBase _reader;
  11. late List<int> _imagePositionList;
  12. late int _version;
  13. late int _imageCount;
  14. late VidUsProbe _probe;
  15. late VidUsImageFormat _imageFormat;
  16. late Uint8List _extendedData;
  17. late int _readHeaderTimeout;
  18. late int _readImageTimeout;
  19. late bool _initialized;
  20. late bool _closed;
  21. final Duration delayDuration = const Duration(milliseconds: 10);
  22. static final String vid_header = "VINNO IMAGE DATA";
  23. /// Gets the version of this image data.
  24. int get version => _version;
  25. /// Gets the image count of this image data.
  26. int get imageCount => _imageCount;
  27. /// Gets the probe information.
  28. VidUsProbe get probe => _probe;
  29. /// Gets the image format of this image data.
  30. VidUsImageFormat get imageFormat => _imageFormat;
  31. /// Gets the extended data.
  32. Uint8List get extendedData => _extendedData;
  33. /// Gets the initialized state.
  34. bool get initialized => _initialized;
  35. /// Create a VINNO Image Data.
  36. /// [readHeaderTimeout] is the timeout value of reading header and probe information etc..., we need give as much time as possible
  37. /// to let the reader read the header.
  38. /// [readImageTimeout] is the timeout value of reading one frame.
  39. /// [minChunkSize] The min download chunk size, set to a large value may speedup the download speed, but will cause the progress not smooth.
  40. AsyncVidImageDataBase(
  41. String url, {
  42. DownloadCallback? downloadCallback,
  43. int readHeaderTimeout = 3000,
  44. int readImageTimeout = 500,
  45. }) {
  46. _initialized = false;
  47. _closed = false;
  48. _readHeaderTimeout = readHeaderTimeout;
  49. _readImageTimeout = readImageTimeout;
  50. _reader = createReader(url, downloadCallback: downloadCallback);
  51. }
  52. @protected
  53. AsyncVidDataReaderBase createReader(String url,
  54. {DownloadCallback? downloadCallback});
  55. ///Get the downloaded data of this HttpVidUsImageData
  56. Uint8List getDownloadedData() {
  57. return _reader.toBytes();
  58. }
  59. void setReadHeaderTimeout(int timeout) => _readHeaderTimeout = timeout;
  60. void setReadImageTimeout(int timeout) => _readImageTimeout = timeout;
  61. ///Initialize the HttpVidUsImageData, must be called firstly.
  62. Future<bool> initialize() async {
  63. if (!_initialized) {
  64. var header = await _readHeader();
  65. if (header != vid_header) {
  66. // throw Exception("The input data is not a VID data.");
  67. }
  68. _version = await _readVersion();
  69. //Get probe info
  70. _probe = await _readProbe();
  71. _imageFormat = await _readImageFormat();
  72. _extendedData = await _readExtendedData();
  73. _imagePositionList = [];
  74. var imagePositionListData = await _readImagePositionListData();
  75. _imageCount = imagePositionListData.length ~/ 8;
  76. var imagePositionReader = VidUsDataReader(imagePositionListData);
  77. for (var i = 0; i < _imageCount; i++) {
  78. _imagePositionList.add(imagePositionReader.readInt64V2());
  79. }
  80. _initialized = true;
  81. }
  82. return _initialized;
  83. }
  84. ///Close the HttpVidUsImageData, it will force close the download operation and reading operation.
  85. void close() {
  86. if (_closed) return;
  87. _closed = true;
  88. _reader.close();
  89. }
  90. T getReader<T extends AsyncVidDataReaderBase>() => _reader as T;
  91. ///Read header from http data.
  92. Future<String> _readHeader() async {
  93. var timeout = 0;
  94. while (!_closed) {
  95. try {
  96. var header = _reader.readString();
  97. return header;
  98. } catch (ex) {
  99. if (ex is NotReadyException) {
  100. if (timeout >= _readHeaderTimeout) {
  101. throw ReadTimeoutException();
  102. }
  103. await Future.delayed(delayDuration);
  104. timeout += delayDuration.inMilliseconds;
  105. } else {
  106. rethrow;
  107. }
  108. }
  109. }
  110. throw AlreadyClosedException();
  111. }
  112. ///Read the version from http data.
  113. Future<int> _readVersion() async {
  114. var timeout = 0;
  115. while (!_closed) {
  116. try {
  117. var version = _reader.readInt();
  118. return version;
  119. } catch (ex) {
  120. if (ex is NotReadyException) {
  121. if (timeout >= _readHeaderTimeout) {
  122. throw ReadTimeoutException();
  123. }
  124. await Future.delayed(delayDuration);
  125. timeout += delayDuration.inMilliseconds;
  126. } else {
  127. rethrow;
  128. }
  129. }
  130. }
  131. throw AlreadyClosedException();
  132. }
  133. ///Read the probe info from http data.
  134. Future<VidUsProbe> _readProbe() async {
  135. var timeout = 0;
  136. while (!_closed) {
  137. try {
  138. var probeData = _reader.readBytes();
  139. return VidUsProbe.fromBytes(probeData);
  140. } catch (ex) {
  141. if (ex is NotReadyException) {
  142. if (timeout >= _readHeaderTimeout) {
  143. throw ReadTimeoutException();
  144. }
  145. await Future.delayed(delayDuration);
  146. timeout += delayDuration.inMilliseconds;
  147. } else {
  148. rethrow;
  149. }
  150. }
  151. }
  152. throw AlreadyClosedException();
  153. }
  154. ///Read the image format from http data.
  155. Future<VidUsImageFormat> _readImageFormat() async {
  156. var timeout = 0;
  157. while (!_closed) {
  158. try {
  159. return VidUsImageFormat.values[_reader.readInt()];
  160. } catch (ex) {
  161. if (ex is NotReadyException) {
  162. if (timeout >= _readHeaderTimeout) {
  163. throw ReadTimeoutException();
  164. }
  165. await Future.delayed(delayDuration);
  166. timeout += delayDuration.inMilliseconds;
  167. } else {
  168. rethrow;
  169. }
  170. }
  171. }
  172. throw AlreadyClosedException();
  173. }
  174. ///Read extended data from http data.
  175. Future<Uint8List> _readExtendedData() async {
  176. var timeout = 0;
  177. while (!_closed) {
  178. try {
  179. return _reader.readBytes();
  180. } catch (ex) {
  181. if (ex is NotReadyException) {
  182. if (timeout >= _readHeaderTimeout) {
  183. throw ReadTimeoutException();
  184. }
  185. await Future.delayed(delayDuration);
  186. timeout += delayDuration.inMilliseconds;
  187. } else {
  188. rethrow;
  189. }
  190. }
  191. }
  192. throw AlreadyClosedException();
  193. }
  194. ///Read the image positions data from http data.
  195. Future<Uint8List> _readImagePositionListData() async {
  196. var timeout = 0;
  197. while (!_closed) {
  198. try {
  199. return _reader.readBytes();
  200. } catch (ex) {
  201. if (ex is NotReadyException) {
  202. if (timeout >= _readHeaderTimeout) {
  203. throw ReadTimeoutException();
  204. }
  205. await Future.delayed(delayDuration);
  206. timeout += delayDuration.inMilliseconds;
  207. } else {
  208. rethrow;
  209. }
  210. }
  211. }
  212. throw AlreadyClosedException();
  213. }
  214. /// Get one image from the vid.
  215. Future<VidUsImage> getImage(int index) async {
  216. if (index >= _imageCount || index < 0) {
  217. throw Exception("Can not find image Data");
  218. }
  219. //Jump to image.
  220. var timeout = 0;
  221. while (!_closed) {
  222. try {
  223. var imageData = _reader.readBytes(_imagePositionList[index]);
  224. return VidUsImage.fromBytes(imageData);
  225. } catch (ex) {
  226. if (ex is NotReadyException) {
  227. if (timeout >= _readImageTimeout) {
  228. throw ReadTimeoutException();
  229. }
  230. await Future.delayed(delayDuration);
  231. timeout += delayDuration.inMilliseconds;
  232. } else {
  233. rethrow;
  234. }
  235. }
  236. }
  237. throw AlreadyClosedException();
  238. }
  239. }