seekable_stream_decoder.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:41k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* libOggFLAC - Free Lossless Audio Codec + Ogg library
  2.  * Copyright (C) 2002,2003,2004,2005  Josh Coalson
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * - Redistributions of source code must retain the above copyright
  9.  * notice, this list of conditions and the following disclaimer.
  10.  *
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  * notice, this list of conditions and the following disclaimer in the
  13.  * documentation and/or other materials provided with the distribution.
  14.  *
  15.  * - Neither the name of the Xiph.org Foundation nor the names of its
  16.  * contributors may be used to endorse or promote products derived from
  17.  * this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20.  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22.  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
  23.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  27.  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  28.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.  */
  31. #include <stdio.h>
  32. #include <stdlib.h> /* for calloc() */
  33. #include <string.h> /* for memcpy()/memcmp() */
  34. #include "FLAC/assert.h"
  35. #include "protected/seekable_stream_decoder.h"
  36. #include "protected/stream_decoder.h"
  37. #include "../libFLAC/include/private/float.h" /* @@@ ugly hack, but how else to do?  we need to reuse the float formats but don't want to expose it */
  38. #include "../libFLAC/include/private/md5.h" /* @@@ ugly hack, but how else to do?  we need to reuse the md5 code but don't want to expose it */
  39. /***********************************************************************
  40.  *
  41.  * Private class method prototypes
  42.  *
  43.  ***********************************************************************/
  44. static void set_defaults_(OggFLAC__SeekableStreamDecoder *decoder);
  45. static FLAC__StreamDecoderReadStatus read_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
  46. static FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
  47. static void metadata_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
  48. static void error_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
  49. static FLAC__bool seek_to_absolute_sample_(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
  50. /***********************************************************************
  51.  *
  52.  * Private class data
  53.  *
  54.  ***********************************************************************/
  55. typedef struct OggFLAC__SeekableStreamDecoderPrivate {
  56. OggFLAC__SeekableStreamDecoderReadCallback read_callback;
  57. OggFLAC__SeekableStreamDecoderSeekCallback seek_callback;
  58. OggFLAC__SeekableStreamDecoderTellCallback tell_callback;
  59. OggFLAC__SeekableStreamDecoderLengthCallback length_callback;
  60. OggFLAC__SeekableStreamDecoderEofCallback eof_callback;
  61. OggFLAC__SeekableStreamDecoderWriteCallback write_callback;
  62. OggFLAC__SeekableStreamDecoderMetadataCallback metadata_callback;
  63. OggFLAC__SeekableStreamDecoderErrorCallback error_callback;
  64. void *client_data;
  65. OggFLAC__StreamDecoder *stream_decoder;
  66. FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek */
  67. struct FLAC__MD5Context md5context;
  68. FLAC__byte stored_md5sum[16]; /* this is what is stored in the metadata */
  69. FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */
  70. /* the rest of these are only used for seeking: */
  71. FLAC__StreamMetadata_StreamInfo stream_info; /* we keep this around so we can figure out how to seek quickly */
  72. const FLAC__StreamMetadata_SeekTable *seek_table; /* we hold a pointer to the stream decoder's seek table for the same reason */
  73. /* Since we always want to see the STREAMINFO and SEEK_TABLE blocks at this level, we need some extra flags to keep track of whether they should be passed on up through the metadata_callback */
  74. FLAC__bool ignore_stream_info_block;
  75. FLAC__bool ignore_seek_table_block;
  76. FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */
  77. FLAC__uint64 target_sample;
  78. FLAC__bool got_a_frame; /* hack needed in seek routine to check when process_single() actually writes a frame */
  79. } OggFLAC__SeekableStreamDecoderPrivate;
  80. /***********************************************************************
  81.  *
  82.  * Public static class data
  83.  *
  84.  ***********************************************************************/
  85. OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderStateString[] = {
  86. "OggFLAC__SEEKABLE_STREAM_DECODER_OK",
  87. "OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING",
  88. "OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM",
  89. "OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
  90. "OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR",
  91. "OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR",
  92. "OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR",
  93. "OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED",
  94. "OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK",
  95. "OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED"
  96. };
  97. OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderReadStatusString[] = {
  98. "OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK",
  99. "OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR"
  100. };
  101. OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderSeekStatusString[] = {
  102. "OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK",
  103. "OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR"
  104. };
  105. OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderTellStatusString[] = {
  106. "OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK",
  107. "OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR"
  108. };
  109. OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderLengthStatusString[] = {
  110. "OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK",
  111. "OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR"
  112. };
  113. /***********************************************************************
  114.  *
  115.  * Class constructor/destructor
  116.  *
  117.  ***********************************************************************/
  118. OggFLAC_API OggFLAC__SeekableStreamDecoder *OggFLAC__seekable_stream_decoder_new()
  119. {
  120. OggFLAC__SeekableStreamDecoder *decoder;
  121. FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
  122. decoder = (OggFLAC__SeekableStreamDecoder*)calloc(1, sizeof(OggFLAC__SeekableStreamDecoder));
  123. if(decoder == 0) {
  124. return 0;
  125. }
  126. decoder->protected_ = (OggFLAC__SeekableStreamDecoderProtected*)calloc(1, sizeof(OggFLAC__SeekableStreamDecoderProtected));
  127. if(decoder->protected_ == 0) {
  128. free(decoder);
  129. return 0;
  130. }
  131. decoder->private_ = (OggFLAC__SeekableStreamDecoderPrivate*)calloc(1, sizeof(OggFLAC__SeekableStreamDecoderPrivate));
  132. if(decoder->private_ == 0) {
  133. free(decoder->protected_);
  134. free(decoder);
  135. return 0;
  136. }
  137. decoder->private_->stream_decoder = OggFLAC__stream_decoder_new();
  138. if(0 == decoder->private_->stream_decoder) {
  139. free(decoder->private_);
  140. free(decoder->protected_);
  141. free(decoder);
  142. return 0;
  143. }
  144. set_defaults_(decoder);
  145. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
  146. return decoder;
  147. }
  148. OggFLAC_API void OggFLAC__seekable_stream_decoder_delete(OggFLAC__SeekableStreamDecoder *decoder)
  149. {
  150. FLAC__ASSERT(0 != decoder);
  151. FLAC__ASSERT(0 != decoder->protected_);
  152. FLAC__ASSERT(0 != decoder->private_);
  153. FLAC__ASSERT(0 != decoder->private_->stream_decoder);
  154. (void)OggFLAC__seekable_stream_decoder_finish(decoder);
  155. OggFLAC__stream_decoder_delete(decoder->private_->stream_decoder);
  156. free(decoder->private_);
  157. free(decoder->protected_);
  158. free(decoder);
  159. }
  160. /***********************************************************************
  161.  *
  162.  * Public class methods
  163.  *
  164.  ***********************************************************************/
  165. OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_init(OggFLAC__SeekableStreamDecoder *decoder)
  166. {
  167. FLAC__ASSERT(0 != decoder);
  168. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  169. return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED;
  170. if(0 == decoder->private_->read_callback || 0 == decoder->private_->seek_callback || 0 == decoder->private_->tell_callback || 0 == decoder->private_->length_callback || 0 == decoder->private_->eof_callback)
  171. return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
  172. if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
  173. return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
  174. decoder->private_->seek_table = 0;
  175. decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
  176. /* We initialize the FLAC__MD5Context even though we may never use it.  This
  177.  * is because md5 checking may be turned on to start and then turned off if
  178.  * a seek occurs.  So we always init the context here and finalize it in
  179.  * OggFLAC__seekable_stream_decoder_finish() to make sure things are always
  180.  * cleaned up properly.
  181.  */
  182. FLAC__MD5Init(&decoder->private_->md5context);
  183. OggFLAC__stream_decoder_set_read_callback(decoder->private_->stream_decoder, read_callback_);
  184. OggFLAC__stream_decoder_set_write_callback(decoder->private_->stream_decoder, write_callback_);
  185. OggFLAC__stream_decoder_set_metadata_callback(decoder->private_->stream_decoder, metadata_callback_);
  186. OggFLAC__stream_decoder_set_error_callback(decoder->private_->stream_decoder, error_callback_);
  187. OggFLAC__stream_decoder_set_client_data(decoder->private_->stream_decoder, decoder);
  188. /* We always want to see these blocks.  Whether or not we pass them up
  189.  * through the metadata callback will be determined by flags set in our
  190.  * implementation of ..._set_metadata_respond/ignore...()
  191.  */
  192. OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO);
  193. OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
  194. if(OggFLAC__stream_decoder_init(decoder->private_->stream_decoder) != OggFLAC__STREAM_DECODER_OK)
  195. return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
  196. return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
  197. }
  198. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_finish(OggFLAC__SeekableStreamDecoder *decoder)
  199. {
  200. FLAC__bool md5_failed = false;
  201. FLAC__ASSERT(0 != decoder);
  202. FLAC__ASSERT(0 != decoder->private_);
  203. FLAC__ASSERT(0 != decoder->protected_);
  204. if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  205. return true;
  206. FLAC__ASSERT(0 != decoder->private_->stream_decoder);
  207. /* see the comment in OggFLAC__seekable_stream_decoder_init() as to why we
  208.  * always call FLAC__MD5Final()
  209.  */
  210. FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
  211. OggFLAC__stream_decoder_finish(decoder->private_->stream_decoder);
  212. if(decoder->private_->do_md5_checking) {
  213. if(memcmp(decoder->private_->stored_md5sum, decoder->private_->computed_md5sum, 16))
  214. md5_failed = true;
  215. }
  216. set_defaults_(decoder);
  217. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
  218. return !md5_failed;
  219. }
  220. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_md5_checking(OggFLAC__SeekableStreamDecoder *decoder, FLAC__bool value)
  221. {
  222. FLAC__ASSERT(0 != decoder);
  223. FLAC__ASSERT(0 != decoder->protected_);
  224. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  225. return false;
  226. decoder->protected_->md5_checking = value;
  227. return true;
  228. }
  229. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_read_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderReadCallback value)
  230. {
  231. FLAC__ASSERT(0 != decoder);
  232. FLAC__ASSERT(0 != decoder->private_);
  233. FLAC__ASSERT(0 != decoder->protected_);
  234. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  235. return false;
  236. decoder->private_->read_callback = value;
  237. return true;
  238. }
  239. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_seek_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderSeekCallback value)
  240. {
  241. FLAC__ASSERT(0 != decoder);
  242. FLAC__ASSERT(0 != decoder->private_);
  243. FLAC__ASSERT(0 != decoder->protected_);
  244. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  245. return false;
  246. decoder->private_->seek_callback = value;
  247. return true;
  248. }
  249. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_tell_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderTellCallback value)
  250. {
  251. FLAC__ASSERT(0 != decoder);
  252. FLAC__ASSERT(0 != decoder->private_);
  253. FLAC__ASSERT(0 != decoder->protected_);
  254. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  255. return false;
  256. decoder->private_->tell_callback = value;
  257. return true;
  258. }
  259. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_length_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderLengthCallback value)
  260. {
  261. FLAC__ASSERT(0 != decoder);
  262. FLAC__ASSERT(0 != decoder->private_);
  263. FLAC__ASSERT(0 != decoder->protected_);
  264. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  265. return false;
  266. decoder->private_->length_callback = value;
  267. return true;
  268. }
  269. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_eof_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderEofCallback value)
  270. {
  271. FLAC__ASSERT(0 != decoder);
  272. FLAC__ASSERT(0 != decoder->private_);
  273. FLAC__ASSERT(0 != decoder->protected_);
  274. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  275. return false;
  276. decoder->private_->eof_callback = value;
  277. return true;
  278. }
  279. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_write_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderWriteCallback value)
  280. {
  281. FLAC__ASSERT(0 != decoder);
  282. FLAC__ASSERT(0 != decoder->private_);
  283. FLAC__ASSERT(0 != decoder->protected_);
  284. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  285. return false;
  286. decoder->private_->write_callback = value;
  287. return true;
  288. }
  289. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderMetadataCallback value)
  290. {
  291. FLAC__ASSERT(0 != decoder);
  292. FLAC__ASSERT(0 != decoder->private_);
  293. FLAC__ASSERT(0 != decoder->protected_);
  294. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  295. return false;
  296. decoder->private_->metadata_callback = value;
  297. return true;
  298. }
  299. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_error_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderErrorCallback value)
  300. {
  301. FLAC__ASSERT(0 != decoder);
  302. FLAC__ASSERT(0 != decoder->private_);
  303. FLAC__ASSERT(0 != decoder->protected_);
  304. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  305. return false;
  306. decoder->private_->error_callback = value;
  307. return true;
  308. }
  309. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_client_data(OggFLAC__SeekableStreamDecoder *decoder, void *value)
  310. {
  311. FLAC__ASSERT(0 != decoder);
  312. FLAC__ASSERT(0 != decoder->private_);
  313. FLAC__ASSERT(0 != decoder->protected_);
  314. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  315. return false;
  316. decoder->private_->client_data = value;
  317. return true;
  318. }
  319. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_serial_number(OggFLAC__SeekableStreamDecoder *decoder, long value)
  320. {
  321. FLAC__ASSERT(0 != decoder);
  322. FLAC__ASSERT(0 != decoder->private_);
  323. FLAC__ASSERT(0 != decoder->protected_);
  324. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  325. return false;
  326. OggFLAC__stream_decoder_set_serial_number(decoder->private_->stream_decoder, value);
  327. return true;
  328. }
  329. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond(OggFLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
  330. {
  331. FLAC__ASSERT(0 != decoder);
  332. FLAC__ASSERT(0 != decoder->private_);
  333. FLAC__ASSERT(0 != decoder->protected_);
  334. FLAC__ASSERT(0 != decoder->private_->stream_decoder);
  335. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  336. return false;
  337. if(type == FLAC__METADATA_TYPE_STREAMINFO)
  338. decoder->private_->ignore_stream_info_block = false;
  339. else if(type == FLAC__METADATA_TYPE_SEEKTABLE)
  340. decoder->private_->ignore_seek_table_block = false;
  341. return OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, type);
  342. }
  343. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond_application(OggFLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
  344. {
  345. FLAC__ASSERT(0 != decoder);
  346. FLAC__ASSERT(0 != decoder->private_);
  347. FLAC__ASSERT(0 != decoder->protected_);
  348. FLAC__ASSERT(0 != decoder->private_->stream_decoder);
  349. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  350. return false;
  351. return OggFLAC__stream_decoder_set_metadata_respond_application(decoder->private_->stream_decoder, id);
  352. }
  353. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond_all(OggFLAC__SeekableStreamDecoder *decoder)
  354. {
  355. FLAC__ASSERT(0 != decoder);
  356. FLAC__ASSERT(0 != decoder->private_);
  357. FLAC__ASSERT(0 != decoder->protected_);
  358. FLAC__ASSERT(0 != decoder->private_->stream_decoder);
  359. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  360. return false;
  361. decoder->private_->ignore_stream_info_block = false;
  362. decoder->private_->ignore_seek_table_block = false;
  363. return OggFLAC__stream_decoder_set_metadata_respond_all(decoder->private_->stream_decoder);
  364. }
  365. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore(OggFLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
  366. {
  367. FLAC__ASSERT(0 != decoder);
  368. FLAC__ASSERT(0 != decoder->private_);
  369. FLAC__ASSERT(0 != decoder->protected_);
  370. FLAC__ASSERT(0 != decoder->private_->stream_decoder);
  371. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  372. return false;
  373. if(type == FLAC__METADATA_TYPE_STREAMINFO) {
  374. decoder->private_->ignore_stream_info_block = true;
  375. return true;
  376. }
  377. else if(type == FLAC__METADATA_TYPE_SEEKTABLE) {
  378. decoder->private_->ignore_seek_table_block = true;
  379. return true;
  380. }
  381. else
  382. return OggFLAC__stream_decoder_set_metadata_ignore(decoder->private_->stream_decoder, type);
  383. }
  384. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_application(OggFLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
  385. {
  386. FLAC__ASSERT(0 != decoder);
  387. FLAC__ASSERT(0 != decoder->private_);
  388. FLAC__ASSERT(0 != decoder->protected_);
  389. FLAC__ASSERT(0 != decoder->private_->stream_decoder);
  390. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  391. return false;
  392. return OggFLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->stream_decoder, id);
  393. }
  394. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_all(OggFLAC__SeekableStreamDecoder *decoder)
  395. {
  396. FLAC__ASSERT(0 != decoder);
  397. FLAC__ASSERT(0 != decoder->private_);
  398. FLAC__ASSERT(0 != decoder->protected_);
  399. FLAC__ASSERT(0 != decoder->private_->stream_decoder);
  400. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
  401. return false;
  402. decoder->private_->ignore_stream_info_block = true;
  403. decoder->private_->ignore_seek_table_block = true;
  404. return
  405. OggFLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->stream_decoder) &&
  406. OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO) &&
  407. OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
  408. }
  409. OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_state(const OggFLAC__SeekableStreamDecoder *decoder)
  410. {
  411. FLAC__ASSERT(0 != decoder);
  412. FLAC__ASSERT(0 != decoder->protected_);
  413. return decoder->protected_->state;
  414. }
  415. OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__seekable_stream_decoder_get_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder)
  416. {
  417. FLAC__ASSERT(0 != decoder);
  418. FLAC__ASSERT(0 != decoder->private_);
  419. return OggFLAC__stream_decoder_get_state(decoder->private_->stream_decoder);
  420. }
  421. OggFLAC_API FLAC__StreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder)
  422. {
  423. FLAC__ASSERT(0 != decoder);
  424. FLAC__ASSERT(0 != decoder->private_);
  425. return OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder->private_->stream_decoder);
  426. }
  427. OggFLAC_API const char *OggFLAC__seekable_stream_decoder_get_resolved_state_string(const OggFLAC__SeekableStreamDecoder *decoder)
  428. {
  429. if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR)
  430. return OggFLAC__SeekableStreamDecoderStateString[decoder->protected_->state];
  431. else
  432. return OggFLAC__stream_decoder_get_resolved_state_string(decoder->private_->stream_decoder);
  433. }
  434. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_get_md5_checking(const OggFLAC__SeekableStreamDecoder *decoder)
  435. {
  436. FLAC__ASSERT(0 != decoder);
  437. FLAC__ASSERT(0 != decoder->protected_);
  438. return decoder->protected_->md5_checking;
  439. }
  440. OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_channels(const OggFLAC__SeekableStreamDecoder *decoder)
  441. {
  442. FLAC__ASSERT(0 != decoder);
  443. FLAC__ASSERT(0 != decoder->private_);
  444. return OggFLAC__stream_decoder_get_channels(decoder->private_->stream_decoder);
  445. }
  446. OggFLAC_API FLAC__ChannelAssignment OggFLAC__seekable_stream_decoder_get_channel_assignment(const OggFLAC__SeekableStreamDecoder *decoder)
  447. {
  448. FLAC__ASSERT(0 != decoder);
  449. FLAC__ASSERT(0 != decoder->private_);
  450. return OggFLAC__stream_decoder_get_channel_assignment(decoder->private_->stream_decoder);
  451. }
  452. OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_bits_per_sample(const OggFLAC__SeekableStreamDecoder *decoder)
  453. {
  454. FLAC__ASSERT(0 != decoder);
  455. FLAC__ASSERT(0 != decoder->private_);
  456. return OggFLAC__stream_decoder_get_bits_per_sample(decoder->private_->stream_decoder);
  457. }
  458. OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_sample_rate(const OggFLAC__SeekableStreamDecoder *decoder)
  459. {
  460. FLAC__ASSERT(0 != decoder);
  461. FLAC__ASSERT(0 != decoder->private_);
  462. return OggFLAC__stream_decoder_get_sample_rate(decoder->private_->stream_decoder);
  463. }
  464. OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_blocksize(const OggFLAC__SeekableStreamDecoder *decoder)
  465. {
  466. FLAC__ASSERT(0 != decoder);
  467. FLAC__ASSERT(0 != decoder->private_);
  468. return OggFLAC__stream_decoder_get_blocksize(decoder->private_->stream_decoder);
  469. }
  470. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_flush(OggFLAC__SeekableStreamDecoder *decoder)
  471. {
  472. FLAC__ASSERT(0 != decoder);
  473. FLAC__ASSERT(0 != decoder->private_);
  474. FLAC__ASSERT(0 != decoder->protected_);
  475. decoder->private_->do_md5_checking = false;
  476. if(!OggFLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
  477. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
  478. return false;
  479. }
  480. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
  481. return true;
  482. }
  483. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_reset(OggFLAC__SeekableStreamDecoder *decoder)
  484. {
  485. FLAC__ASSERT(0 != decoder);
  486. FLAC__ASSERT(0 != decoder->private_);
  487. FLAC__ASSERT(0 != decoder->protected_);
  488. if(!OggFLAC__seekable_stream_decoder_flush(decoder)) {
  489. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
  490. return false;
  491. }
  492. if(!OggFLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
  493. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
  494. return false;
  495. }
  496. decoder->private_->seek_table = 0;
  497. decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
  498. /* We initialize the FLAC__MD5Context even though we may never use it.  This
  499.  * is because md5 checking may be turned on to start and then turned off if
  500.  * a seek occurs.  So we always init the context here and finalize it in
  501.  * OggFLAC__seekable_stream_decoder_finish() to make sure things are always
  502.  * cleaned up properly.
  503.  */
  504. FLAC__MD5Init(&decoder->private_->md5context);
  505. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
  506. return true;
  507. }
  508. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_single(OggFLAC__SeekableStreamDecoder *decoder)
  509. {
  510. FLAC__bool ret;
  511. FLAC__ASSERT(0 != decoder);
  512. if(decoder->private_->stream_decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
  513. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
  514. if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
  515. return true;
  516. FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
  517. ret = OggFLAC__stream_decoder_process_single(decoder->private_->stream_decoder);
  518. if(!ret)
  519. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
  520. return ret;
  521. }
  522. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_until_end_of_metadata(OggFLAC__SeekableStreamDecoder *decoder)
  523. {
  524. FLAC__bool ret;
  525. FLAC__ASSERT(0 != decoder);
  526. if(decoder->private_->stream_decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
  527. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
  528. if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
  529. return true;
  530. FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
  531. ret = OggFLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder);
  532. if(!ret)
  533. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
  534. return ret;
  535. }
  536. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_until_end_of_stream(OggFLAC__SeekableStreamDecoder *decoder)
  537. {
  538. FLAC__bool ret;
  539. FLAC__ASSERT(0 != decoder);
  540. if(decoder->private_->stream_decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
  541. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
  542. if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
  543. return true;
  544. FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
  545. ret = OggFLAC__stream_decoder_process_until_end_of_stream(decoder->private_->stream_decoder);
  546. if(!ret)
  547. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
  548. return ret;
  549. }
  550. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_seek_absolute(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 sample)
  551. {
  552. FLAC__uint64 length;
  553. FLAC__ASSERT(0 != decoder);
  554. FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK || decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM);
  555. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING;
  556. /* turn off md5 checking if a seek is attempted */
  557. decoder->private_->do_md5_checking = false;
  558. if(!OggFLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
  559. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
  560. return false;
  561. }
  562. /* get the file length */
  563. if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK) {
  564. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
  565. return false;
  566. }
  567. /* rewind */
  568. if(decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
  569. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
  570. return false;
  571. }
  572. if(!OggFLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder)) {
  573. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
  574. return false;
  575. }
  576. if(decoder->private_->stream_info.total_samples > 0 && sample >= decoder->private_->stream_info.total_samples) {
  577. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
  578. return false;
  579. }
  580. return seek_to_absolute_sample_(decoder, length, sample);
  581. }
  582. /***********************************************************************
  583.  *
  584.  * Private class methods
  585.  *
  586.  ***********************************************************************/
  587. void set_defaults_(OggFLAC__SeekableStreamDecoder *decoder)
  588. {
  589. decoder->private_->read_callback = 0;
  590. decoder->private_->seek_callback = 0;
  591. decoder->private_->tell_callback = 0;
  592. decoder->private_->length_callback = 0;
  593. decoder->private_->eof_callback = 0;
  594. decoder->private_->write_callback = 0;
  595. decoder->private_->metadata_callback = 0;
  596. decoder->private_->error_callback = 0;
  597. decoder->private_->client_data = 0;
  598. /* WATCHOUT: these should match the default behavior of OggFLAC__StreamDecoder */
  599. decoder->private_->ignore_stream_info_block = false;
  600. decoder->private_->ignore_seek_table_block = true;
  601. decoder->protected_->md5_checking = false;
  602. }
  603. FLAC__StreamDecoderReadStatus read_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
  604. {
  605. OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
  606. (void)decoder;
  607. if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
  608. *bytes = 0;
  609. #if 0
  610. /*@@@@@@ we used to do this: */
  611. seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
  612. /* but it causes a problem because the Ogg decoding layer reads as much as it can to get pages, so the state will get to end-of-stream before the bitbuffer does */
  613. #endif
  614. return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
  615. }
  616. else if(*bytes > 0) {
  617. if(seekable_stream_decoder->private_->read_callback(seekable_stream_decoder, buffer, bytes, seekable_stream_decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK) {
  618. seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR;
  619. return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
  620. }
  621. if(*bytes == 0) {
  622. if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
  623. #if 0
  624. /*@@@@@@ we used to do this: */
  625. seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
  626. /* but it causes a problem because the Ogg decoding layer reads as much as it can to get pages, so the state will get to end-of-stream before the bitbuffer does */
  627. #endif
  628. return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
  629. }
  630. else
  631. return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
  632. }
  633. else {
  634. return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
  635. }
  636. }
  637. else
  638. return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
  639. }
  640. FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
  641. {
  642. OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
  643. (void)decoder;
  644. if(seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
  645. FLAC__uint64 this_frame_sample = frame->header.number.sample_number;
  646. FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize;
  647. FLAC__uint64 target_sample = seekable_stream_decoder->private_->target_sample;
  648. FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
  649. seekable_stream_decoder->private_->got_a_frame = true;
  650. seekable_stream_decoder->private_->last_frame = *frame; /* save the frame */
  651. if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */
  652. unsigned delta = (unsigned)(target_sample - this_frame_sample);
  653. /* kick out of seek mode */
  654. seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
  655. /* shift out the samples before target_sample */
  656. if(delta > 0) {
  657. unsigned channel;
  658. const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS];
  659. for(channel = 0; channel < frame->header.channels; channel++)
  660. newbuffer[channel] = buffer[channel] + delta;
  661. seekable_stream_decoder->private_->last_frame.header.blocksize -= delta;
  662. seekable_stream_decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta;
  663. /* write the relevant samples */
  664. return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, &seekable_stream_decoder->private_->last_frame, newbuffer, seekable_stream_decoder->private_->client_data);
  665. }
  666. else {
  667. /* write the relevant samples */
  668. return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
  669. }
  670. }
  671. else {
  672. return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
  673. }
  674. }
  675. else {
  676. if(seekable_stream_decoder->private_->do_md5_checking) {
  677. if(!FLAC__MD5Accumulate(&seekable_stream_decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
  678. return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
  679. }
  680. return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
  681. }
  682. }
  683. void metadata_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
  684. {
  685. OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
  686. (void)decoder;
  687. if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
  688. seekable_stream_decoder->private_->stream_info = metadata->data.stream_info;
  689. /* save the MD5 signature for comparison later */
  690. memcpy(seekable_stream_decoder->private_->stored_md5sum, metadata->data.stream_info.md5sum, 16);
  691. if(0 == memcmp(seekable_stream_decoder->private_->stored_md5sum, "", 16))
  692. seekable_stream_decoder->private_->do_md5_checking = false;
  693. }
  694. else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE) {
  695. seekable_stream_decoder->private_->seek_table = &metadata->data.seek_table;
  696. }
  697. if(seekable_stream_decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
  698. FLAC__bool ignore_block = false;
  699. if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO && seekable_stream_decoder->private_->ignore_stream_info_block)
  700. ignore_block = true;
  701. else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE && seekable_stream_decoder->private_->ignore_seek_table_block)
  702. ignore_block = true;
  703. if(!ignore_block)
  704. seekable_stream_decoder->private_->metadata_callback(seekable_stream_decoder, metadata, seekable_stream_decoder->private_->client_data);
  705. }
  706. }
  707. void error_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
  708. {
  709. OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
  710. (void)decoder;
  711. if(seekable_stream_decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING)
  712. seekable_stream_decoder->private_->error_callback(seekable_stream_decoder, status, seekable_stream_decoder->private_->client_data);
  713. }
  714. FLAC__bool seek_to_absolute_sample_(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
  715. {
  716. FLAC__uint64 left_pos = 0, right_pos = stream_length;
  717. FLAC__uint64 left_sample = 0, right_sample = decoder->private_->stream_info.total_samples;
  718. FLAC__uint64 this_frame_sample = 0; /* only initialized to avoid compiler warning */
  719. FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */
  720. FLAC__bool did_a_seek;
  721. unsigned iteration = 0;
  722. /* In the first iterations, we will calculate the target byte position 
  723.  * by the distance from the target sample to left_sample and
  724.  * right_sample (let's call it "proportional search").  After that, we
  725.  * will switch to binary search.
  726.  */
  727. unsigned BINARY_SEARCH_AFTER_ITERATION = 2;
  728. /* We will switch to a linear search once our current sample is less
  729.  * that this number of samples ahead of the target sample
  730.  */
  731. static const FLAC__uint64 LINEAR_SEARCH_WITHIN_SAMPLES = FLAC__MAX_BLOCK_SIZE * 2;
  732. /* If the total number of samples is unknown, use a large value and
  733.  * increase 'iteration' to force binary search immediately.
  734.  */
  735. if(right_sample == 0) {
  736. right_sample = (FLAC__uint64)(-1);
  737. BINARY_SEARCH_AFTER_ITERATION = 0;
  738. }
  739. decoder->private_->target_sample = target_sample;
  740. for( ; ; iteration++) {
  741. if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) {
  742. if (iteration >= BINARY_SEARCH_AFTER_ITERATION) {
  743. pos = (right_pos + left_pos) / 2;
  744. }
  745. else {
  746. #ifndef FLAC__INTEGER_ONLY_LIBRARY
  747. #if defined _MSC_VER || defined __MINGW32__
  748. /* with MSVC you have to spoon feed it the casting */
  749. pos = (FLAC__uint64)((FLAC__double)(FLAC__int64)(target_sample - left_sample) / (FLAC__double)(FLAC__int64)(right_sample - left_sample) * (FLAC__double)(FLAC__int64)(right_pos - left_pos));
  750. #else
  751. pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos));
  752. #endif
  753. #else
  754. /* a little less accurate: */
  755. if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff))
  756. pos = (FLAC__int64)(((target_sample-left_sample) * (right_pos-left_pos)) / (right_sample-left_sample));
  757. else /* @@@ WATCHOUT, ~2TB limit */
  758. pos = (FLAC__int64)((((target_sample-left_sample)>>8) * ((right_pos-left_pos)>>8)) / ((right_sample-left_sample)>>16));
  759. #endif
  760. /* @@@ TODO: might want to limit pos to some distance
  761.  * before EOF, to make sure we land before the last frame,
  762.  * thereby getting a this_fram_sample and so having a better
  763.  * estimate.  this would also mostly (or totally if we could
  764.  * be sure to land before the last frame) avoid the
  765.  * end-of-stream case we have to check later.
  766.  */
  767. }
  768. /* physical seek */
  769. if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
  770. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
  771. return false;
  772. }
  773. if(!OggFLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
  774. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
  775. return false;
  776. }
  777. did_a_seek = true;
  778. }
  779. else
  780. did_a_seek = false;
  781. decoder->private_->got_a_frame = false;
  782. if(!OggFLAC__stream_decoder_process_single(decoder->private_->stream_decoder)) {
  783. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
  784. return false;
  785. }
  786. if(!decoder->private_->got_a_frame) {
  787. if(did_a_seek) {
  788. /* this can happen if we seek to a point after the last frame; we drop
  789.  * to binary search right away in this case to avoid any wasted
  790.  * iterations of proportional search.
  791.  */
  792. right_pos = pos;
  793. BINARY_SEARCH_AFTER_ITERATION = 0;
  794. }
  795. else {
  796. /* this can probably only happen if total_samples is unknown and the
  797.  * target_sample is past the end of the stream
  798.  */
  799. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
  800. return false;
  801. }
  802. }
  803. /* our write callback will change the state when it gets to the target frame */
  804. else if(
  805. decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING &&
  806. decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM
  807. ) {
  808. break;
  809. }
  810. else {
  811. this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
  812. FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
  813. if (did_a_seek) {
  814. if (this_frame_sample <= target_sample) {
  815. /* The 'equal' case should not happen, since
  816.  * OggFLAC__stream_decoder_process_single()
  817.  * should recognize that it has hit the
  818.  * target sample and we would exit through
  819.  * the 'break' above.
  820.  */
  821. FLAC__ASSERT(this_frame_sample != target_sample);
  822. left_sample = this_frame_sample;
  823. /* sanity check to avoid infinite loop */
  824. if (left_pos == pos) {
  825. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
  826. return false;
  827. }
  828. left_pos = pos;
  829. }
  830. else if(this_frame_sample > target_sample) {
  831. right_sample = this_frame_sample;
  832. /* sanity check to avoid infinite loop */
  833. if (right_pos == pos) {
  834. decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
  835. return false;
  836. }
  837. right_pos = pos;
  838. }
  839. }
  840. }
  841. }
  842. return true;
  843. }