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

Windows CE

开发平台:

C/C++

  1. /* test_seeking - Seeking tester for libFLAC and libOggFLAC
  2.  * Copyright (C) 2004,2005  Josh Coalson
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21. #include <signal.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #if defined _MSC_VER || defined __MINGW32__
  26. #include <time.h>
  27. #else
  28. #include <sys/time.h>
  29. #endif
  30. #include <sys/stat.h> /* for stat() */
  31. #include "FLAC/assert.h"
  32. #include "FLAC/file_decoder.h"
  33. #ifdef FLAC__HAS_OGG
  34. #include "OggFLAC/file_decoder.h"
  35. #endif
  36. typedef struct {
  37. FLAC__bool got_data;
  38. FLAC__uint64 total_samples;
  39. unsigned channels;
  40. unsigned bits_per_sample;
  41. FLAC__bool ignore_errors;
  42. FLAC__bool error_occurred;
  43. } decoder_client_data_struct;
  44. static FLAC__bool stop_signal_ = false;
  45. static void our_sigint_handler_(int signal)
  46. {
  47. (void)signal;
  48. printf("(caught SIGINT) ");
  49. fflush(stdout);
  50. stop_signal_ = true;
  51. }
  52. static FLAC__bool die_(const char *msg)
  53. {
  54. printf("ERROR: %sn", msg);
  55. return false;
  56. }
  57. static FLAC__bool die_f_(const char *msg, const FLAC__FileDecoder *decoder)
  58. {
  59. FLAC__FileDecoderState state = FLAC__file_decoder_get_state(decoder);
  60. if(msg)
  61. printf("FAILED, %s", msg);
  62. else
  63. printf("FAILED");
  64. printf(", state = %u (%s)n", (unsigned)state, FLAC__FileDecoderStateString[state]);
  65. if(state == FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR) {
  66. FLAC__SeekableStreamDecoderState state_ = FLAC__file_decoder_get_seekable_stream_decoder_state(decoder);
  67. printf("      seekable stream decoder state = %u (%s)n", (unsigned)state, FLAC__SeekableStreamDecoderStateString[state_]);
  68. if(state_ == FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
  69. FLAC__StreamDecoderState state__ = FLAC__file_decoder_get_stream_decoder_state(decoder);
  70. printf("      stream decoder state = %u (%s)n", (unsigned)state__, FLAC__StreamDecoderStateString[state__]);
  71. }
  72. }
  73. return false;
  74. }
  75. #ifdef FLAC__HAS_OGG
  76. static FLAC__bool die_of_(const char *msg, const OggFLAC__FileDecoder *decoder)
  77. {
  78. OggFLAC__FileDecoderState state = OggFLAC__file_decoder_get_state(decoder);
  79. if(msg)
  80. printf("FAILED, %s", msg);
  81. else
  82. printf("FAILED");
  83. printf(", state = %u (%s)n", (unsigned)state, OggFLAC__SeekableStreamDecoderStateString[state]);
  84. if(state == OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR) {
  85. OggFLAC__SeekableStreamDecoderState state_ = OggFLAC__file_decoder_get_seekable_stream_decoder_state(decoder);
  86. printf("      seekable stream decoder state = %u (%s)n", (unsigned)state_, OggFLAC__SeekableStreamDecoderStateString[state_]);
  87. if(state_ == OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
  88. OggFLAC__StreamDecoderState state__ = OggFLAC__file_decoder_get_stream_decoder_state(decoder);
  89. printf("      stream decoder state = %u (%s)n", (unsigned)state__, OggFLAC__StreamDecoderStateString[state__]);
  90. if(state__ == OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
  91. FLAC__StreamDecoderState state___ = OggFLAC__file_decoder_get_FLAC_stream_decoder_state(decoder);
  92. printf("      FLAC stream decoder state = %u (%s)n", (unsigned)state___, FLAC__StreamDecoderStateString[state___]);
  93. }
  94. }
  95. }
  96. return false;
  97. }
  98. #endif
  99. static off_t get_filesize_(const char *srcpath)
  100. {
  101. struct stat srcstat;
  102. if(0 == stat(srcpath, &srcstat))
  103. return srcstat.st_size;
  104. else
  105. return -1;
  106. }
  107. static FLAC__StreamDecoderWriteStatus file_decoder_write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
  108. {
  109. decoder_client_data_struct *dcd = (decoder_client_data_struct*)client_data;
  110. (void)decoder, (void)buffer;
  111. if(0 == dcd) {
  112. printf("ERROR: client_data in write callback is NULLn");
  113. return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
  114. }
  115. if(dcd->error_occurred)
  116. return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
  117. if (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER)
  118. printf("frame@%uf(%u)... ", frame->header.number.frame_number, frame->header.blocksize);
  119. else if (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER)
  120. printf("frame@%llu(%u)... ", frame->header.number.sample_number, frame->header.blocksize);
  121. else {
  122. FLAC__ASSERT(0);
  123. dcd->error_occurred = true;
  124. return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
  125. }
  126. fflush(stdout);
  127. return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
  128. }
  129. static void file_decoder_metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
  130. {
  131. decoder_client_data_struct *dcd = (decoder_client_data_struct*)client_data;
  132. (void)decoder;
  133. if(0 == dcd) {
  134. printf("ERROR: client_data in metadata callback is NULLn");
  135. return;
  136. }
  137. if(dcd->error_occurred)
  138. return;
  139. if (!dcd->got_data && metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
  140. dcd->got_data = true;
  141. dcd->total_samples = metadata->data.stream_info.total_samples;
  142. dcd->channels = metadata->data.stream_info.channels;
  143. dcd->bits_per_sample = metadata->data.stream_info.bits_per_sample;
  144. }
  145. }
  146. static void file_decoder_error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
  147. {
  148. decoder_client_data_struct *dcd = (decoder_client_data_struct*)client_data;
  149. (void)decoder;
  150. if(0 == dcd) {
  151. printf("ERROR: client_data in error callback is NULLn");
  152. return;
  153. }
  154. if(!dcd->ignore_errors) {
  155. printf("ERROR: got error callback: err = %u (%s)n", (unsigned)status, FLAC__StreamDecoderErrorStatusString[status]);
  156. dcd->error_occurred = true;
  157. }
  158. }
  159. static FLAC__bool seek_barrage_native_flac(const char *filename, off_t filesize, unsigned count)
  160. {
  161. FLAC__FileDecoder *decoder;
  162. decoder_client_data_struct decoder_client_data;
  163. unsigned i;
  164. long int n;
  165. decoder_client_data.got_data = false;
  166. decoder_client_data.total_samples = 0;
  167. decoder_client_data.ignore_errors = false;
  168. decoder_client_data.error_occurred = false;
  169. printf("n+++ seek test: FLAC__FileDecodernn");
  170. decoder = FLAC__file_decoder_new();
  171. if(0 == decoder)
  172. return die_("FLAC__file_decoder_new() FAILED, returned NULLn");
  173. if(!FLAC__file_decoder_set_write_callback(decoder, file_decoder_write_callback_))
  174. return die_f_("FLAC__file_decoder_set_write_callback() FAILED", decoder);
  175. if(!FLAC__file_decoder_set_metadata_callback(decoder, file_decoder_metadata_callback_))
  176. return die_f_("FLAC__file_decoder_set_metadata_callback() FAILED", decoder);
  177. if(!FLAC__file_decoder_set_error_callback(decoder, file_decoder_error_callback_))
  178. return die_f_("FLAC__file_decoder_set_error_callback() FAILED", decoder);
  179. if(!FLAC__file_decoder_set_client_data(decoder, &decoder_client_data))
  180. return die_f_("FLAC__file_decoder_set_client_data() FAILED", decoder);
  181. if(!FLAC__file_decoder_set_filename(decoder, filename))
  182. return die_f_("FLAC__file_decoder_set_filename() FAILED", decoder);
  183. if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK)
  184. return die_f_("FLAC__file_decoder_init() FAILED", decoder);
  185. if(!FLAC__file_decoder_process_until_end_of_metadata(decoder))
  186. return die_f_("FLAC__file_decoder_process_until_end_of_metadata() FAILED", decoder);
  187. printf("file's total_samples is %llun", decoder_client_data.total_samples);
  188. #if !defined _MSC_VER && !defined __MINGW32__
  189. if (decoder_client_data.total_samples > (FLAC__uint64)RAND_MAX) {
  190. printf("ERROR: must be total_samples < %un", (unsigned)RAND_MAX);
  191. return false;
  192. }
  193. #endif
  194. n = (long int)decoder_client_data.total_samples;
  195. /* if we don't have a total samples count, just guess based on the file size */
  196. /* @@@ should get it from last page's granulepos */
  197. if(n == 0) {
  198. /* 8 would imply no compression, 9 guarantees that we will get some samples off the end of the stream to test that case */
  199. n = 9 * filesize / (decoder_client_data.channels * decoder_client_data.bits_per_sample);
  200. #if !defined _MSC_VER && !defined __MINGW32__
  201. if(n > RAND_MAX)
  202. n = RAND_MAX;
  203. #endif
  204. }
  205. printf("Begin seek barrage, count=%un", count);
  206. for (i = 0; !stop_signal_ && (count == 0 || i < count); i++) {
  207. FLAC__uint64 pos;
  208. /* for the first 10, seek to the first 10 samples */
  209. if (n >= 10 && i < 10) {
  210. pos = i;
  211. }
  212. /* for the second 10, seek to the last 10 samples */
  213. else if (n >= 10 && i < 20) {
  214. pos = n - 1 - (i-10);
  215. }
  216. /* for the third 10, seek past the end and make sure we fail properly as expected */
  217. else if (i < 30) {
  218. pos = n + (i-20);
  219. }
  220. else {
  221. #if !defined _MSC_VER && !defined __MINGW32__
  222. pos = (FLAC__uint64)(random() % n);
  223. #else
  224. /* RAND_MAX is only 32767 in my MSVC */
  225. pos = (FLAC__uint64)((rand()<<15|rand()) % n);
  226. #endif
  227. }
  228. printf("seek(%llu)... ", pos);
  229. fflush(stdout);
  230. if(!FLAC__file_decoder_seek_absolute(decoder, pos)) {
  231. if(pos < (FLAC__uint64)n && decoder_client_data.total_samples != 0)
  232. return die_f_("FLAC__file_decoder_seek_absolute() FAILED", decoder);
  233. else if(decoder_client_data.total_samples == 0)
  234. printf("seek failed, assuming it was past EOF... ");
  235. else
  236. printf("seek past end failed as expected... ");
  237. /* hack to work around a deficiency in the seek API's behavior */
  238. /* seeking past EOF sets the file decoder state to non-OK and there's no ..._flush() or ..._reset() call to reset it */
  239. if(!FLAC__file_decoder_finish(decoder))
  240. return die_f_("FLAC__file_decoder_finish() FAILED", decoder);
  241. if(!FLAC__file_decoder_set_write_callback(decoder, file_decoder_write_callback_))
  242. return die_f_("FLAC__file_decoder_set_write_callback() FAILED", decoder);
  243. if(!FLAC__file_decoder_set_metadata_callback(decoder, file_decoder_metadata_callback_))
  244. return die_f_("FLAC__file_decoder_set_metadata_callback() FAILED", decoder);
  245. if(!FLAC__file_decoder_set_error_callback(decoder, file_decoder_error_callback_))
  246. return die_f_("FLAC__file_decoder_set_error_callback() FAILED", decoder);
  247. if(!FLAC__file_decoder_set_client_data(decoder, &decoder_client_data))
  248. return die_f_("FLAC__file_decoder_set_client_data() FAILED", decoder);
  249. if(!FLAC__file_decoder_set_filename(decoder, filename))
  250. return die_f_("FLAC__file_decoder_set_filename() FAILED", decoder);
  251. if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK)
  252. return die_f_("FLAC__file_decoder_init() FAILED", decoder);
  253. if(!FLAC__file_decoder_process_until_end_of_metadata(decoder))
  254. return die_f_("FLAC__file_decoder_process_until_end_of_metadata() FAILED", decoder);
  255. }
  256. else {
  257. printf("decode_frame... ");
  258. fflush(stdout);
  259. if(!FLAC__file_decoder_process_single(decoder))
  260. return die_f_("FLAC__file_decoder_process_single() FAILED", decoder);
  261. printf("decode_frame... ");
  262. fflush(stdout);
  263. if(!FLAC__file_decoder_process_single(decoder))
  264. return die_f_("FLAC__file_decoder_process_single() FAILED", decoder);
  265. }
  266. printf("OKn");
  267. fflush(stdout);
  268. }
  269. if(FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_UNINITIALIZED) {
  270. if(!FLAC__file_decoder_finish(decoder))
  271. return die_f_("FLAC__file_decoder_finish() FAILED", decoder);
  272. }
  273. printf("nPASSED!n");
  274. return true;
  275. }
  276. #ifdef FLAC__HAS_OGG
  277. static FLAC__bool seek_barrage_ogg_flac(const char *filename, off_t filesize, unsigned count)
  278. {
  279. OggFLAC__FileDecoder *decoder;
  280. decoder_client_data_struct decoder_client_data;
  281. unsigned i;
  282. long int n;
  283. decoder_client_data.got_data = false;
  284. decoder_client_data.total_samples = 0;
  285. decoder_client_data.ignore_errors = false;
  286. decoder_client_data.error_occurred = false;
  287. printf("n+++ seek test: OggFLAC__FileDecodernn");
  288. decoder = OggFLAC__file_decoder_new();
  289. if(0 == decoder)
  290. return die_("OggFLAC__file_decoder_new() FAILED, returned NULLn");
  291. if(!OggFLAC__file_decoder_set_write_callback(decoder, (OggFLAC__FileDecoderWriteCallback)file_decoder_write_callback_))
  292. return die_of_("OggFLAC__file_decoder_set_write_callback() FAILED", decoder);
  293. if(!OggFLAC__file_decoder_set_metadata_callback(decoder, (OggFLAC__FileDecoderMetadataCallback)file_decoder_metadata_callback_))
  294. return die_of_("OggFLAC__file_decoder_set_metadata_callback() FAILED", decoder);
  295. if(!OggFLAC__file_decoder_set_error_callback(decoder, (OggFLAC__FileDecoderErrorCallback)file_decoder_error_callback_))
  296. return die_of_("OggFLAC__file_decoder_set_error_callback() FAILED", decoder);
  297. if(!OggFLAC__file_decoder_set_client_data(decoder, &decoder_client_data))
  298. return die_of_("OggFLAC__file_decoder_set_client_data() FAILED", decoder);
  299. if(!OggFLAC__file_decoder_set_filename(decoder, filename))
  300. return die_of_("OggFLAC__file_decoder_set_filename() FAILED", decoder);
  301. if(OggFLAC__file_decoder_init(decoder) != OggFLAC__FILE_DECODER_OK)
  302. return die_of_("OggFLAC__file_decoder_init() FAILED", decoder);
  303. if(!OggFLAC__file_decoder_process_until_end_of_metadata(decoder))
  304. return die_of_("OggFLAC__file_decoder_process_until_end_of_metadata() FAILED", decoder);
  305. printf("file's total_samples is %llun", decoder_client_data.total_samples);
  306. #if !defined _MSC_VER && !defined __MINGW32__
  307. if (decoder_client_data.total_samples > (FLAC__uint64)RAND_MAX) {
  308. printf("ERROR: must be total_samples < %un", (unsigned)RAND_MAX);
  309. return false;
  310. }
  311. #endif
  312. n = (long int)decoder_client_data.total_samples;
  313. /* if we don't have a total samples count, just guess based on the file size */
  314. if(n == 0) {
  315. /* 8 would imply no compression, 9 guarantees that we will get some samples off the end of the stream to test that case */
  316. n = 9 * filesize / (decoder_client_data.channels * decoder_client_data.bits_per_sample);
  317. #if !defined _MSC_VER && !defined __MINGW32__
  318. if(n > RAND_MAX)
  319. n = RAND_MAX;
  320. #endif
  321. }
  322. printf("Begin seek barrage, count=%un", count);
  323. for (i = 0; !stop_signal_ && (count == 0 || i < count); i++) {
  324. FLAC__uint64 pos;
  325. /* for the first 10, seek to the first 10 samples */
  326. if (n >= 10 && i < 10) {
  327. pos = i;
  328. }
  329. /* for the second 10, seek to the last 10 samples */
  330. else if (n >= 10 && i < 20) {
  331. pos = n - 1 - (i-10);
  332. }
  333. /* for the third 10, seek past the end and make sure we fail properly as expected */
  334. else if (i < 30) {
  335. pos = n + (i-20);
  336. }
  337. else {
  338. #if !defined _MSC_VER && !defined __MINGW32__
  339. pos = (FLAC__uint64)(random() % n);
  340. #else
  341. /* RAND_MAX is only 32767 in my MSVC */
  342. pos = (FLAC__uint64)((rand()<<15|rand()) % n);
  343. #endif
  344. }
  345. printf("seek(%llu)... ", pos);
  346. fflush(stdout);
  347. if(!OggFLAC__file_decoder_seek_absolute(decoder, pos)) {
  348. if(pos < (FLAC__uint64)n && decoder_client_data.total_samples != 0)
  349. return die_of_("OggFLAC__file_decoder_seek_absolute() FAILED", decoder);
  350. else if(decoder_client_data.total_samples == 0)
  351. printf("seek failed, assuming it was past EOF... ");
  352. else
  353. printf("seek past end failed as expected... ");
  354. /* hack to work around a deficiency in the seek API's behavior */
  355. /* seeking past EOF sets the file decoder state to non-OK and there's no ..._flush() or ..._reset() call to reset it */
  356. if(!OggFLAC__file_decoder_finish(decoder))
  357. return die_of_("OggFLAC__file_decoder_finish() FAILED", decoder);
  358. if(!OggFLAC__file_decoder_set_write_callback(decoder, (OggFLAC__FileDecoderWriteCallback)file_decoder_write_callback_))
  359. return die_of_("OggFLAC__file_decoder_set_write_callback() FAILED", decoder);
  360. if(!OggFLAC__file_decoder_set_metadata_callback(decoder, (OggFLAC__FileDecoderMetadataCallback)file_decoder_metadata_callback_))
  361. return die_of_("OggFLAC__file_decoder_set_metadata_callback() FAILED", decoder);
  362. if(!OggFLAC__file_decoder_set_error_callback(decoder, (OggFLAC__FileDecoderErrorCallback)file_decoder_error_callback_))
  363. return die_of_("OggFLAC__file_decoder_set_error_callback() FAILED", decoder);
  364. if(!OggFLAC__file_decoder_set_client_data(decoder, &decoder_client_data))
  365. return die_of_("OggFLAC__file_decoder_set_client_data() FAILED", decoder);
  366. if(!OggFLAC__file_decoder_set_filename(decoder, filename))
  367. return die_of_("OggFLAC__file_decoder_set_filename() FAILED", decoder);
  368. if(OggFLAC__file_decoder_init(decoder) != OggFLAC__FILE_DECODER_OK)
  369. return die_of_("OggFLAC__file_decoder_init() FAILED", decoder);
  370. if(!OggFLAC__file_decoder_process_until_end_of_metadata(decoder))
  371. return die_of_("OggFLAC__file_decoder_process_until_end_of_metadata() FAILED", decoder);
  372. }
  373. else {
  374. printf("decode_frame... ");
  375. fflush(stdout);
  376. if(!OggFLAC__file_decoder_process_single(decoder))
  377. return die_of_("OggFLAC__file_decoder_process_single() FAILED", decoder);
  378. printf("decode_frame... ");
  379. fflush(stdout);
  380. if(!OggFLAC__file_decoder_process_single(decoder))
  381. return die_of_("OggFLAC__file_decoder_process_single() FAILED", decoder);
  382. }
  383. printf("OKn");
  384. fflush(stdout);
  385. }
  386. if(OggFLAC__file_decoder_get_state(decoder) != OggFLAC__FILE_DECODER_UNINITIALIZED) {
  387. if(!OggFLAC__file_decoder_finish(decoder))
  388. return die_of_("OggFLAC__file_decoder_finish() FAILED", decoder);
  389. }
  390. printf("nPASSED!n");
  391. return true;
  392. }
  393. #endif
  394. int main(int argc, char *argv[])
  395. {
  396. const char *filename;
  397. unsigned count = 0;
  398. off_t filesize;
  399. static const char * const usage = "usage: test_seeking file.flac [#seeks]n";
  400. if (argc < 1 || argc > 3) {
  401. fprintf(stderr, usage);
  402. return 1;
  403. }
  404. filename = argv[1];
  405. if (argc > 2)
  406. count = strtoul(argv[2], 0, 10);
  407. if (count < 30)
  408. fprintf(stderr, "WARNING: random seeks don't kick in until after 30 preprogrammed onesn");
  409. #if !defined _MSC_VER && !defined __MINGW32__
  410. {
  411. struct timeval tv;
  412. if (gettimeofday(&tv, 0) < 0) {
  413. fprintf(stderr, "WARNING: couldn't seed RNG with timen");
  414. tv.tv_usec = 4321;
  415. }
  416. srandom(tv.tv_usec);
  417. }
  418. #else
  419. srand(time(0));
  420. #endif
  421. filesize = get_filesize_(filename);
  422. if (filesize < 0) {
  423. fprintf(stderr, "ERROR: can't determine filesize for %sn", filename);
  424. return 1;
  425. }
  426. (void) signal(SIGINT, our_sigint_handler_);
  427. {
  428. FLAC__bool ok;
  429. if (strlen(filename) > 4 && 0 == strcmp(filename+strlen(filename)-4, ".ogg")) {
  430. #ifdef FLAC__HAS_OGG
  431. ok = seek_barrage_ogg_flac(filename, filesize, count);
  432. #else
  433. fprintf(stderr, "ERROR: Ogg FLAC not supportedn");
  434. ok = false;
  435. #endif
  436. }
  437. else {
  438. ok = seek_barrage_native_flac(filename, filesize, count);
  439. }
  440. return ok? 0 : 2;
  441. }
  442. }