vid_data.dart 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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. final String 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(String url, {DownloadCallback? downloadCallback}) {
  41. _initialized = false;
  42. _closed = false;
  43. createReader(url, downloadCallback: downloadCallback);
  44. }
  45. @protected
  46. AsyncVidDataReaderBase createReader(String url,
  47. {DownloadCallback? downloadCallback});
  48. ///Get the downloaded data of this HttpVidUsImageData
  49. Uint8List getDownloadedData() {
  50. return _reader.toBytes();
  51. }
  52. ///Initialize the HttpVidUsImageData, must be called firstly.
  53. Future initialize() async {
  54. if (!_initialized) {
  55. var header = await _readHeader();
  56. if (header != header) {
  57. throw Exception("The input data is not a VID data.");
  58. }
  59. _version = await _readVersion();
  60. //Get probe info
  61. _probe = await _readProbe();
  62. _imageFormat = await _readImageFormat();
  63. _extendedData = await _readExtendedData();
  64. _imagePositionList = [];
  65. var imagePositionListData = await _readImagePositionListData();
  66. _imageCount = imagePositionListData.length ~/ 8;
  67. var imagePositionReader = VidUsDataReader(imagePositionListData);
  68. for (var i = 0; i < _imageCount; i++) {
  69. _imagePositionList.add(imagePositionReader.readInt64V2());
  70. }
  71. _initialized = true;
  72. }
  73. }
  74. ///Close the HttpVidUsImageData, it will force close the download operation and reading operation.
  75. void close() {
  76. _closed = true;
  77. _reader.close();
  78. }
  79. @protected
  80. T getReader<T extends AsyncVidDataReaderBase>() => _reader as T;
  81. ///Read header from http data.
  82. Future<String> _readHeader() async {
  83. var timeout = 0;
  84. while (!_closed) {
  85. try {
  86. var header = _reader.readString();
  87. return header;
  88. } catch (ex) {
  89. if (ex is NotReadyException) {
  90. if (timeout >= _readHeaderTimeout) {
  91. throw ReadTimeoutException();
  92. }
  93. await Future.delayed(delayDuration);
  94. timeout += delayDuration.inMilliseconds;
  95. } else {
  96. rethrow;
  97. }
  98. }
  99. }
  100. throw AlreadyClosedException();
  101. }
  102. ///Read the version from http data.
  103. Future<int> _readVersion() async {
  104. var timeout = 0;
  105. while (!_closed) {
  106. try {
  107. var version = _reader.readInt();
  108. return version;
  109. } catch (ex) {
  110. if (ex is NotReadyException) {
  111. if (timeout >= _readHeaderTimeout) {
  112. throw ReadTimeoutException();
  113. }
  114. await Future.delayed(delayDuration);
  115. timeout += delayDuration.inMilliseconds;
  116. } else {
  117. rethrow;
  118. }
  119. }
  120. }
  121. throw AlreadyClosedException();
  122. }
  123. ///Read the probe info from http data.
  124. Future<VidUsProbe> _readProbe() async {
  125. var timeout = 0;
  126. while (!_closed) {
  127. try {
  128. var probeData = _reader.readBytes();
  129. return VidUsProbe.fromBytes(probeData);
  130. } catch (ex) {
  131. if (ex is NotReadyException) {
  132. if (timeout >= _readHeaderTimeout) {
  133. throw ReadTimeoutException();
  134. }
  135. await Future.delayed(delayDuration);
  136. timeout += delayDuration.inMilliseconds;
  137. } else {
  138. rethrow;
  139. }
  140. }
  141. }
  142. throw AlreadyClosedException();
  143. }
  144. ///Read the image format from http data.
  145. Future<VidUsImageFormat> _readImageFormat() async {
  146. var timeout = 0;
  147. while (!_closed) {
  148. try {
  149. return VidUsImageFormat.values[_reader.readInt()];
  150. } catch (ex) {
  151. if (ex is NotReadyException) {
  152. if (timeout >= _readHeaderTimeout) {
  153. throw ReadTimeoutException();
  154. }
  155. await Future.delayed(delayDuration);
  156. timeout += delayDuration.inMilliseconds;
  157. } else {
  158. rethrow;
  159. }
  160. }
  161. }
  162. throw AlreadyClosedException();
  163. }
  164. ///Read extended data from http data.
  165. Future<Uint8List> _readExtendedData() async {
  166. var timeout = 0;
  167. while (!_closed) {
  168. try {
  169. return _reader.readBytes();
  170. } catch (ex) {
  171. if (ex is NotReadyException) {
  172. if (timeout >= _readHeaderTimeout) {
  173. throw ReadTimeoutException();
  174. }
  175. await Future.delayed(delayDuration);
  176. timeout += delayDuration.inMilliseconds;
  177. } else {
  178. rethrow;
  179. }
  180. }
  181. }
  182. throw AlreadyClosedException();
  183. }
  184. ///Read the image positions data from http data.
  185. Future<Uint8List> _readImagePositionListData() async {
  186. var timeout = 0;
  187. while (!_closed) {
  188. try {
  189. return _reader.readBytes();
  190. } catch (ex) {
  191. if (ex is NotReadyException) {
  192. if (timeout >= _readHeaderTimeout) {
  193. throw ReadTimeoutException();
  194. }
  195. await Future.delayed(delayDuration);
  196. timeout += delayDuration.inMilliseconds;
  197. } else {
  198. rethrow;
  199. }
  200. }
  201. }
  202. throw AlreadyClosedException();
  203. }
  204. /// Get one image from the vid.
  205. Future<VidUsImage> getImage(int index) async {
  206. if (index >= _imageCount || index < 0) {
  207. throw Exception("Can not find image Data");
  208. }
  209. //Jump to image.
  210. var timeout = 0;
  211. while (!_closed) {
  212. try {
  213. var imageData = _reader.readBytes(_imagePositionList[index]);
  214. return VidUsImage.fromBytes(imageData);
  215. } catch (ex) {
  216. if (ex is NotReadyException) {
  217. if (timeout >= _readImageTimeout) {
  218. throw ReadTimeoutException();
  219. }
  220. await Future.delayed(delayDuration);
  221. timeout += delayDuration.inMilliseconds;
  222. } else {
  223. rethrow;
  224. }
  225. }
  226. }
  227. throw AlreadyClosedException();
  228. }
  229. }