vid_data.dart 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. @protected
  91. T getReader<T extends AsyncVidDataReaderBase>() => _reader as T;
  92. ///Read header from http data.
  93. Future<String> _readHeader() async {
  94. var timeout = 0;
  95. while (!_closed) {
  96. try {
  97. var header = _reader.readString();
  98. return header;
  99. } catch (ex) {
  100. if (ex is NotReadyException) {
  101. if (timeout >= _readHeaderTimeout) {
  102. throw ReadTimeoutException();
  103. }
  104. await Future.delayed(delayDuration);
  105. timeout += delayDuration.inMilliseconds;
  106. } else {
  107. rethrow;
  108. }
  109. }
  110. }
  111. throw AlreadyClosedException();
  112. }
  113. ///Read the version from http data.
  114. Future<int> _readVersion() async {
  115. var timeout = 0;
  116. while (!_closed) {
  117. try {
  118. var version = _reader.readInt();
  119. return version;
  120. } catch (ex) {
  121. if (ex is NotReadyException) {
  122. if (timeout >= _readHeaderTimeout) {
  123. throw ReadTimeoutException();
  124. }
  125. await Future.delayed(delayDuration);
  126. timeout += delayDuration.inMilliseconds;
  127. } else {
  128. rethrow;
  129. }
  130. }
  131. }
  132. throw AlreadyClosedException();
  133. }
  134. ///Read the probe info from http data.
  135. Future<VidUsProbe> _readProbe() async {
  136. var timeout = 0;
  137. while (!_closed) {
  138. try {
  139. var probeData = _reader.readBytes();
  140. return VidUsProbe.fromBytes(probeData);
  141. } catch (ex) {
  142. if (ex is NotReadyException) {
  143. if (timeout >= _readHeaderTimeout) {
  144. throw ReadTimeoutException();
  145. }
  146. await Future.delayed(delayDuration);
  147. timeout += delayDuration.inMilliseconds;
  148. } else {
  149. rethrow;
  150. }
  151. }
  152. }
  153. throw AlreadyClosedException();
  154. }
  155. ///Read the image format from http data.
  156. Future<VidUsImageFormat> _readImageFormat() async {
  157. var timeout = 0;
  158. while (!_closed) {
  159. try {
  160. return VidUsImageFormat.values[_reader.readInt()];
  161. } catch (ex) {
  162. if (ex is NotReadyException) {
  163. if (timeout >= _readHeaderTimeout) {
  164. throw ReadTimeoutException();
  165. }
  166. await Future.delayed(delayDuration);
  167. timeout += delayDuration.inMilliseconds;
  168. } else {
  169. rethrow;
  170. }
  171. }
  172. }
  173. throw AlreadyClosedException();
  174. }
  175. ///Read extended data from http data.
  176. Future<Uint8List> _readExtendedData() async {
  177. var timeout = 0;
  178. while (!_closed) {
  179. try {
  180. return _reader.readBytes();
  181. } catch (ex) {
  182. if (ex is NotReadyException) {
  183. if (timeout >= _readHeaderTimeout) {
  184. throw ReadTimeoutException();
  185. }
  186. await Future.delayed(delayDuration);
  187. timeout += delayDuration.inMilliseconds;
  188. } else {
  189. rethrow;
  190. }
  191. }
  192. }
  193. throw AlreadyClosedException();
  194. }
  195. ///Read the image positions data from http data.
  196. Future<Uint8List> _readImagePositionListData() async {
  197. var timeout = 0;
  198. while (!_closed) {
  199. try {
  200. return _reader.readBytes();
  201. } catch (ex) {
  202. if (ex is NotReadyException) {
  203. if (timeout >= _readHeaderTimeout) {
  204. throw ReadTimeoutException();
  205. }
  206. await Future.delayed(delayDuration);
  207. timeout += delayDuration.inMilliseconds;
  208. } else {
  209. rethrow;
  210. }
  211. }
  212. }
  213. throw AlreadyClosedException();
  214. }
  215. /// Get one image from the vid.
  216. Future<VidUsImage> getImage(int index) async {
  217. if (index >= _imageCount || index < 0) {
  218. throw Exception("Can not find image Data");
  219. }
  220. //Jump to image.
  221. var timeout = 0;
  222. while (!_closed) {
  223. try {
  224. var imageData = _reader.readBytes(_imagePositionList[index]);
  225. return VidUsImage.fromBytes(imageData);
  226. } catch (ex) {
  227. if (ex is NotReadyException) {
  228. if (timeout >= _readImageTimeout) {
  229. throw ReadTimeoutException();
  230. }
  231. await Future.delayed(delayDuration);
  232. timeout += delayDuration.inMilliseconds;
  233. } else {
  234. rethrow;
  235. }
  236. }
  237. }
  238. throw AlreadyClosedException();
  239. }
  240. }