Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4034 lines
149 KiB

  1. /*
  2. * @DEC_COPYRIGHT@
  3. */
  4. /*
  5. * HISTORY
  6. * $Log: slib_api.c,v $
  7. * Revision 1.1.6.35 1996/12/13 18:19:04 Hans_Graves
  8. * Update Audio and Video timestamp correctly.
  9. * [1996/12/13 18:09:02 Hans_Graves]
  10. *
  11. * Revision 1.1.6.34 1996/12/12 20:54:44 Hans_Graves
  12. * Timestamp fixes after seek to Key frames.
  13. * [1996/12/12 20:52:06 Hans_Graves]
  14. *
  15. * Revision 1.1.6.33 1996/12/10 19:46:02 Hans_Graves
  16. * Fix floating division error when audio only.
  17. * [1996/12/10 19:45:03 Hans_Graves]
  18. *
  19. * Revision 1.1.6.32 1996/12/10 19:21:55 Hans_Graves
  20. * Made calculate video positions more accurate using slibFrameToTime100().
  21. * [1996/12/10 19:16:20 Hans_Graves]
  22. *
  23. * Revision 1.1.6.31 1996/12/05 20:10:15 Hans_Graves
  24. * Add gradual increase or decrease of framerates according to timestamps.
  25. * [1996/12/05 20:06:57 Hans_Graves]
  26. *
  27. * Revision 1.1.6.30 1996/12/04 22:34:28 Hans_Graves
  28. * Put limit on data used by Sv/SaDecompressBegin().
  29. * [1996/12/04 22:14:33 Hans_Graves]
  30. *
  31. * Revision 1.1.6.29 1996/12/03 23:15:13 Hans_Graves
  32. * MME-1498: Made seeks with PERCENT100 more accurate
  33. * [1996/12/03 23:10:43 Hans_Graves]
  34. *
  35. * Revision 1.1.6.28 1996/12/03 00:08:31 Hans_Graves
  36. * Handling of End Of Sequence points. Added PERCENT100 support.
  37. * [1996/12/03 00:05:59 Hans_Graves]
  38. *
  39. * Revision 1.1.6.27 1996/11/21 23:34:21 Hans_Graves
  40. * Handle MPEG B frames better when seeking.
  41. * [1996/11/21 23:28:18 Hans_Graves]
  42. *
  43. * Revision 1.1.6.26 1996/11/20 02:15:09 Hans_Graves
  44. * Added SEEK_AHEAD. Removed old code.
  45. * [1996/11/20 02:10:43 Hans_Graves]
  46. *
  47. * Revision 1.1.6.25 1996/11/18 23:07:21 Hans_Graves
  48. * Remove MaxVideoLength usage.
  49. * [1996/11/18 22:55:56 Hans_Graves]
  50. *
  51. * Make use of presentation timestamps. Make seeking time-based.
  52. * [1996/11/18 22:47:30 Hans_Graves]
  53. *
  54. * Revision 1.1.6.24 1996/11/14 21:49:26 Hans_Graves
  55. * AC3 buffering fixes.
  56. * [1996/11/14 21:43:20 Hans_Graves]
  57. *
  58. * Revision 1.1.6.23 1996/11/13 16:10:54 Hans_Graves
  59. * AC3 recognition of byte reversed streams in slibGetDataFormat().
  60. * [1996/11/13 16:03:14 Hans_Graves]
  61. *
  62. * Revision 1.1.6.22 1996/11/11 18:21:03 Hans_Graves
  63. * More AC3 support changes.
  64. * [1996/11/11 17:59:01 Hans_Graves]
  65. *
  66. * Revision 1.1.6.21 1996/11/08 21:51:02 Hans_Graves
  67. * Added AC3 support. Better seperation of stream types.
  68. * [1996/11/08 21:27:57 Hans_Graves]
  69. *
  70. * Revision 1.1.6.20 1996/10/31 00:08:51 Hans_Graves
  71. * Fix skipping data after RESET with MPEG video only streams.
  72. * [1996/10/31 00:07:08 Hans_Graves]
  73. *
  74. * Revision 1.1.6.19 1996/10/28 23:16:42 Hans_Graves
  75. * MME-0145?, Fix artifacts when using SlibReadData() at a new position. Jump to first GOP.
  76. * [1996/10/28 23:13:01 Hans_Graves]
  77. *
  78. * Revision 1.1.6.18 1996/10/28 17:32:28 Hans_Graves
  79. * MME-1402, 1431, 1435: Timestamp related changes.
  80. * [1996/10/28 17:22:58 Hans_Graves]
  81. *
  82. * Revision 1.1.6.17 1996/10/17 00:23:32 Hans_Graves
  83. * Fix buffer problems after SlibQueryData() calls.
  84. * [1996/10/17 00:19:05 Hans_Graves]
  85. *
  86. * Revision 1.1.6.16 1996/10/15 17:34:09 Hans_Graves
  87. * Added MPEG-2 Program Stream support.
  88. * [1996/10/15 17:30:26 Hans_Graves]
  89. *
  90. * Revision 1.1.6.15 1996/10/12 17:18:51 Hans_Graves
  91. * Fixed some seeking problems. Moved render code to slib_render.c
  92. * [1996/10/12 17:00:49 Hans_Graves]
  93. *
  94. * Revision 1.1.6.14 1996/10/03 19:14:21 Hans_Graves
  95. * Added Presentation and Decoding timestamp support.
  96. * [1996/10/03 19:10:35 Hans_Graves]
  97. *
  98. * Revision 1.1.6.13 1996/09/29 22:19:37 Hans_Graves
  99. * Added stride support. Added SlibQueryData().
  100. * [1996/09/29 21:29:44 Hans_Graves]
  101. *
  102. * Revision 1.1.6.12 1996/09/25 19:16:44 Hans_Graves
  103. * Added DECOMPRESS_QUERY. Fix up support for YUY2.
  104. * [1996/09/25 19:00:45 Hans_Graves]
  105. *
  106. * Revision 1.1.6.11 1996/09/23 18:04:03 Hans_Graves
  107. * Added stats support. Scaleing and negative height fixes.
  108. * [1996/09/23 17:59:31 Hans_Graves]
  109. *
  110. * Revision 1.1.6.10 1996/09/18 23:46:32 Hans_Graves
  111. * Seek fixes. Added SlibReadData() and SlibAddBufferEx().
  112. * [1996/09/18 22:04:57 Hans_Graves]
  113. *
  114. * Revision 1.1.6.9 1996/08/09 20:51:42 Hans_Graves
  115. * Fix handle arg for SlibRegisterVideoBuffer()
  116. * [1996/08/09 20:10:11 Hans_Graves]
  117. *
  118. * Revision 1.1.6.8 1996/07/19 02:11:11 Hans_Graves
  119. * Added SlibRegisterVideoBuffer. Added YUV422i to RGB 16 rendering.
  120. * [1996/07/19 02:01:11 Hans_Graves]
  121. *
  122. * Revision 1.1.6.7 1996/06/03 21:41:12 Hans_Graves
  123. * Fix file seeking. Always seeked to position 0.
  124. * [1996/06/03 21:40:44 Hans_Graves]
  125. *
  126. * Revision 1.1.6.6 1996/05/24 22:21:44 Hans_Graves
  127. * Merge MME-1221. Last SlibReadAudio() returned EndOfStream even if data read.
  128. * [1996/05/24 20:58:42 Hans_Graves]
  129. *
  130. * Revision 1.1.6.5 1996/05/23 18:46:35 Hans_Graves
  131. * Seperate global audio and video SInfo variables, to help multi-threaded apps
  132. * [1996/05/23 18:35:14 Hans_Graves]
  133. *
  134. * Revision 1.1.6.4 1996/05/23 18:16:31 Hans_Graves
  135. * Added more YUV Conversions. MPEG audio buffering fix.
  136. * [1996/05/23 18:16:11 Hans_Graves]
  137. *
  138. * Revision 1.1.6.3 1996/05/10 21:17:00 Hans_Graves
  139. * Added callback support. Also fill entire buffers when calling SlibReadAudio()
  140. * [1996/05/10 20:26:08 Hans_Graves]
  141. *
  142. * Revision 1.1.6.2 1996/05/07 19:56:16 Hans_Graves
  143. * Added SlibOpen() and SlibAddBuffer() framework. Added HUFF_SUPPORT.
  144. * [1996/05/07 17:20:12 Hans_Graves]
  145. *
  146. * Revision 1.1.4.16 1996/05/02 17:10:33 Hans_Graves
  147. * Be more specific about checking for MPEG-2 Systems file type. Fixes MME-01234
  148. * [1996/05/02 17:04:44 Hans_Graves]
  149. *
  150. * Revision 1.1.4.15 1996/04/24 22:33:44 Hans_Graves
  151. * MPEG encoding bitrate fixups.
  152. * [1996/04/24 22:27:09 Hans_Graves]
  153. *
  154. * Revision 1.1.4.14 1996/04/23 21:22:31 Hans_Graves
  155. * Added description for SlibErrorSettingNotEqual
  156. * [1996/04/23 21:16:09 Hans_Graves]
  157. *
  158. * Revision 1.1.4.13 1996/04/22 15:04:51 Hans_Graves
  159. * Fix bad frame counts and seeking under NT caused by int overflows
  160. * [1996/04/22 15:02:26 Hans_Graves]
  161. *
  162. * Revision 1.1.4.12 1996/04/19 21:52:22 Hans_Graves
  163. * MPEG 1 Systems writing enhancements
  164. * [1996/04/19 21:47:48 Hans_Graves]
  165. *
  166. * Revision 1.1.4.11 1996/04/15 14:18:37 Hans_Graves
  167. * Handle any audio buffer size during encoding.
  168. * [1996/04/15 14:16:11 Hans_Graves]
  169. *
  170. * Revision 1.1.4.10 1996/04/12 19:25:20 Hans_Graves
  171. * Add MPEG2_VIDEO type to Commit
  172. * [1996/04/12 19:24:19 Hans_Graves]
  173. *
  174. * Revision 1.1.4.9 1996/04/10 21:47:41 Hans_Graves
  175. * Fix in SlibIsEnd().
  176. * [1996/04/10 21:39:37 Hans_Graves]
  177. *
  178. * Revision 1.1.4.8 1996/04/09 16:04:42 Hans_Graves
  179. * Remove NT warnings
  180. * [1996/04/09 14:42:48 Hans_Graves]
  181. *
  182. * Revision 1.1.4.7 1996/04/04 23:35:07 Hans_Graves
  183. * Format conversion cleanup
  184. * [1996/04/04 23:16:20 Hans_Graves]
  185. *
  186. * Revision 1.1.4.6 1996/04/01 19:07:52 Hans_Graves
  187. * And some error checking
  188. * [1996/04/01 19:04:33 Hans_Graves]
  189. *
  190. * Revision 1.1.4.5 1996/04/01 16:23:12 Hans_Graves
  191. * NT porting
  192. * [1996/04/01 16:15:54 Hans_Graves]
  193. *
  194. * Revision 1.1.4.4 1996/03/29 22:21:30 Hans_Graves
  195. * Added MPEG/JPEG/H261_SUPPORT ifdefs
  196. * [1996/03/29 21:56:55 Hans_Graves]
  197. *
  198. * Added MPEG-I Systems encoding support
  199. * [1996/03/27 21:55:54 Hans_Graves]
  200. *
  201. * Revision 1.1.4.3 1996/03/12 16:15:45 Hans_Graves
  202. * Added seperate streams to SlibIsEnd()
  203. * [1996/03/12 15:56:28 Hans_Graves]
  204. *
  205. * Revision 1.1.4.2 1996/03/08 18:46:42 Hans_Graves
  206. * YUV conversions moved to slibRenderFrame()
  207. * [1996/03/08 18:14:47 Hans_Graves]
  208. *
  209. * Revision 1.1.2.18 1996/02/22 23:30:24 Hans_Graves
  210. * Update FPS on seeks
  211. * [1996/02/22 23:29:27 Hans_Graves]
  212. *
  213. * Revision 1.1.2.17 1996/02/22 22:23:56 Hans_Graves
  214. * Update frame numbers with timecode more often
  215. * [1996/02/22 22:23:07 Hans_Graves]
  216. *
  217. * Revision 1.1.2.16 1996/02/21 22:52:43 Hans_Graves
  218. * Fixed MPEG 2 systems stuff
  219. * [1996/02/21 22:50:55 Hans_Graves]
  220. *
  221. * Revision 1.1.2.15 1996/02/19 20:09:28 Hans_Graves
  222. * Debugging message clean-up
  223. * [1996/02/19 20:08:31 Hans_Graves]
  224. *
  225. * Revision 1.1.2.14 1996/02/19 18:03:54 Hans_Graves
  226. * Fixed a number of MPEG related bugs
  227. * [1996/02/19 17:57:36 Hans_Graves]
  228. *
  229. * Revision 1.1.2.13 1996/02/13 18:47:46 Hans_Graves
  230. * Fix some Seek related bugs
  231. * [1996/02/13 18:40:36 Hans_Graves]
  232. *
  233. * Revision 1.1.2.12 1996/02/07 23:23:54 Hans_Graves
  234. * Added SEEK_EXACT. Fixed most frame counting problems.
  235. * [1996/02/07 23:20:29 Hans_Graves]
  236. *
  237. * Revision 1.1.2.11 1996/02/06 22:54:05 Hans_Graves
  238. * Seek fix-ups. More accurate MPEG frame counts.
  239. * [1996/02/06 22:44:56 Hans_Graves]
  240. *
  241. * Revision 1.1.2.10 1996/02/02 17:36:02 Hans_Graves
  242. * Enhanced audio info. Cleaned up API
  243. * [1996/02/02 17:29:44 Hans_Graves]
  244. *
  245. * Revision 1.1.2.9 1996/01/30 22:23:08 Hans_Graves
  246. * Added AVI YUV support
  247. * [1996/01/30 22:21:38 Hans_Graves]
  248. *
  249. * Revision 1.1.2.8 1996/01/15 16:26:27 Hans_Graves
  250. * Removed debuging message
  251. * [1996/01/15 16:02:47 Hans_Graves]
  252. *
  253. * Added MPEG 1 Audio compression and SlibWriteAudio()
  254. * [1996/01/15 15:45:46 Hans_Graves]
  255. *
  256. * Revision 1.1.2.7 1996/01/11 16:17:29 Hans_Graves
  257. * Added MPEG II Systems decode support
  258. * [1996/01/11 16:12:33 Hans_Graves]
  259. *
  260. * Revision 1.1.2.6 1996/01/08 16:41:31 Hans_Graves
  261. * Added MPEG II decoding support
  262. * [1996/01/08 15:53:02 Hans_Graves]
  263. *
  264. * Revision 1.1.2.5 1995/12/08 20:01:20 Hans_Graves
  265. * Fixed SlibSetParam(). Added H.261 compression support.
  266. * [1995/12/08 19:53:52 Hans_Graves]
  267. *
  268. * Revision 1.1.2.4 1995/12/07 19:31:36 Hans_Graves
  269. * Added JPEG Decoding and MPEG encoding support
  270. * [1995/12/07 18:30:10 Hans_Graves]
  271. *
  272. * Revision 1.1.2.3 1995/11/09 23:14:05 Hans_Graves
  273. * Added MPEG audio decompression
  274. * [1995/11/09 23:08:33 Hans_Graves]
  275. *
  276. * Revision 1.1.2.2 1995/11/06 18:47:52 Hans_Graves
  277. * First time under SLIB
  278. * [1995/11/06 18:36:01 Hans_Graves]
  279. *
  280. * $EndLog$
  281. */
  282. /*****************************************************************************
  283. ** Copyright (c) Digital Equipment Corporation, 1995 **
  284. ** **
  285. ** All Rights Reserved. Unpublished rights reserved under the copyright **
  286. ** laws of the United States. **
  287. ** **
  288. ** The software contained on this media is proprietary to and embodies **
  289. ** the confidential technology of Digital Equipment Corporation. **
  290. ** Possession, use, duplication or dissemination of the software and **
  291. ** media is authorized only pursuant to a valid written license from **
  292. ** Digital Equipment Corporation. **
  293. ** **
  294. ** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
  295. ** Government is subject to restrictions as set forth in Subparagraph **
  296. ** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
  297. ******************************************************************************/
  298. /*
  299. #define _SLIBDEBUG_
  300. */
  301. #include <fcntl.h>
  302. #include <sys/stat.h>
  303. #ifdef WIN32
  304. #include <io.h>
  305. #endif
  306. #ifdef _SHM_
  307. #include <sys/ipc.h> /* shared memory */
  308. #endif
  309. #define SLIB_INTERNAL
  310. #include "slib.h"
  311. #include "SC_err.h"
  312. /* #include "SC_convert.h" */
  313. #include "mpeg.h"
  314. #include "ac3.h"
  315. #include "avi.h"
  316. #ifdef _SLIBDEBUG_
  317. #include <stdio.h>
  318. #include "sc_debug.h"
  319. #define _DEBUG_ 1 /* detailed debuging statements */
  320. #define _VERBOSE_ 1 /* show progress */
  321. #define _VERIFY_ 1 /* verify correct operation */
  322. #define _WARN_ 1 /* warnings about strange behavior */
  323. #define _SEEK_ 1 /* seek, frame counts/timecode info: 2=more detail */
  324. #define _CALLBACK_ 0 /* callback debugging */
  325. #define _DUMP_ 0 /* dump data in hex format */
  326. #define _TIMECODE_ 1 /* debug timecodes */
  327. #endif
  328. static SlibStatus_t slibOpen(SlibHandle_t *handle, SlibMode_t smode,
  329. SlibType_t *stype);
  330. /*
  331. ** Lists
  332. */
  333. static SlibList_t _listTypes [] = {
  334. SLIB_TYPE_MPEG1_VIDEO, "MPEG1_VIDEO", "MPEG-1 Video Stream",0,0,
  335. SLIB_TYPE_MPEG1_AUDIO, "MPEG1_AUDIO", "MPEG-1 Audio Stream",0,0,
  336. SLIB_TYPE_MPEG2_VIDEO, "MPEG2_VIDEO", "MPEG-2 Video Stream",0,0,
  337. SLIB_TYPE_MPEG2_AUDIO, "MPEG2_AUDIO", "MPEG-2 Audio Stream",0,0,
  338. SLIB_TYPE_AC3_AUDIO, "AC3", "Dolby Digital(AC-3) Stream",0,0,
  339. SLIB_TYPE_MPEG_SYSTEMS, "MPEG_SYSTEMS", "MPEG Systems Stream",0,0,
  340. SLIB_TYPE_MPEG_SYSTEMS_MPEG2, "MPEG_SYSTEMS_MPEG2", "MPEG Systems (MPEG-2)",0,0,
  341. SLIB_TYPE_MPEG_TRANSPORT,"MPEG_TRANSPORT", "MPEG Transport Stream",0,0,
  342. SLIB_TYPE_MPEG_PROGRAM, "MPEG_PROGRAM", "MPEG Program Stream",0,0,
  343. SLIB_TYPE_H261, "H261", "H.261 Video Stream",0,0,
  344. SLIB_TYPE_RTP_H261, "RTP_H261", "RTP (H.261) Stream",0,0,
  345. SLIB_TYPE_H263, "H263", "H.263 Video Stream",0,0,
  346. SLIB_TYPE_RTP_H263, "RTP_H263", "RTP (H.263) Stream",0,0,
  347. SLIB_TYPE_RIFF, "RIFF", "RIFF File Format",0,0,
  348. SLIB_TYPE_AVI, "AVI", "AVI File Format",0,0,
  349. SLIB_TYPE_PCM_WAVE, "PCM_WAVE", "WAVE (PCM) File Format",0,0,
  350. SLIB_TYPE_JPEG_AVI, "JPEG_AVI", "AVI (JPEG) Stream",0,0,
  351. SLIB_TYPE_MJPG_AVI, "MJPG_AVI", "AVI (MJPG) Stream",0,0,
  352. SLIB_TYPE_YUV_AVI, "YUV_AVI", "AVI (YUV) File Format",0,0,
  353. SLIB_TYPE_JFIF, "JFIF", "JPEG (JFIF) Stream",0,0,
  354. SLIB_TYPE_JPEG_QUICKTIME,"JPEG_QUICKTIME","JPEG (Quicktime) Stream",0,0,
  355. SLIB_TYPE_JPEG, "JPEG", "JPEG Stream",0,0,
  356. SLIB_TYPE_MJPG, "MJPG", "MJPG Stream",0,0,
  357. SLIB_TYPE_YUV, "YUV", "YUV Data",0,0,
  358. SLIB_TYPE_RGB, "RGB", "RGB Data",0,0,
  359. SLIB_TYPE_PCM, "PCM", "PCM Audio",0,0,
  360. SLIB_TYPE_SLIB, "SLIB", "SLIB Stream",0,0,
  361. SLIB_TYPE_SHUFF, "SHUFF", "SLIB Huffman Stream",0,0,
  362. SLIB_TYPE_G723, "G723", "G.723 Audio Stream",0,0,
  363. SLIB_TYPE_RASTER, "RASTER","Sun Raster",0,0,
  364. SLIB_TYPE_BMP, "BMP", "Windows Bitmap",0,0,
  365. 0, NULL, "End of List",0,0
  366. };
  367. static SlibList_t _listCompressTypes [] = {
  368. #ifdef MPEG_SUPPORT
  369. SLIB_TYPE_MPEG1_VIDEO, "MPEG1_VIDEO", "MPEG-1 Video Stream",0,0,
  370. SLIB_TYPE_MPEG1_AUDIO, "MPEG1_AUDIO", "MPEG-1 Audio Stream",0,0,
  371. SLIB_TYPE_MPEG2_VIDEO, "MPEG2_VIDEO", "MPEG-2 Video Stream",0,0,
  372. SLIB_TYPE_MPEG_SYSTEMS, "MPEG_SYSTEMS", "MPEG Systems Stream",0,0,
  373. SLIB_TYPE_MPEG_SYSTEMS_MPEG2, "MPEG2_SYSTEMS", "MPEG Systems (MPEG-2)",0,0,
  374. #endif /* MPEG_SUPPORT */
  375. #ifdef H261_SUPPORT
  376. SLIB_TYPE_H261, "H261", "H.261 Video Stream",0,0,
  377. #endif /* H261_SUPPORT */
  378. #ifdef H263_SUPPORT
  379. SLIB_TYPE_H263, "H263", "H.263 Video Stream",0,0,
  380. #endif /* H263_SUPPORT */
  381. #ifdef HUFF_SUPPORT
  382. SLIB_TYPE_SHUFF, "SHUFF", "SLIB Huffman Stream",0,0,
  383. #endif /* HUFF_SUPPORT */
  384. #ifdef G723_SUPPORT
  385. SLIB_TYPE_G723, "G723", "G.723 Audio Stream",0,0,
  386. #endif /* G723_SUPPORT */
  387. 0, NULL, "End of List",0,0
  388. };
  389. static SlibList_t _listDecompressTypes [] = {
  390. #ifdef MPEG_SUPPORT
  391. SLIB_TYPE_MPEG1_VIDEO, "MPEG1_VIDEO", "MPEG-1 Video Stream",0,0,
  392. SLIB_TYPE_MPEG1_AUDIO, "MPEG1_AUDIO", "MPEG-1 Audio Stream",0,0,
  393. SLIB_TYPE_MPEG2_VIDEO, "MPEG2_VIDEO", "MPEG-2 Video Stream",0,0,
  394. SLIB_TYPE_MPEG_SYSTEMS, "MPEG_SYSTEMS", "MPEG Systems Stream",0,0,
  395. SLIB_TYPE_MPEG_SYSTEMS_MPEG2, "MPEG2_SYSTEMS", "MPEG Systems (MPEG-2)",0,0,
  396. SLIB_TYPE_MPEG_TRANSPORT, "MPEG_TRANSPORT", "MPEG Transport Stream",0,0,
  397. SLIB_TYPE_MPEG_PROGRAM, "MPEG_PROGRAM", "MPEG Program Stream",0,0,
  398. #endif /* MPEG_SUPPORT */
  399. #ifdef AC3_SUPPORT
  400. SLIB_TYPE_AC3_AUDIO, "AC3", "Dolby Digital(AC-3) Stream",0,0,
  401. #endif /* AC3_SUPPORT */
  402. #ifdef H261_SUPPORT
  403. SLIB_TYPE_H261, "H261", "H.261 Video Stream",0,0,
  404. SLIB_TYPE_RTP_H261, "RTP_H261", "RTP (H.261) Stream",0,0,
  405. #endif /* H261_SUPPORT */
  406. #ifdef H263_SUPPORT
  407. SLIB_TYPE_H263, "H263", "H.263 Video Stream",0,0,
  408. SLIB_TYPE_RTP_H263, "RTP_H263", "RTP (H.263) Stream",0,0,
  409. #endif /* H261_SUPPORT */
  410. #ifdef JPEG_SUPPORT
  411. SLIB_TYPE_JPEG_AVI, "JPEG_AVI", "AVI (JPEG) Stream",0,0,
  412. SLIB_TYPE_MJPG_AVI, "MJPG_AVI", "AVI (MJPG) Stream",0,0,
  413. #endif /* JPEG_SUPPORT */
  414. SLIB_TYPE_RIFF, "RIFF", "RIFF File Format",0,0,
  415. SLIB_TYPE_AVI, "AVI", "AVI File Format",0,0,
  416. SLIB_TYPE_PCM_WAVE, "PCM_WAVE", "WAVE (PCM) File Format",0,0,
  417. SLIB_TYPE_YUV_AVI, "YUV_AVI", "AVI (YUV) File Format",0,0,
  418. SLIB_TYPE_RASTER, "RASTER","Sun Raster",0,0,
  419. SLIB_TYPE_BMP, "BMP", "Windows Bitmap",0,0,
  420. #ifdef HUFF_SUPPORT
  421. SLIB_TYPE_SHUFF, "SHUFF", "SLIB Huffman Stream",0,0,
  422. #endif /* HUFF_SUPPORT */
  423. #ifdef G723_SUPPORT
  424. SLIB_TYPE_G723, "G723", "G.723 Audio Stream",0,0,
  425. #endif /* G723_SUPPORT */
  426. 0, NULL, "End of List",0,0
  427. };
  428. static SlibList_t _listErrors[] = {
  429. SlibErrorNone, "SlibErrorNone",
  430. "No Error",0,0,
  431. SlibErrorInternal, "SlibErrorInternal",
  432. "Internal SLIB error",0,0,
  433. SlibErrorMemory, "SlibErrorMemory",
  434. "Unable to allocated memory",0,0,
  435. SlibErrorBadArgument, "SlibErrorBadArgument",
  436. "Invalid argument to function",0,0,
  437. SlibErrorBadHandle, "SlibErrorBadHandle",
  438. "Invalid SLIB handle",0,0,
  439. SlibErrorBadMode, "SlibErrorBadMode",
  440. "Invalid SLIB mode",0,0,
  441. SlibErrorUnsupportedFormat, "SlibErrorUnsupportedFormat",
  442. "Unsupported format",0,0,
  443. SlibErrorReading, "SlibErrorReading",
  444. "Error reading from file",0,0,
  445. SlibErrorWriting, "SlibErrorWriting",
  446. "Error writing to file",0,0,
  447. SlibErrorBufSize, "SlibErrorBufSize",
  448. "Buffer size is too small",0,0,
  449. SlibErrorEndOfStream, "SlibErrorEndOfStream",
  450. "End of data stream",0,0,
  451. SlibErrorForwardOnly, "SlibErrorForwardOnly",
  452. "The decompressor can work only forward",0,0,
  453. SlibErrorUnsupportedParam, "SlibErrorUnsupportedParam",
  454. "The parameter is invalid or unsupported",0,0,
  455. SlibErrorImageSize, "SlibErrorImageSize",
  456. "Invalid image height and/or width size",0,0,
  457. SlibErrorSettingNotEqual, "SlibErrorSettingNotEqual",
  458. "The exact parameter setting was not used",0,0,
  459. SlibErrorInit, "SlibErrorInit",
  460. "Initializing CODEC failed",0,0,
  461. SlibErrorFileSize, "SlibErrorFileSize",
  462. "Error in file size",0,0,
  463. SlibErrorBadPosition, "SlibErrorBadPosition",
  464. "Error in seek position",0,0,
  465. SlibErrorBadUnit, "SlibErrorBadUnit",
  466. "Error in seek units",0,0,
  467. SlibErrorNoData, "SlibErrorNoData",
  468. "No data available",0,0,
  469. 0, NULL, "End of List",0,0
  470. };
  471. SlibList_t *SlibFindEnumEntry(SlibList_t *list, int enumval)
  472. {
  473. if (!list)
  474. return(NULL);
  475. while (list->Name)
  476. {
  477. if (list->Enum==enumval)
  478. return(list);
  479. list++;
  480. }
  481. return(NULL);
  482. }
  483. char *SlibGetErrorText(SlibStatus_t status)
  484. {
  485. SlibList_t *entry=SlibFindEnumEntry(_listErrors, status);
  486. if (entry)
  487. return(entry->Desc);
  488. else
  489. return(NULL);
  490. }
  491. int VCompressCallback(SvHandle_t Svh, SvCallbackInfo_t *CB,
  492. SvPictureInfo_t *pinfo)
  493. {
  494. int status;
  495. SlibInfo_t *Info=(SlibInfo_t *)CB->UserData;
  496. _SlibDebug(_CALLBACK_, printf("VCompressCallback()\n") );
  497. switch (CB->Message)
  498. {
  499. case CB_END_BUFFERS:
  500. _SlibDebug(_CALLBACK_,
  501. printf("VCompressCallback received CB_END_BUFFER message\n") );
  502. if (CB->DataType==CB_DATA_COMPRESSED)
  503. {
  504. CB->DataSize=Info->CompBufSize;
  505. CB->Data=SlibAllocBuffer(CB->DataSize);
  506. status=SvAddBuffer(Svh, CB);
  507. _SlibDebug(_WARN_ && status!=NoErrors,
  508. printf("SvAddBuffer() %s\n", ScGetErrorStr(status)) );
  509. }
  510. break;
  511. case CB_RELEASE_BUFFER:
  512. _SlibDebug(_CALLBACK_,
  513. printf("VCompressCallback received CB_RELEASE_BUFFER message\n"));
  514. if (CB->DataType==CB_DATA_COMPRESSED && CB->Data && CB->DataUsed)
  515. {
  516. SlibPin_t *dstpin=slibGetPin(Info, SLIB_DATA_VIDEO);
  517. if (dstpin)
  518. {
  519. slibAddBufferToPin(dstpin, CB->Data, CB->DataUsed,
  520. Info->VideoPTimeCode);
  521. Info->VideoPTimeCode=SLIB_TIME_NONE;
  522. if (!slibCommitBuffers(Info, FALSE))
  523. CB->Action = CB_ACTION_END;
  524. break;
  525. }
  526. }
  527. if (CB->Data)
  528. SlibFreeBuffer(CB->Data);
  529. break;
  530. case CB_FRAME_START:
  531. _SlibDebug(_CALLBACK_||_TIMECODE_,
  532. printf("VCompress CB_FRAME_START: TimeCode=%ld TemporalRef=%d\n",
  533. pinfo->TimeCode, pinfo->TemporalRef) );
  534. Info->VideoPTimeCode=pinfo->TimeCode;
  535. #if 0
  536. if (pinfo->Type==SV_I_PICTURE || pinfo->Type==SV_P_PICTURE)
  537. {
  538. if (!SlibTimeIsValid(Info->LastVideoDTimeCode))
  539. Info->VideoDTimeCode=-1000/(long)Info->FramesPerSec;
  540. else
  541. Info->VideoDTimeCode=Info->LastVideoDTimeCode;
  542. Info->LastVideoDTimeCode=pinfo->TimeCode;
  543. _SlibDebug(_CALLBACK_||_TIMECODE_,
  544. printf("CB_FRAME_START: LastVideoDTimeCode=%ld VideoDTimeCode=%ld\n",
  545. Info->LastVideoDTimeCode, Info->VideoDTimeCode));
  546. }
  547. else
  548. Info->VideoDTimeCode=-1;
  549. #endif
  550. break;
  551. }
  552. CB->Action = CB_ACTION_CONTINUE;
  553. return(NoErrors);
  554. }
  555. int VDecompressCallback(SvHandle_t Svh, SvCallbackInfo_t *CB,
  556. SvPictureInfo_t *PictInfo)
  557. {
  558. int status;
  559. unsigned dword size;
  560. SlibInfo_t *Info=(SlibInfo_t *)CB->UserData;
  561. _SlibDebug(_CALLBACK_, printf("VDecompressCallback()\n") );
  562. switch (CB->Message)
  563. {
  564. case CB_SEQ_END: /* reset presentation timestamps at end-of-sequence */
  565. _SlibDebug(_CALLBACK_ || _TIMECODE_,
  566. printf("VDecompressCallback received CB_SEQ_END message\n") );
  567. Info->VideoPTimeCode=SLIB_TIME_NONE;
  568. Info->AudioPTimeCode=SLIB_TIME_NONE;
  569. Info->VideoTimeStamp=SLIB_TIME_NONE;
  570. Info->AudioTimeStamp=SLIB_TIME_NONE;
  571. break;
  572. case CB_END_BUFFERS:
  573. _SlibDebug(_CALLBACK_,
  574. printf("VDecompressCallback received CB_END_BUFFER message\n") );
  575. if (CB->DataType==CB_DATA_COMPRESSED)
  576. {
  577. SlibTime_t ptimestamp, timediff;
  578. slibSetMaxInput(Info, 1500*1024); /* set limit for input data */
  579. CB->Data = SlibGetBuffer(Info, SLIB_DATA_VIDEO, &size,
  580. &ptimestamp);
  581. slibSetMaxInput(Info, 0); /* clear limit */
  582. CB->DataSize = size;
  583. if (SlibTimeIsValid(Info->AudioPTimeCode))
  584. {
  585. timediff=ptimestamp-Info->AudioPTimeCode;
  586. if (timediff>6000)
  587. {
  588. /* Make sure a NEW audio time is not way out of
  589. * sync with video time.
  590. * This can happen after an End of Sequence.
  591. */
  592. /* assign audio time to video time */
  593. Info->VideoPTimeCode=SLIB_TIME_NONE;
  594. Info->VideoPTimeBase=Info->AudioPTimeBase;
  595. ptimestamp=Info->AudioPTimeCode;
  596. }
  597. }
  598. if (SlibTimeIsValid(ptimestamp) &&
  599. ptimestamp>Info->VideoPTimeCode)
  600. {
  601. SlibTime_t lasttime=Info->VideoPTimeCode;
  602. Info->VideoPTimeCode=ptimestamp;
  603. _SlibDebug(_CALLBACK_||_TIMECODE_,
  604. printf("VideoPTimeCode=%ld\n", Info->VideoPTimeCode) );
  605. ptimestamp-=Info->VideoPTimeBase;
  606. timediff=ptimestamp-Info->VideoTimeStamp;
  607. if (SlibTimeIsInValid(lasttime) ||
  608. SlibTimeIsInValid(Info->VideoTimeStamp))
  609. {
  610. _SlibDebug(_TIMECODE_,
  611. printf("Updating VideoTimeStamp none->%ld\n",
  612. ptimestamp) );
  613. Info->VideoTimeStamp=ptimestamp;
  614. Info->AvgVideoTimeDiff=0;
  615. Info->VarVideoTimeDiff=0;
  616. }
  617. else /* see if times are far off */
  618. {
  619. SlibTime_t lastavg=Info->AvgVideoTimeDiff;
  620. Info->AvgVideoTimeDiff=(lastavg*14+timediff)/15;
  621. Info->VarVideoTimeDiff=(Info->VarVideoTimeDiff*3+
  622. lastavg-Info->AvgVideoTimeDiff)/4;
  623. _SlibDebug(_CALLBACK_||_TIMECODE_,
  624. printf("Video timediff: Cur=%ld Avg=%ld Var=%ld\n",
  625. timediff, Info->AvgVideoTimeDiff,
  626. Info->VarVideoTimeDiff));
  627. if (Info->VarVideoTimeDiff==0)
  628. {
  629. _SlibDebug(_TIMECODE_,
  630. printf("Updating VideoTimeStamp %ld->%ld (diff=%ld)\n",
  631. Info->VideoTimeStamp, ptimestamp,
  632. ptimestamp-Info->VideoTimeStamp) );
  633. Info->VideoTimeStamp=ptimestamp;
  634. Info->AvgVideoTimeDiff=0;
  635. }
  636. else if (Info->AvgVideoTimeDiff>=100
  637. || Info->AvgVideoTimeDiff<=-100)
  638. {
  639. /* calculated time and timestamps are too far off */
  640. float fps=Info->FramesPerSec;
  641. if (Info->VarVideoTimeDiff>1 && fps>=15.5F)
  642. fps-=0.25F; /* playing too fast, slow frame rate */
  643. else if (Info->VarVideoTimeDiff<-1 && fps<=59.0F)
  644. fps+=0.25F; /* playing too slow, speed up frame rate */
  645. _SlibDebug(_WARN_ || _CALLBACK_||_TIMECODE_,
  646. printf("Updating fps from %.4f -> %.4f\n",
  647. Info->FramesPerSec, fps) );
  648. Info->FramesPerSec=fps;
  649. Info->VideoFrameDuration=slibFrameToTime100(Info, 1);
  650. Info->VideoTimeStamp=ptimestamp;
  651. Info->AvgVideoTimeDiff=0;
  652. }
  653. }
  654. Info->VideoFramesProcessed=0; /* reset frames processed */
  655. }
  656. if (CB->DataSize>0)
  657. {
  658. _SlibDebug(_DUMP_,
  659. SlibPin_t *pin=slibGetPin(Info, SLIB_DATA_VIDEO);
  660. printf("VDecompressCallback() Adding buffer of length %d\n",
  661. CB->DataSize);
  662. ScDumpChar(CB->Data, (int)CB->DataSize, (int)pin->Offset-CB->DataSize));
  663. CB->DataType = CB_DATA_COMPRESSED;
  664. _SlibDebug(_CALLBACK_,
  665. printf("VDecompressCallback() Adding buffer of length %d\n",
  666. CB->DataSize) );
  667. status = SvAddBuffer(Svh, CB);
  668. }
  669. else
  670. {
  671. _SlibDebug(_WARN_ || _CALLBACK_,
  672. printf("VDecompressCallback() got no data\n") );
  673. CB->Action = CB_ACTION_END;
  674. return(NoErrors);
  675. }
  676. }
  677. break;
  678. case CB_RELEASE_BUFFER:
  679. _SlibDebug(_CALLBACK_,
  680. printf("VDecompressCallback received CB_RELEASE_BUFFER message\n"));
  681. if (CB->DataType==CB_DATA_COMPRESSED && CB->Data)
  682. SlibFreeBuffer(CB->Data);
  683. break;
  684. case CB_PROCESSING:
  685. _SlibDebug(_CALLBACK_,
  686. printf("VDecompressCallback received CB_PROCESSING message\n") );
  687. break;
  688. case CB_CODEC_DONE:
  689. _SlibDebug(_CALLBACK_,
  690. printf("VDecompressCallback received CB_CODEC_DONE message\n") );
  691. break;
  692. }
  693. CB->Action = CB_ACTION_CONTINUE;
  694. return(NoErrors);
  695. }
  696. int ACompressCallback(SaHandle_t Sah, SaCallbackInfo_t *CB, SaInfo_t *SaInfo)
  697. {
  698. int status;
  699. SlibInfo_t *Info=(SlibInfo_t *)CB->UserData;
  700. _SlibDebug(_CALLBACK_, printf("ACompressCallback()\n") );
  701. CB->Action = CB_ACTION_CONTINUE;
  702. switch (CB->Message)
  703. {
  704. case CB_END_BUFFERS:
  705. _SlibDebug(_CALLBACK_,
  706. printf("ACompressCallback received CB_END_BUFFER message\n") );
  707. if (CB->DataType==CB_DATA_COMPRESSED)
  708. {
  709. CB->DataSize=Info->CompBufSize;
  710. CB->Data=SlibAllocBuffer(CB->DataSize);
  711. _SlibDebug(_CALLBACK_,
  712. printf("ACompressCallback() Adding buffer of length %d\n",
  713. CB->DataSize) );
  714. status=SaAddBuffer(Sah, CB);
  715. _SlibDebug(_WARN_ && status!=NoErrors,
  716. printf("SaAddBuffer() %s\n", ScGetErrorStr(status)) );
  717. }
  718. break;
  719. case CB_RELEASE_BUFFER:
  720. _SlibDebug(_CALLBACK_,
  721. printf("ACompressCallback received CB_RELEASE_BUFFER message\n"));
  722. if (CB->DataType==CB_DATA_COMPRESSED && CB->Data && CB->DataUsed)
  723. {
  724. SlibPin_t *dstpin=slibGetPin(Info, SLIB_DATA_AUDIO);
  725. if (dstpin)
  726. {
  727. slibAddBufferToPin(dstpin, CB->Data, CB->DataUsed,
  728. Info->AudioPTimeCode);
  729. Info->AudioPTimeCode=SLIB_TIME_NONE;
  730. if (!slibCommitBuffers(Info, FALSE))
  731. CB->Action = CB_ACTION_END;
  732. }
  733. }
  734. else if (CB->Data)
  735. SlibFreeBuffer(CB->Data);
  736. break;
  737. case CB_FRAME_START:
  738. _SlibDebug(_CALLBACK_||_TIMECODE_,
  739. printf("ACompress CB_FRAME_START: TimeStamp=%ld Frame=%d\n",
  740. CB->TimeStamp, Info->VideoFramesProcessed
  741. ) );
  742. if (SlibTimeIsInValid(Info->AudioPTimeCode))
  743. {
  744. Info->AudioPTimeCode=CB->TimeStamp;
  745. _SlibDebug(_TIMECODE_,
  746. printf("AudioPTimeCode=%ld\n", Info->AudioPTimeCode) );
  747. _SlibDebug(_WARN_ && (Info->AudioTimeStamp-CB->TimeStamp>400 ||
  748. CB->TimeStamp-Info->AudioTimeStamp>400),
  749. printf("Bad Audio Time: AudioPTimeCode=%ld AudioTimestamp=%ld\n",
  750. Info->AudioPTimeCode, Info->AudioTimeStamp) );
  751. }
  752. break;
  753. }
  754. return(NoErrors);
  755. }
  756. int ADecompressCallback(SvHandle_t Sah, SaCallbackInfo_t *CB, SaInfo_t *SaInfo)
  757. {
  758. int status;
  759. unsigned dword size;
  760. SlibInfo_t *Info=(SlibInfo_t *)CB->UserData;
  761. _SlibDebug(_DEBUG_, printf("ADecompressCallback()\n") );
  762. switch (CB->Message)
  763. {
  764. case CB_END_BUFFERS:
  765. _SlibDebug(_CALLBACK_,
  766. printf("ADecompressCallback() CB_END_BUFFER\n") );
  767. if (CB->DataType==CB_DATA_COMPRESSED)
  768. {
  769. SlibTime_t ptimestamp, timediff;
  770. slibSetMaxInput(Info, 2000*1024); /* set limit for input data */
  771. CB->Data = SlibGetBuffer(Info, SLIB_DATA_AUDIO, &size,
  772. &ptimestamp);
  773. slibSetMaxInput(Info, 0); /* clear limit */
  774. CB->DataSize = size;
  775. if (SlibTimeIsValid(ptimestamp))
  776. {
  777. Info->AudioPTimeCode=ptimestamp;
  778. _SlibDebug(_CALLBACK_||_TIMECODE_,
  779. printf("AudioPTimeCode=%ld\n", Info->AudioPTimeCode) );
  780. ptimestamp-=Info->AudioPTimeBase;
  781. timediff=ptimestamp-Info->AudioTimeStamp;
  782. if (SlibTimeIsInValid(Info->AudioTimeStamp))
  783. Info->AudioTimeStamp=ptimestamp;
  784. else if (timediff<-300 || timediff>300) /* time is far off */
  785. {
  786. _SlibDebug(_WARN_||_TIMECODE_,
  787. printf("Updating AudioTimeStamp %ld->%ld (diff=%ld)\n",
  788. Info->AudioTimeStamp, ptimestamp,timediff) );
  789. Info->AudioTimeStamp=ptimestamp;
  790. if (SlibTimeIsValid(Info->VideoTimeStamp))
  791. {
  792. /* Make sure a NEW audio time is not way out of
  793. * sync with video time.
  794. * This can happen after an End of Sequence.
  795. */
  796. timediff=ptimestamp-Info->VideoTimeStamp;
  797. if (timediff<-6000)
  798. {
  799. /* assign audio time to video time */
  800. Info->VideoPTimeCode=SLIB_TIME_NONE;
  801. Info->VideoPTimeBase=Info->AudioPTimeBase;
  802. Info->VideoTimeStamp=ptimestamp;
  803. }
  804. }
  805. }
  806. }
  807. if (CB->Data)
  808. {
  809. if (CB->DataSize>0)
  810. {
  811. CB->DataType = CB_DATA_COMPRESSED;
  812. _SlibDebug(_CALLBACK_,
  813. printf("ADecompressCallback() Adding buffer of length %d\n",
  814. CB->DataSize) );
  815. status = SaAddBuffer(Sah, CB);
  816. }
  817. else
  818. SlibFreeBuffer(CB->Data);
  819. }
  820. else
  821. {
  822. _SlibDebug(_WARN_ || _CALLBACK_,
  823. printf("ADecompressCallback() got no data\n") );
  824. CB->Action = CB_ACTION_END;
  825. return(NoErrors);
  826. }
  827. }
  828. break;
  829. case CB_RELEASE_BUFFER:
  830. _SlibDebug(_CALLBACK_,
  831. printf("ADecompressCallback() CB_RELEASE_BUFFER\n"));
  832. if (CB->DataType==CB_DATA_COMPRESSED && CB->Data)
  833. SlibFreeBuffer(CB->Data);
  834. break;
  835. case CB_PROCESSING:
  836. _SlibDebug(_CALLBACK_,
  837. printf("ADecompressCallback() CB_PROCESSING\n") );
  838. break;
  839. case CB_CODEC_DONE:
  840. _SlibDebug(_CALLBACK_,
  841. printf("ADecompressCallback() CB_CODEC_DONE\n") );
  842. break;
  843. }
  844. CB->Action = CB_ACTION_CONTINUE;
  845. return(NoErrors);
  846. }
  847. static void slibInitInfo(SlibInfo_t *Info)
  848. {
  849. _SlibDebug(_DEBUG_, printf("slibInitInfo()\n") );
  850. Info->Type = SLIB_TYPE_UNKNOWN;
  851. Info->Mode = SLIB_MODE_NONE;
  852. Info->Svh = NULL;
  853. Info->Sah = NULL;
  854. Info->Sch = NULL;
  855. Info->NeedAccuracy = FALSE;
  856. Info->TotalBitRate = 0;
  857. Info->MuxBitRate = 0;
  858. Info->SystemTimeStamp = 0;
  859. /* Audio parameters */
  860. Info->AudioStreams = 0;
  861. Info->SamplesPerSec = 0;
  862. Info->BitsPerSample = 0;
  863. Info->Channels = 0;
  864. Info->AudioBitRate = 0;
  865. Info->AudioMainStream = 0;
  866. Info->AudioType = SLIB_TYPE_UNKNOWN;
  867. /* Video parameters */
  868. Info->VideoStreams = 0;
  869. Info->Width = 0;
  870. Info->Height = 0;
  871. Info->Stride = 0;
  872. Info->VideoBitRate = 0;
  873. Info->FramesPerSec = 0.0F;
  874. Info->ImageSize = 0;
  875. Info->AudioPID = -1;
  876. Info->VideoPID = -1;
  877. Info->VideoMainStream = 0;
  878. Info->VideoType = SLIB_TYPE_UNKNOWN;
  879. /* Data Exchange */
  880. Info->Offset = 0;
  881. Info->Pins = NULL;
  882. Info->PinCount = 0;
  883. Info->IOError = FALSE;
  884. Info->MaxBytesInput = 0;
  885. Info->BytesProcessed = 0;
  886. /* stream dependent stuff */
  887. Info->VideoLength = 0;
  888. Info->VideoLengthKnown = FALSE;
  889. Info->VideoTimeStamp = SLIB_TIME_NONE;
  890. Info->VideoFrameDuration = 0;
  891. Info->AudioLength = 0;
  892. Info->AudioLengthKnown = FALSE;
  893. Info->AudioTimeStamp = SLIB_TIME_NONE;
  894. Info->LastAudioTimeStamp = SLIB_TIME_NONE;
  895. Info->KeySpacing = 0;
  896. Info->SubKeySpacing = 0;
  897. Info->VideoPTimeBase = SLIB_TIME_NONE;
  898. Info->VideoPTimeCode = SLIB_TIME_NONE;
  899. Info->VideoDTimeCode = SLIB_TIME_NONE;
  900. Info->LastAudioPTimeCode = SLIB_TIME_NONE;
  901. Info->LastVideoPTimeCode = SLIB_TIME_NONE;
  902. Info->LastVideoDTimeCode = SLIB_TIME_NONE;
  903. Info->AvgVideoTimeDiff = 0;
  904. Info->VarVideoTimeDiff = 0;
  905. Info->AudioPTimeBase = SLIB_TIME_NONE;
  906. Info->AudioPTimeCode = SLIB_TIME_NONE;
  907. Info->AudioDTimeCode = SLIB_TIME_NONE;
  908. Info->VideoFramesProcessed=0;
  909. /* Encoding info */
  910. Info->HeaderProcessed = FALSE;
  911. Info->PacketCount = 0;
  912. Info->BytesSincePack = 0;
  913. /* Miscellaneous */
  914. Info->SlibCB = NULL;
  915. Info->SlibCBUserData = NULL;
  916. Info->Fd = -1;
  917. Info->FileSize = 0;
  918. Info->FileBufSize = 50*1024;
  919. Info->CompBufSize = 2*1024;
  920. Info->PacketSize = 512;
  921. Info->AudioFormat = NULL;
  922. Info->VideoFormat = NULL;
  923. Info->CompAudioFormat = NULL;
  924. Info->CompVideoFormat = NULL;
  925. Info->CodecVideoFormat = NULL;
  926. Info->VideoCodecState = SLIB_CODEC_STATE_NONE;
  927. Info->AudioCodecState = SLIB_CODEC_STATE_NONE;
  928. Info->Imagebuf = NULL;
  929. Info->IntImagebuf = NULL;
  930. Info->IntImageSize = 0;
  931. Info->CodecImagebuf = NULL;
  932. Info->CodecImageSize = 0;
  933. Info->Multibuf = NULL;
  934. Info->MultibufSize = 0;
  935. Info->Audiobuf = NULL;
  936. Info->AudiobufSize = 0;
  937. Info->AudiobufUsed = 0;
  938. Info->OverflowSize = 1500*1024;
  939. Info->VBVbufSize = 0;
  940. Info->stats = NULL;
  941. Info->dbg = NULL;
  942. }
  943. /*
  944. ** Name: slibGetDataFormat
  945. ** Purpose: Find out the type of some multmedia data.
  946. */
  947. static SlibType_t slibGetDataFormat(unsigned char *buf, int size,
  948. dword *headerstart,
  949. dword *headersize)
  950. {
  951. dword i, count;
  952. unsigned char *bufptr;
  953. if (headersize)
  954. *headersize=0;
  955. if (size<4 || !buf)
  956. return(SLIB_TYPE_UNKNOWN);
  957. /*
  958. ** H261 video stream file
  959. */
  960. if ((buf[0] == 0x00) &&
  961. (buf[1] == 0x01) &&
  962. (buf[2] & 0xF0)==0x00)
  963. return(SLIB_TYPE_H261);
  964. /*
  965. ** H263 video stream file
  966. */
  967. if ((buf[0] == 0x00) &&
  968. (buf[1] == 0x00) &&
  969. (buf[2] == 0x80) &&
  970. (buf[3] & 0xF8)==0x00)
  971. return(SLIB_TYPE_H263);
  972. /*
  973. ** JFIF file (ffd8 = Start-Of-Image marker)
  974. */
  975. if (buf[0] == 0xff && buf[1] == 0xd8)
  976. return(SLIB_TYPE_JFIF);
  977. /*
  978. ** QUICKTIME JPEG file (4 ignored bytes, "mdat", ff, d8, ff)
  979. */
  980. if ((strncmp(&buf[4], "mdat", 4) == 0 ) &&
  981. (buf[8] == 0xff) &&
  982. (buf[9] == 0xd8) &&
  983. (buf[10] == 0xff))
  984. return(SLIB_TYPE_JPEG_QUICKTIME);
  985. /*
  986. ** AVI RIFF file
  987. */
  988. if ( strncmp(buf, "RIFF", 4) == 0 )
  989. {
  990. if (strncmp(&buf[8], "WAVE",4) == 0)
  991. return(SLIB_TYPE_PCM_WAVE);
  992. else if (strncmp(&buf[8], "AVI ",4) == 0)
  993. return(SLIB_TYPE_AVI);
  994. else
  995. return(SLIB_TYPE_RIFF);
  996. }
  997. /*
  998. ** BMP file
  999. */
  1000. if (buf[0] == 'B' && buf[1]=='M')
  1001. return(SLIB_TYPE_BMP);
  1002. /*
  1003. ** Dolby AC-3 stream
  1004. */
  1005. if ((buf[0]==0x77 && buf[1] == 0x0B) || /* may be byte reversed */
  1006. (buf[0]==0x0B && buf[1] == 0x77))
  1007. return(SLIB_TYPE_AC3_AUDIO);
  1008. /*
  1009. ** Sun Raster file
  1010. */
  1011. if ((buf[0]==0x59 && buf[1] == 0xA6) || /* may be byte reversed */
  1012. (buf[0]==0x6A && buf[1] == 0x95))
  1013. return(SLIB_TYPE_RASTER);
  1014. /*
  1015. ** SLIB file
  1016. */
  1017. if ((buf[0] == 'S') && (buf[1] == 'L') &&
  1018. (buf[2] == 'I') && (buf[3] == 'B'))
  1019. {
  1020. if ((buf[4] == 'H') && (buf[5] == 'U') && /* SLIB Huffman Stream */
  1021. (buf[6] == 'F') && (buf[7] == 'F'))
  1022. return(SLIB_TYPE_SHUFF);
  1023. else
  1024. return(SLIB_TYPE_SLIB);
  1025. }
  1026. /*
  1027. ** MPEG II Transport Stream
  1028. */
  1029. if (buf[0] == MPEG_TSYNC_CODE &&
  1030. (buf[3]&0x30)!=0) /* adaptation field value is not reserved */
  1031. return(SLIB_TYPE_MPEG_TRANSPORT);
  1032. if (buf[0] == MPEG_TSYNC_CODE && buf[1] == 0x1F &&
  1033. buf[2]==0xFF) /* NULL PID */
  1034. return(SLIB_TYPE_MPEG_TRANSPORT);
  1035. /* search for mpeg startcode 000001 */
  1036. bufptr=buf;
  1037. for (i=4, count=size;
  1038. i<count && (bufptr[0]!=0x00 || bufptr[1]!=0x00 || bufptr[2]!=0x01); i++)
  1039. bufptr++;
  1040. count-=i-4;
  1041. if (headerstart)
  1042. *headerstart=i-4;
  1043. /*
  1044. ** MPEG video file
  1045. */
  1046. if (bufptr[0] == 0x00 && bufptr[1] == 0x00 &&
  1047. bufptr[2] == 0x01 && bufptr[3] == 0xB3)
  1048. {
  1049. if (headersize) /* calculate the header size */
  1050. {
  1051. *headersize=12; /* minimum size is twelve bytes */
  1052. if (count>11 && (bufptr[11]&0x02)) /* load_intra_quantizer_matrixe */
  1053. {
  1054. *headersize+=64;
  1055. if (count>75 && bufptr[64+11]&0x01) /* load_non_intra_quantizer_matrix */
  1056. *headersize+=64;
  1057. }
  1058. else if (count>11 && (bufptr[11]&0x01)) /* load_non_intra_quant_matrix */
  1059. *headersize+=64;
  1060. }
  1061. return(SLIB_TYPE_MPEG1_VIDEO);
  1062. }
  1063. /*
  1064. ** MPEG I Systems file
  1065. */
  1066. if ((bufptr[0] == 0x00) && (bufptr[1] == 0x00) &&
  1067. (bufptr[2] == 0x01) && (bufptr[3] == 0xba) &&
  1068. ((bufptr[4]&0xF0) == 0x20))
  1069. return(SLIB_TYPE_MPEG_SYSTEMS);
  1070. /*
  1071. ** MPEG II Program Stream
  1072. */
  1073. if ((bufptr[0] == 0x00) && (bufptr[1] == 0x00) &&
  1074. (bufptr[2] == 0x01) && (bufptr[3] == 0xba) &&
  1075. ((bufptr[4]&0xC0) == 0x40))
  1076. return(SLIB_TYPE_MPEG_PROGRAM);
  1077. /*
  1078. ** H263 video stream file
  1079. */
  1080. /* search for H.263 picture startcode 000000000000000100000 */
  1081. for (bufptr=buf, i=0, count=size-4; i<count; i++, bufptr++)
  1082. {
  1083. if ((bufptr[0] == 0x00) &&
  1084. (bufptr[1] == 0x00) &&
  1085. (bufptr[2] == 0x80) &&
  1086. (bufptr[3] & 0xF8)==0x00)
  1087. return(i>=12 ? SLIB_TYPE_RTP_H263 : SLIB_TYPE_H263);
  1088. }
  1089. /*
  1090. ** H261 video stream file
  1091. */
  1092. /* search for H.261 picture startcode 00000000000000010000 */
  1093. for (bufptr=buf, i=0, count=size-3; i<count; i++, bufptr++)
  1094. {
  1095. if ((bufptr[0] == 0x00) &&
  1096. (bufptr[1] == 0x01) &&
  1097. (bufptr[2] & 0xF0)==0x00)
  1098. return(i>=12 ? SLIB_TYPE_RTP_H261 : SLIB_TYPE_H261);
  1099. }
  1100. /*
  1101. ** MPEG audio stream file
  1102. */
  1103. if (buf[0]==0xFF && (buf[1] & 0xF0)==0xF0)
  1104. return(SLIB_TYPE_MPEG1_AUDIO);
  1105. #ifdef G723_SUPPORT
  1106. //Detect the RATEFLAG and VADFLAG in each frame in this
  1107. //buffer.
  1108. {
  1109. int i,iFrameSize,iNoOfFrames;
  1110. BOOL bRateFlag; //0 for High rate(6.3K 24bit), 1 for low rate(5.3K,20bit)
  1111. BOOL bVADflag; // 0 for Active speech 1 for Non-speech
  1112. BOOL bTypeG723 = TRUE; //Initialized to say that it's a g723 media stream
  1113. if(buf[0] & 0x1)
  1114. {
  1115. bRateFlag = TRUE; //Low rate 5.3K
  1116. iFrameSize = 20;
  1117. }
  1118. else
  1119. {
  1120. bRateFlag = FALSE; //High Rate 6.3K
  1121. iFrameSize = 24;
  1122. }
  1123. if(buf[0] & 0x2)
  1124. bVADflag =TRUE; //Non-Speech
  1125. else
  1126. bVADflag = FALSE; //Active-Speech
  1127. iNoOfFrames = size/iFrameSize;
  1128. if (iNoOfFrames>15) iNoOfFrames=15; /* just check first 15 frames */
  1129. //Leave the first frame.The first frame is used to extract
  1130. // the above information.Check for this info in the remaining
  1131. // frames.If it exists in all frames,the audio is G723 ,otherwise
  1132. // audio type is Unknown.
  1133. for(i =1; i < iNoOfFrames;i++)
  1134. {
  1135. //Search for RateFlag and bVADflag for each frame
  1136. if(((buf[i*iFrameSize] & 0x1) == bRateFlag) &&
  1137. ((buf[i*iFrameSize] & 0x2) == bVADflag))
  1138. continue;
  1139. //type is Unknown ,Set the flag to false and
  1140. //break from the for loop
  1141. bTypeG723 = FALSE;
  1142. break;
  1143. }
  1144. if(bTypeG723)
  1145. return(SLIB_TYPE_G723);
  1146. }
  1147. #endif /* G723_SUPPORT */
  1148. _SlibDebug(_WARN_, printf("slibGetDataFormat() Unknown file format\n") );
  1149. return(SLIB_TYPE_UNKNOWN);
  1150. }
  1151. SlibStatus_t SlibQueryData(void *databuf, unsigned dword databufsize,
  1152. SlibQueryInfo_t *qinfo)
  1153. {
  1154. SlibInfo_t *Info=NULL;
  1155. SlibStatus_t status;
  1156. if (!databuf)
  1157. return(SlibErrorBadArgument);
  1158. if (databufsize==0)
  1159. return(SlibErrorBufSize);
  1160. qinfo->Bitrate=0;
  1161. qinfo->VideoStreams=0;
  1162. qinfo->Width=0;
  1163. qinfo->Height=0;
  1164. qinfo->VideoBitrate=0;
  1165. qinfo->FramesPerSec=0.0F;
  1166. qinfo->VideoLength=0;
  1167. qinfo->AudioStreams=0;
  1168. qinfo->SamplesPerSec=0;
  1169. qinfo->BitsPerSample=0;
  1170. qinfo->Channels=0;
  1171. qinfo->AudioBitrate=0;
  1172. qinfo->AudioLength=0;
  1173. qinfo->Type = slibGetDataFormat(databuf, databufsize,
  1174. &qinfo->HeaderStart, &qinfo->HeaderSize);
  1175. if (qinfo->Type!=SLIB_TYPE_UNKNOWN)
  1176. {
  1177. if ((Info = (SlibInfo_t *)ScAlloc(sizeof(SlibInfo_t))) == NULL)
  1178. return(SlibErrorMemory);
  1179. slibInitInfo(Info);
  1180. Info->Mode = SLIB_MODE_DECOMPRESS;
  1181. Info->Type = qinfo->Type;
  1182. slibAddPin(Info, SLIB_DATA_COMPRESSED, "Compressed");
  1183. status=slibManageUserBuffer(NULL, databuf, databufsize, NULL);
  1184. if (status==SlibErrorNone)
  1185. status=slibAddBufferToPin(slibGetPin(Info, SLIB_DATA_COMPRESSED),
  1186. databuf, databufsize, SLIB_TIME_NONE);
  1187. if (status!=SlibErrorNone)
  1188. {
  1189. SlibClose((SlibHandle_t)Info);
  1190. return(status);
  1191. }
  1192. slibAddPin(Info, SLIB_DATA_AUDIO, "Audio");
  1193. slibAddPin(Info, SLIB_DATA_VIDEO, "Video");
  1194. SlibUpdateAudioInfo(Info);
  1195. SlibUpdateVideoInfo(Info);
  1196. if (Info->TotalBitRate==0)
  1197. qinfo->Bitrate=Info->AudioBitRate+
  1198. ((Info->VideoBitRate>100000000)?0:Info->VideoBitRate);
  1199. else
  1200. qinfo->Bitrate=Info->TotalBitRate;
  1201. qinfo->VideoStreams=Info->VideoStreams;
  1202. qinfo->Width=Info->Width;
  1203. qinfo->Height=Info->Height;
  1204. qinfo->VideoBitrate=Info->VideoBitRate;
  1205. qinfo->FramesPerSec=Info->FramesPerSec;
  1206. qinfo->VideoLength=Info->VideoLength;
  1207. qinfo->AudioStreams=Info->AudioStreams;
  1208. qinfo->SamplesPerSec=Info->SamplesPerSec;
  1209. qinfo->BitsPerSample=Info->BitsPerSample;
  1210. qinfo->Channels=Info->Channels;
  1211. qinfo->AudioBitrate=Info->AudioBitRate;
  1212. qinfo->AudioLength=Info->AudioLength;
  1213. SlibClose((SlibHandle_t)Info);
  1214. return(SlibErrorNone);
  1215. }
  1216. return(SlibErrorUnsupportedFormat);
  1217. }
  1218. /************************** The Main Slib API ***********************/
  1219. SlibStatus_t SlibOpen(SlibHandle_t *handle, SlibMode_t smode,
  1220. SlibType_t *stype, SlibMessage_t (*slibCB)(SlibHandle_t,
  1221. SlibMessage_t, SlibCBParam1_t, SlibCBParam2_t, void *),
  1222. void *cbuserdata)
  1223. {
  1224. SlibInfo_t *Info=NULL;
  1225. SlibStatus_t status;
  1226. _SlibDebug(_VERBOSE_,printf("SlibOpen()\n") );
  1227. if (!handle)
  1228. return(SlibErrorBadHandle);
  1229. *handle = NULL;
  1230. if (!stype)
  1231. return(SlibErrorBadArgument);
  1232. if (!slibCB)
  1233. return(SlibErrorBadArgument);
  1234. if (smode == SLIB_MODE_COMPRESS)
  1235. {
  1236. if (SlibFindEnumEntry(_listCompressTypes, *stype)==NULL)
  1237. return(SlibErrorUnsupportedFormat);
  1238. }
  1239. if ((Info = (SlibInfo_t *)ScAlloc(sizeof(SlibInfo_t))) == NULL)
  1240. return(SlibErrorMemory);
  1241. slibInitInfo(Info);
  1242. slibAddPin(Info, SLIB_DATA_COMPRESSED, "Compressed");
  1243. Info->SlibCB = slibCB;
  1244. Info->SlibCBUserData = cbuserdata;
  1245. *handle=(SlibHandle_t)Info;
  1246. if ((status=slibOpen(handle, smode, stype))!=SlibErrorNone)
  1247. *handle = NULL;
  1248. return(status);
  1249. }
  1250. SlibStatus_t SlibOpenSync(SlibHandle_t *handle, SlibMode_t smode,
  1251. SlibType_t *stype, void *buffer, unsigned dword bufsize)
  1252. {
  1253. SlibInfo_t *Info=NULL;
  1254. SlibStatus_t status;
  1255. _SlibDebug(_VERBOSE_,printf("SlibOpenSync()\n") );
  1256. if (!handle)
  1257. return(SlibErrorBadHandle);
  1258. *handle = NULL;
  1259. if (!stype)
  1260. return(SlibErrorBadArgument);
  1261. if (smode == SLIB_MODE_COMPRESS)
  1262. {
  1263. if (SlibFindEnumEntry(_listCompressTypes, *stype)==NULL)
  1264. return(SlibErrorUnsupportedFormat);
  1265. }
  1266. else if (smode == SLIB_MODE_DECOMPRESS)
  1267. {
  1268. /* for decompression we need the first buffer to open the codecs */
  1269. if (!buffer || bufsize==0)
  1270. return(SlibErrorBadArgument);
  1271. }
  1272. if ((Info = (SlibInfo_t *)ScAlloc(sizeof(SlibInfo_t))) == NULL)
  1273. return(SlibErrorMemory);
  1274. slibInitInfo(Info);
  1275. Info->Mode=smode;
  1276. slibAddPin(Info, SLIB_DATA_COMPRESSED, "Compressed");
  1277. if (smode == SLIB_MODE_DECOMPRESS)
  1278. {
  1279. status=SlibAddBuffer((SlibHandle_t *)Info, SLIB_DATA_COMPRESSED, buffer, bufsize);
  1280. if (status!=SlibErrorNone)
  1281. return(status);
  1282. }
  1283. *handle=(SlibHandle_t)Info;
  1284. if ((status=slibOpen(handle, smode, stype))!=SlibErrorNone)
  1285. *handle = NULL;
  1286. return(status);
  1287. }
  1288. SlibStatus_t SlibOpenFile(SlibHandle_t *handle, SlibMode_t smode,
  1289. SlibType_t *stype, char *filename)
  1290. {
  1291. SlibInfo_t *Info=NULL;
  1292. SlibStatus_t status;
  1293. _SlibDebug(_VERBOSE_,printf("SlibOpenFile()\n") );
  1294. if (!handle)
  1295. return(SlibErrorBadHandle);
  1296. *handle = NULL;
  1297. if (!stype)
  1298. return(SlibErrorBadArgument);
  1299. if (!filename)
  1300. return(SlibErrorBadArgument);
  1301. if (smode == SLIB_MODE_COMPRESS)
  1302. {
  1303. if (SlibFindEnumEntry(_listCompressTypes, *stype)==NULL)
  1304. return(SlibErrorUnsupportedFormat);
  1305. if ((Info = (SlibInfo_t *) ScAlloc(sizeof(SlibInfo_t))) == NULL)
  1306. return(SlibErrorMemory);
  1307. slibInitInfo(Info);
  1308. Info->Fd = ScFileOpenForWriting(filename, TRUE);
  1309. if (Info->Fd<0)
  1310. {
  1311. ScFree(Info);
  1312. return(SlibErrorWriting);
  1313. }
  1314. *handle=(SlibHandle_t)Info;
  1315. if ((status=slibOpen(handle, smode, stype))!=SlibErrorNone)
  1316. *handle = NULL;
  1317. return(status);
  1318. }
  1319. else if (smode == SLIB_MODE_DECOMPRESS)
  1320. {
  1321. if ((Info = (SlibInfo_t *)ScAlloc(sizeof(SlibInfo_t))) == NULL)
  1322. return(SlibErrorMemory);
  1323. slibInitInfo(Info);
  1324. Info->Fd = ScFileOpenForReading(filename);
  1325. if (Info->Fd<0)
  1326. {
  1327. ScFree(Info);
  1328. return(SlibErrorReading);
  1329. }
  1330. ScFileSize(filename, &Info->FileSize);
  1331. *handle=(SlibHandle_t)Info;
  1332. if ((status=slibOpen(handle, smode, stype))!=SlibErrorNone)
  1333. *handle = NULL;
  1334. return(status);
  1335. }
  1336. else
  1337. return(SlibErrorBadMode);
  1338. }
  1339. static SlibStatus_t slibOpen(SlibHandle_t *handle, SlibMode_t smode,
  1340. SlibType_t *stype)
  1341. {
  1342. SlibInfo_t *Info=(SlibInfo_t *)*handle;
  1343. unsigned char *buf;
  1344. unsigned dword size;
  1345. _SlibDebug(_VERBOSE_,printf("SlibOpenFile()\n") );
  1346. if (!Info)
  1347. return(SlibErrorMemory);
  1348. if (!stype)
  1349. return(SlibErrorBadArgument);
  1350. if (Info->SlibCB)
  1351. {
  1352. SlibMessage_t result;
  1353. _SlibDebug(_VERBOSE_,
  1354. printf("slibOpen() SlibCB(SLIB_MSG_OPEN)\n") );
  1355. result=(*(Info->SlibCB))((SlibHandle_t)Info,
  1356. SLIB_MSG_OPEN, (SlibCBParam1_t)0,
  1357. (SlibCBParam2_t)0, (void *)Info->SlibCBUserData);
  1358. }
  1359. if (smode == SLIB_MODE_COMPRESS)
  1360. {
  1361. Info->Mode = smode;
  1362. Info->Type = *stype;
  1363. SlibUpdateAudioInfo(Info);
  1364. SlibUpdateVideoInfo(Info);
  1365. switch (Info->Type)
  1366. {
  1367. #ifdef MPEG_SUPPORT
  1368. case SLIB_TYPE_MPEG_SYSTEMS:
  1369. case SLIB_TYPE_MPEG_SYSTEMS_MPEG2:
  1370. case SLIB_TYPE_MPEG1_VIDEO:
  1371. Info->VideoStreams = 1;
  1372. if (SvOpenCodec (Info->Type==SLIB_TYPE_MPEG_SYSTEMS_MPEG2 ?
  1373. SV_MPEG2_ENCODE : SV_MPEG_ENCODE,
  1374. &Info->Svh)!=SvErrorNone)
  1375. {
  1376. SlibClose((SlibHandle_t)Info);
  1377. return(SlibErrorUnsupportedFormat);
  1378. }
  1379. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1380. slibAddPin(Info, SLIB_DATA_VIDEO, "Video");
  1381. if (Info->Type==SLIB_TYPE_MPEG1_VIDEO)
  1382. break;
  1383. case SLIB_TYPE_MPEG1_AUDIO:
  1384. Info->AudioStreams = 1;
  1385. if (SaOpenCodec (SA_MPEG_ENCODE, &Info->Sah)!=SvErrorNone)
  1386. {
  1387. SlibClose((SlibHandle_t)Info);
  1388. return(SlibErrorUnsupportedFormat);
  1389. }
  1390. Info->AudioCodecState=SLIB_CODEC_STATE_OPEN;
  1391. slibAddPin(Info, SLIB_DATA_AUDIO, "Audio");
  1392. break;
  1393. case SLIB_TYPE_MPEG2_VIDEO:
  1394. Info->VideoStreams = 1;
  1395. if (SvOpenCodec (SV_MPEG2_ENCODE, &Info->Svh)!=SvErrorNone)
  1396. {
  1397. SlibClose((SlibHandle_t)Info);
  1398. return(SlibErrorUnsupportedFormat);
  1399. }
  1400. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1401. slibAddPin(Info, SLIB_DATA_VIDEO, "Video");
  1402. break;
  1403. #endif /* MPEG_SUPPORT */
  1404. #ifdef H261_SUPPORT
  1405. case SLIB_TYPE_H261:
  1406. Info->VideoStreams = 1;
  1407. if (SvOpenCodec (SV_H261_ENCODE, &Info->Svh)!=SvErrorNone)
  1408. {
  1409. SlibClose((SlibHandle_t)Info);
  1410. return(SlibErrorUnsupportedFormat);
  1411. }
  1412. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1413. slibAddPin(Info, SLIB_DATA_VIDEO, "Video");
  1414. break;
  1415. #endif /* H261_SUPPORT */
  1416. #ifdef H263_SUPPORT
  1417. case SLIB_TYPE_H263:
  1418. Info->VideoStreams = 1;
  1419. if (SvOpenCodec (SV_H263_ENCODE, &Info->Svh)!=SvErrorNone)
  1420. {
  1421. SlibClose((SlibHandle_t)Info);
  1422. return(SlibErrorUnsupportedFormat);
  1423. }
  1424. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1425. slibAddPin(Info, SLIB_DATA_VIDEO, "Video");
  1426. break;
  1427. #endif /* H263_SUPPORT */
  1428. #ifdef HUFF_SUPPORT
  1429. case SLIB_TYPE_SHUFF:
  1430. Info->VideoStreams = 1;
  1431. if (SvOpenCodec (SV_HUFF_ENCODE, &Info->Svh)!=SvErrorNone)
  1432. {
  1433. SlibClose((SlibHandle_t)Info);
  1434. return(SlibErrorUnsupportedFormat);
  1435. }
  1436. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1437. slibAddPin(Info, SLIB_DATA_VIDEO, "Video");
  1438. break;
  1439. #endif /* HUFF_SUPPORT */
  1440. #ifdef G723_SUPPORT
  1441. case SLIB_TYPE_G723:
  1442. Info->AudioStreams = 1;
  1443. if (SaOpenCodec (SA_G723_ENCODE, &Info->Sah)!=SvErrorNone)
  1444. {
  1445. SlibClose((SlibHandle_t)Info);
  1446. return(SlibErrorUnsupportedFormat);
  1447. }
  1448. Info->AudioCodecState=SLIB_CODEC_STATE_OPEN;
  1449. slibAddPin(Info, SLIB_DATA_AUDIO, "Audio");
  1450. break;
  1451. #endif /*G723_SUPPORT*/
  1452. default:
  1453. return(SlibErrorUnsupportedFormat);
  1454. }
  1455. slibAddPin(Info, SLIB_DATA_COMPRESSED, "Compressed");
  1456. }
  1457. else if (smode == SLIB_MODE_DECOMPRESS)
  1458. {
  1459. Info->Mode = smode;
  1460. /*
  1461. ** Determine the input data type
  1462. */
  1463. if (slibLoadPin(Info, SLIB_DATA_COMPRESSED)==NULL)
  1464. return(SlibErrorReading);
  1465. if ((buf=SlibPeekBuffer(Info, SLIB_DATA_COMPRESSED, &size, NULL))==NULL
  1466. || size<=0)
  1467. {
  1468. /* couldn't get any compressed data */
  1469. SlibClose((SlibHandle_t)Info);
  1470. return(SlibErrorReading);
  1471. }
  1472. Info->Type = slibGetDataFormat(buf, size, NULL, NULL);
  1473. /* if we can't determine the type, use stype as the type */
  1474. if (Info->Type==SLIB_TYPE_UNKNOWN && stype)
  1475. Info->Type=*stype;
  1476. if (SlibFindEnumEntry(_listDecompressTypes, Info->Type)==NULL)
  1477. {
  1478. SlibClose((SlibHandle_t)Info);
  1479. return(SlibErrorUnsupportedFormat);
  1480. }
  1481. slibAddPin(Info, SLIB_DATA_AUDIO, "Audio");
  1482. slibAddPin(Info, SLIB_DATA_VIDEO, "Video");
  1483. if (SlibTypeIsMPEGMux(Info->Type))
  1484. {
  1485. /* need to select main streams for multiplexed streams */
  1486. Info->AudioMainStream=MPEG_AUDIO_STREAM_START;
  1487. Info->VideoMainStream=MPEG_VIDEO_STREAM_START;
  1488. /* private data may be needed - i.e. AC3 */
  1489. slibAddPin(Info, SLIB_DATA_PRIVATE, "Private");
  1490. }
  1491. SlibUpdateAudioInfo(Info);
  1492. SlibUpdateVideoInfo(Info);
  1493. if (Info->AudioStreams<=0)
  1494. slibRemovePin(Info, SLIB_DATA_AUDIO);
  1495. if (Info->VideoStreams<=0)
  1496. slibRemovePin(Info, SLIB_DATA_VIDEO);
  1497. slibRemovePin(Info, SLIB_DATA_PRIVATE); /* only used in init */
  1498. if (Info->AudioBitRate && Info->VideoBitRate)
  1499. {
  1500. if (!Info->VideoLengthKnown)
  1501. {
  1502. qword ms=((qword)Info->FileSize*80L)/
  1503. (Info->AudioBitRate+Info->VideoBitRate);
  1504. ms = (ms*75)/80; /* adjust for systems data */
  1505. Info->AudioLength = Info->VideoLength = (SlibTime_t)ms*100;
  1506. _SlibDebug(_SEEK_||_VERBOSE_,
  1507. ScDebugPrintf(Info->dbg,"slibOpen() FileSize=%ld VideoLength=%ld\n",
  1508. Info->FileSize, Info->VideoLength) );
  1509. }
  1510. else if (Info->VideoLengthKnown && Info->FramesPerSec)
  1511. Info->AudioLength = Info->VideoLength;
  1512. }
  1513. if (Info->TotalBitRate==0)
  1514. Info->TotalBitRate=Info->AudioBitRate +
  1515. ((Info->VideoBitRate>100000000)?0:Info->VideoBitRate);
  1516. _SlibDebug(_SEEK_||_VERBOSE_,
  1517. ScDebugPrintf(Info->dbg,"AudioLength=%ld VideoLength=%ld %s\n",
  1518. Info->AudioLength, Info->VideoLength,
  1519. Info->VideoLengthKnown?"(known)":"") );
  1520. if (Info->AudioType==SLIB_TYPE_UNKNOWN &&
  1521. Info->VideoType==SLIB_TYPE_UNKNOWN)
  1522. return(SlibErrorUnsupportedFormat);
  1523. switch (Info->AudioType)
  1524. {
  1525. case SLIB_TYPE_UNKNOWN:
  1526. break;
  1527. #ifdef MPEG_SUPPORT
  1528. case SLIB_TYPE_MPEG1_AUDIO:
  1529. if (SaOpenCodec (SA_MPEG_DECODE, &Info->Sah)!=SvErrorNone)
  1530. {
  1531. SlibClose((SlibHandle_t)Info);
  1532. return(SlibErrorUnsupportedFormat);
  1533. }
  1534. Info->AudioCodecState=SLIB_CODEC_STATE_OPEN;
  1535. break;
  1536. #endif /* MPEG_SUPPORT */
  1537. #ifdef GSM_SUPPORT
  1538. if (SaOpenCodec (SA_GSM_DECODE, &Info->Sah)!=SvErrorNone)
  1539. {
  1540. SlibClose((SlibHandle_t)Info);
  1541. return(SlibErrorUnsupportedFormat);
  1542. }
  1543. Info->AudioCodecState=SLIB_CODEC_STATE_OPEN;
  1544. break;
  1545. #endif /* GSM_SUPPORT */
  1546. #ifdef AC3_SUPPORT
  1547. case SLIB_TYPE_AC3_AUDIO:
  1548. if (SaOpenCodec (SA_AC3_DECODE, &Info->Sah)!=SvErrorNone)
  1549. {
  1550. SlibClose((SlibHandle_t)Info);
  1551. return(SlibErrorUnsupportedFormat);
  1552. }
  1553. Info->AudioCodecState=SLIB_CODEC_STATE_OPEN;
  1554. break;
  1555. #endif /* AC3_SUPPORT */
  1556. #ifdef G723_SUPPORT
  1557. case SLIB_TYPE_G723:
  1558. if (SaOpenCodec (SA_G723_DECODE, &Info->Sah)!=SvErrorNone)
  1559. {
  1560. SlibClose((SlibHandle_t)Info);
  1561. return(SlibErrorUnsupportedFormat);
  1562. }
  1563. Info->AudioCodecState=SLIB_CODEC_STATE_OPEN;
  1564. break;
  1565. #endif /* G723_SUPPORT */
  1566. } /* AudioType */
  1567. switch (Info->VideoType)
  1568. {
  1569. case SLIB_TYPE_UNKNOWN:
  1570. break;
  1571. #ifdef MPEG_SUPPORT
  1572. case SLIB_TYPE_MPEG1_VIDEO:
  1573. if (SvOpenCodec (SV_MPEG_DECODE, &Info->Svh)!=SvErrorNone)
  1574. {
  1575. SlibClose((SlibHandle_t)Info);
  1576. return(SlibErrorUnsupportedFormat);
  1577. }
  1578. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1579. _SlibDebug(_DEBUG_,printf("VideoCodecState=OPEN\n"));
  1580. break;
  1581. case SLIB_TYPE_MPEG2_VIDEO:
  1582. if (SvOpenCodec (SV_MPEG2_DECODE, &Info->Svh)!=SvErrorNone)
  1583. {
  1584. SlibClose((SlibHandle_t)Info);
  1585. return(SlibErrorUnsupportedFormat);
  1586. }
  1587. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1588. _SlibDebug(_DEBUG_,printf("VideoCodecState=OPEN\n"));
  1589. break;
  1590. #endif /* MPEG_SUPPORT */
  1591. #ifdef H261_SUPPORT
  1592. case SLIB_TYPE_H261:
  1593. if (SvOpenCodec (SV_H261_DECODE, &Info->Svh)!=SvErrorNone)
  1594. {
  1595. SlibClose((SlibHandle_t)Info);
  1596. return(SlibErrorUnsupportedFormat);
  1597. }
  1598. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1599. _SlibDebug(_DEBUG_,printf("VideoCodecState=OPEN\n"));
  1600. break;
  1601. #endif /* H261_SUPPORT */
  1602. #ifdef H263_SUPPORT
  1603. case SLIB_TYPE_H263:
  1604. if (SvOpenCodec (SV_H263_DECODE, &Info->Svh)!=SvErrorNone)
  1605. {
  1606. SlibClose((SlibHandle_t)Info);
  1607. return(SlibErrorUnsupportedFormat);
  1608. }
  1609. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1610. _SlibDebug(_DEBUG_,printf("VideoCodecState=OPEN\n"));
  1611. break;
  1612. #endif /* H263_SUPPORT */
  1613. #ifdef HUFF_SUPPORT
  1614. case SLIB_TYPE_SHUFF:
  1615. if (SvOpenCodec (SV_HUFF_DECODE, &Info->Svh)!=SvErrorNone)
  1616. {
  1617. SlibClose((SlibHandle_t)Info);
  1618. return(SlibErrorUnsupportedFormat);
  1619. }
  1620. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1621. _SlibDebug(_DEBUG_,printf("VideoCodecState=OPEN\n"));
  1622. break;
  1623. #endif /* HUFF_SUPPORT */
  1624. #ifdef JPEG_SUPPORT
  1625. case SLIB_TYPE_JPEG:
  1626. case SLIB_TYPE_MJPG:
  1627. if (SvOpenCodec (SV_JPEG_DECODE, &Info->Svh)!=SvErrorNone)
  1628. {
  1629. SlibClose((SlibHandle_t)Info);
  1630. return(SlibErrorUnsupportedFormat);
  1631. }
  1632. Info->VideoCodecState=SLIB_CODEC_STATE_OPEN;
  1633. _SlibDebug(_DEBUG_,printf("VideoCodecState=OPEN\n"));
  1634. break;
  1635. #endif /* JPEG_SUPPORT */
  1636. } /* VideoType */
  1637. }
  1638. else
  1639. return(SlibErrorBadMode);
  1640. *stype = Info->Type;
  1641. return(SlibErrorNone);
  1642. }
  1643. SlibStatus_t SlibAddBuffer(SlibHandle_t handle, SlibDataType_t dtype,
  1644. void *buffer, unsigned dword bufsize)
  1645. {
  1646. SvStatus_t status;
  1647. SlibInfo_t *Info=(SlibInfo_t *)handle;
  1648. SlibPin_t *dstpin;
  1649. if (!handle)
  1650. return(SlibErrorBadHandle);
  1651. dstpin = slibGetPin(Info, dtype);
  1652. if (dstpin==NULL || buffer==NULL)
  1653. return(SlibErrorBadArgument);
  1654. if (Info->SlibCB)
  1655. {
  1656. status=slibManageUserBuffer(Info, buffer, bufsize, NULL);
  1657. if (status!=SlibErrorNone)
  1658. return(status);
  1659. status=slibAddBufferToPin(dstpin, buffer, bufsize, SLIB_TIME_NONE);
  1660. }
  1661. else if (!SlibValidBuffer(buffer))
  1662. {
  1663. /* we need to create a SLIB allocated buffer to copy the
  1664. * output to and then add to the compressed data pin
  1665. */
  1666. unsigned char *bufptr=SlibAllocBuffer(bufsize);
  1667. if (!bufptr)
  1668. return(SlibErrorMemory);
  1669. memcpy(bufptr, buffer, bufsize);
  1670. status=slibAddBufferToPin(dstpin, bufptr, bufsize, SLIB_TIME_NONE);
  1671. }
  1672. else
  1673. status=slibAddBufferToPin(dstpin, buffer, bufsize, SLIB_TIME_NONE);
  1674. if (Info->Mode==SLIB_MODE_DECOMPRESS)
  1675. {
  1676. ScBitstream_t *BS;
  1677. Info->IOError=FALSE;
  1678. /* reset end-of-input flags in bitstream objects */
  1679. if (Info->Svh)
  1680. {
  1681. BS=SvGetDataSource(Info->Svh);
  1682. if (BS && BS->EOI) ScBSReset(BS);
  1683. }
  1684. if (Info->Sah)
  1685. {
  1686. BS=SaGetDataSource(Info->Sah);
  1687. if (BS && BS->EOI) ScBSReset(BS);
  1688. }
  1689. }
  1690. return(status);
  1691. }
  1692. SlibStatus_t SlibAddBufferEx(SlibHandle_t handle, SlibDataType_t dtype,
  1693. void *buffer, unsigned dword bufsize,
  1694. void *userdata)
  1695. {
  1696. SvStatus_t status;
  1697. SlibInfo_t *Info=(SlibInfo_t *)handle;
  1698. SlibPin_t *dstpin;
  1699. if (!handle)
  1700. return(SlibErrorBadHandle);
  1701. dstpin = slibGetPin(Info, dtype);
  1702. if (dstpin==NULL || buffer==NULL)
  1703. return(SlibErrorBadArgument);
  1704. status=slibManageUserBuffer(Info, buffer, bufsize, userdata);
  1705. if (status!=SlibErrorNone)
  1706. return(status);
  1707. status=slibAddBufferToPin(dstpin, buffer, bufsize, SLIB_TIME_NONE);
  1708. return(status);
  1709. }
  1710. SlibStatus_t slibStartVideo(SlibInfo_t *Info, SlibBoolean_t fillbuf)
  1711. {
  1712. SvStatus_t status=SvErrorNone;
  1713. _SlibDebug(_VERBOSE_,printf("slibStartVideo()\n") );
  1714. if (Info->VideoCodecState==SLIB_CODEC_STATE_NONE ||
  1715. Info->VideoCodecState==SLIB_CODEC_STATE_BEGUN)
  1716. {
  1717. _SlibDebug(_DEBUG_,ScDebugPrintf(Info->dbg,"slibStartVideo(filebuf=%d) %s\n",
  1718. fillbuf,Info->VideoCodecState==SLIB_CODEC_STATE_NONE ? "NONE" : "BEGUN") );
  1719. return(SlibErrorNone);
  1720. }
  1721. if (Info->VideoCodecState==SLIB_CODEC_STATE_OPEN)
  1722. {
  1723. _SlibDebug(_DEBUG_,ScDebugPrintf(Info->dbg,"slibStartVideo(filebuf=%d) OPEN\n",
  1724. fillbuf));
  1725. if (Info->Mode==SLIB_MODE_DECOMPRESS)
  1726. {
  1727. if (Info->Type==SLIB_TYPE_YUV_AVI)
  1728. {
  1729. Info->VideoCodecState=SLIB_CODEC_STATE_BEGUN;
  1730. _SlibDebug(_DEBUG_,ScDebugPrintf(Info->dbg,"VideoCodecState=BEGUN\n"));
  1731. }
  1732. else if (Info->Svh)
  1733. {
  1734. _SlibDebug(_DEBUG_,ScDebugPrintf(Info->dbg,"SvRegisterCallback()\n") );
  1735. status = SvRegisterCallback(Info->Svh, VDecompressCallback, (void *)Info);
  1736. /* if codec is not bitstreaming, don't use callbacks */
  1737. if (status==SlibErrorNone && SvGetDataSource(Info->Svh)==NULL)
  1738. {
  1739. _SlibDebug(_DEBUG_,ScDebugPrintf(Info->dbg,"SvRegisterCallback(NULL)\n") );
  1740. status = SvRegisterCallback(Info->Svh, NULL, NULL);
  1741. }
  1742. _SlibDebug(_WARN_ && status!=SvErrorNone,
  1743. ScDebugPrintf(Info->dbg,"SvRegisterCallback() %s\n",
  1744. ScGetErrorStr(status)) );
  1745. Info->VideoCodecState=SLIB_CODEC_STATE_INITED;
  1746. _SlibDebug(_DEBUG_,printf("VideoCodecState=INITED\n"));
  1747. }
  1748. }
  1749. else if (Info->Mode==SLIB_MODE_COMPRESS)
  1750. {
  1751. if (Info->TotalBitRate==0)
  1752. {
  1753. #ifdef MPEG_SUPPORT
  1754. if (Info->Type==SLIB_TYPE_MPEG_SYSTEMS || /* default to 1XCDROM rate */
  1755. Info->Type==SLIB_TYPE_MPEG_SYSTEMS_MPEG2)
  1756. SlibSetParamInt((SlibHandle_t)Info, SLIB_STREAM_ALL,
  1757. SLIB_PARAM_BITRATE, 44100*16*2);
  1758. #endif
  1759. slibValidateBitrates(Info); /* update bitrates */
  1760. }
  1761. if (Info->Svh)
  1762. {
  1763. status = SvRegisterCallback(Info->Svh, VCompressCallback, (void *)Info);
  1764. _SlibDebug(_WARN_ && status!=SvErrorNone,
  1765. ScDebugPrintf(Info->dbg,"SvRegisterCallback() %s\n",
  1766. ScGetErrorStr(status)) );
  1767. /* if codec is not bitstreaming, don't use callbacks */
  1768. if (status==SlibErrorNone && SvGetDataDestination(Info->Svh)==NULL)
  1769. status = SvRegisterCallback(Info->Svh, NULL, NULL);
  1770. Info->VideoCodecState=SLIB_CODEC_STATE_INITED;
  1771. _SlibDebug(_DEBUG_,ScDebugPrintf(Info->dbg,"VideoCodecState=BEGUN\n"));
  1772. }
  1773. }
  1774. }
  1775. if (Info->VideoCodecState==SLIB_CODEC_STATE_INITED ||
  1776. Info->VideoCodecState==SLIB_CODEC_STATE_REPOSITIONING)
  1777. {
  1778. _SlibDebug(_DEBUG_,ScDebugPrintf(Info->dbg,
  1779. "slibStartVideo(fillbuf=%d) INITED || REPOSITIONING\n",fillbuf));
  1780. if (Info->Mode==SLIB_MODE_DECOMPRESS)
  1781. {
  1782. if (Info->Type==SLIB_TYPE_YUV_AVI)
  1783. {
  1784. if (Info->CompVideoFormat->biCompression !=
  1785. Info->VideoFormat->biCompression &&
  1786. Info->Multibuf==NULL)
  1787. {
  1788. Info->MultibufSize=Info->ImageSize;
  1789. Info->Multibuf = SlibAllocSharedBuffer(Info->MultibufSize, NULL);
  1790. }
  1791. }
  1792. else if (Info->Svh)
  1793. {
  1794. int mbufsize;
  1795. if (1) /* fillbuf && Info->CodecVideoFormat) */
  1796. {
  1797. Info->CodecVideoFormat->biCompression=
  1798. SlibGetParamInt((SlibHandle_t)Info, SLIB_STREAM_MAINVIDEO,
  1799. SLIB_PARAM_NATIVEVIDEOFORMAT);
  1800. if (Info->CodecVideoFormat->biCompression==0)
  1801. Info->CodecVideoFormat->biCompression=
  1802. Info->VideoFormat->biCompression;
  1803. }
  1804. else
  1805. {
  1806. Info->CodecVideoFormat->biCompression=
  1807. Info->VideoFormat->biCompression;
  1808. Info->CodecVideoFormat->biBitCount=
  1809. Info->VideoFormat->biBitCount;
  1810. }
  1811. slibValidateVideoParams(Info);
  1812. _SlibDebug(_DEBUG_, ScDebugPrintf(Info->dbg,
  1813. "SvDecompressBegin(%c%c%c%c/%d bits,%c%c%c%c/%d bits)\n",
  1814. (Info->CompVideoFormat->biCompression)&0xFF,
  1815. (Info->CompVideoFormat->biCompression>>8)&0xFF,
  1816. (Info->CompVideoFormat->biCompression>>16)&0xFF,
  1817. (Info->CompVideoFormat->biCompression>>24)&0xFF,
  1818. Info->CompVideoFormat->biBitCount,
  1819. (Info->CodecVideoFormat->biCompression)&0xFF,
  1820. (Info->CodecVideoFormat->biCompression>>8)&0xFF,
  1821. (Info->CodecVideoFormat->biCompression>>16)&0xFF,
  1822. (Info->CodecVideoFormat->biCompression>>24)&0xFF,
  1823. Info->CodecVideoFormat->biBitCount) );
  1824. status=SvDecompressBegin(Info->Svh, Info->CompVideoFormat,
  1825. Info->CodecVideoFormat);
  1826. if (status==SvErrorNone)
  1827. {
  1828. Info->KeySpacing=(int)SvGetParamInt(Info->Svh, SV_PARAM_KEYSPACING);
  1829. Info->SubKeySpacing=(int)SvGetParamInt(Info->Svh,
  1830. SV_PARAM_SUBKEYSPACING);
  1831. Info->VideoCodecState=SLIB_CODEC_STATE_BEGUN;
  1832. Info->HeaderProcessed=TRUE; /* we must have processed header info */
  1833. _SlibDebug(_DEBUG_,ScDebugPrintf(Info->dbg,"VideoCodecState=BEGUN\n"));
  1834. }
  1835. else if (status==SvErrorEndBitstream)
  1836. return(SlibErrorNoBeginning);
  1837. else
  1838. {
  1839. _SlibDebug(_WARN_, ScDebugPrintf(Info->dbg,"SvDecompressBegin() %s\n",
  1840. ScGetErrorStr(status)) );
  1841. return(SlibErrorUnsupportedFormat);
  1842. }
  1843. _SlibDebug(_DEBUG_, ScDebugPrintf(Info->dbg,"SvGetDecompressSize\n") );
  1844. SvGetDecompressSize(Info->Svh, &mbufsize);
  1845. if (Info->Multibuf==NULL || Info->MultibufSize<mbufsize)
  1846. {
  1847. if (Info->Multibuf) SlibFreeBuffer(Info->Multibuf);
  1848. Info->MultibufSize=mbufsize;
  1849. Info->Multibuf = SlibAllocSharedBuffer(Info->MultibufSize, NULL);
  1850. }
  1851. }
  1852. }
  1853. else if (Info->Mode==SLIB_MODE_COMPRESS && Info->Svh)
  1854. {
  1855. status=SvCompressBegin(Info->Svh, Info->CodecVideoFormat,
  1856. Info->CompVideoFormat);
  1857. if (status==SvErrorNone)
  1858. {
  1859. Info->KeySpacing=(int)SvGetParamInt(Info->Svh, SV_PARAM_KEYSPACING);
  1860. Info->SubKeySpacing=(int)SvGetParamInt(Info->Svh,
  1861. SV_PARAM_SUBKEYSPACING);
  1862. Info->VideoCodecState=SLIB_CODEC_STATE_BEGUN;
  1863. _SlibDebug(_DEBUG_,ScDebugPrintf(Info->dbg,"VideoCodecState=BEGUN\n"));
  1864. }
  1865. else
  1866. {
  1867. _SlibDebug(_WARN_, ScDebugPrintf(Info->dbg,"SvCompressBegin() %s\n",
  1868. ScGetErrorStr(status)) );
  1869. return(SlibErrorUnsupportedFormat);
  1870. }
  1871. }
  1872. }
  1873. if (Info->VideoCodecState==SLIB_CODEC_STATE_BEGUN)
  1874. return(SlibErrorNone);
  1875. else
  1876. return(SlibErrorInit);
  1877. }
  1878. static SlibStatus_t slibStartAudio(SlibInfo_t *Info)
  1879. {
  1880. SvStatus_t status=SvErrorNone;
  1881. _SlibDebug(_VERBOSE_,printf("slibStartAudio()\n") );
  1882. if (Info->AudioCodecState==SLIB_CODEC_STATE_NONE ||
  1883. Info->AudioCodecState==SLIB_CODEC_STATE_BEGUN)
  1884. {
  1885. _SlibDebug(_DEBUG_,printf("slibStartAudio() %s\n",
  1886. Info->AudioCodecState==SLIB_CODEC_STATE_NONE ? "NONE" : "BEGUN") );
  1887. return(SlibErrorNone);
  1888. }
  1889. if (Info->AudioCodecState==SLIB_CODEC_STATE_OPEN)
  1890. {
  1891. _SlibDebug(_DEBUG_,printf("slibStartAudio() OPEN\n"));
  1892. if (Info->Sah)
  1893. {
  1894. if (Info->Mode==SLIB_MODE_DECOMPRESS)
  1895. {
  1896. status = SaRegisterCallback(Info->Sah, ADecompressCallback, (void *)Info);
  1897. if (status!=SaErrorNone)
  1898. {
  1899. _SlibDebug(_WARN_, printf("SaRegisterCallback() ",
  1900. ScGetErrorStr(status)) );
  1901. return(SlibErrorInternal);
  1902. }
  1903. status = SaSetDataSource(Info->Sah, SA_USE_BUFFER_QUEUE, 0, (void *)Info, 0);
  1904. _SlibDebug(_WARN_ && status!=SaErrorNone,
  1905. printf("SaSetDataSource() ", ScGetErrorStr(status)) );
  1906. Info->AudioCodecState=SLIB_CODEC_STATE_INITED;
  1907. _SlibDebug(_DEBUG_,printf("AudioCodecState=INITED\n"));
  1908. }
  1909. else if (Info->Mode==SLIB_MODE_COMPRESS)
  1910. {
  1911. if (Info->TotalBitRate==0)
  1912. {
  1913. #ifdef MPEG_SUPPORT
  1914. /* default to 1X CDROM rate */
  1915. if (Info->Type==SLIB_TYPE_MPEG_SYSTEMS ||
  1916. Info->Type==SLIB_TYPE_MPEG_SYSTEMS_MPEG2)
  1917. SlibSetParamInt((SlibHandle_t)Info, SLIB_STREAM_ALL,
  1918. SLIB_PARAM_BITRATE, 44100*16*2);
  1919. #endif
  1920. slibValidateBitrates(Info); /* update bitrates */
  1921. }
  1922. status = SaRegisterCallback(Info->Sah, ACompressCallback, (void *)Info);
  1923. _SlibDebug(_WARN_ && status!=SaErrorNone,
  1924. printf("SaRegisterCallback() %s\n", ScGetErrorStr(status)) );
  1925. status = SaSetDataDestination(Info->Sah, SA_USE_BUFFER_QUEUE, 0,
  1926. (void *)Info, 0);
  1927. _SlibDebug(_WARN_ && status!=SaErrorNone,
  1928. printf("SaSetDataDestination() %s\n",
  1929. ScGetErrorStr(status)) );
  1930. Info->AudioCodecState=SLIB_CODEC_STATE_INITED;
  1931. _SlibDebug(_DEBUG_,printf("AudioCodecState=INITED\n"));
  1932. }
  1933. }
  1934. }
  1935. if (Info->AudioCodecState==SLIB_CODEC_STATE_INITED ||
  1936. Info->AudioCodecState==SLIB_CODEC_STATE_REPOSITIONING)
  1937. {
  1938. _SlibDebug(_DEBUG_,printf("slibStartAudio() INITED || REPOSITIONING\n"));
  1939. if (Info->Sah)
  1940. {
  1941. if (Info->Mode==SLIB_MODE_DECOMPRESS)
  1942. {
  1943. Info->AudiobufUsed=0;
  1944. /* don't want codec to search through to much data for start */
  1945. status=SaDecompressBegin(Info->Sah, Info->CompAudioFormat,
  1946. Info->AudioFormat);
  1947. if (status==SaErrorNone)
  1948. {
  1949. Info->AudioCodecState=SLIB_CODEC_STATE_BEGUN;
  1950. _SlibDebug(_DEBUG_,printf("AudioCodecState=BEGUN\n"));
  1951. }
  1952. else if (status==SlibErrorNoBeginning)
  1953. return(SlibErrorEndOfStream);
  1954. else
  1955. {
  1956. _SlibDebug(_WARN_, printf("SaDecompressBegin() %s\n",
  1957. ScGetErrorStr(status)) );
  1958. return(SlibErrorUnsupportedFormat);
  1959. }
  1960. }
  1961. else if (Info->Mode==SLIB_MODE_COMPRESS)
  1962. {
  1963. status=SaCompressBegin(Info->Sah, Info->AudioFormat,
  1964. Info->CompAudioFormat);
  1965. if (status==SvErrorNone)
  1966. {
  1967. Info->AudioCodecState=SLIB_CODEC_STATE_BEGUN;
  1968. _SlibDebug(_DEBUG_,printf("AudioCodecState=BEGUN\n"));
  1969. }
  1970. else
  1971. {
  1972. _SlibDebug(_WARN_, printf("SaCompressBegin() %s\n",
  1973. ScGetErrorStr(status)) );
  1974. return(SlibErrorUnsupportedFormat);
  1975. }
  1976. }
  1977. }
  1978. }
  1979. return(SlibErrorNone);
  1980. }
  1981. SlibStatus_t SlibRegisterVideoBuffer(SlibHandle_t handle,
  1982. void *buffer, unsigned dword bufsize)
  1983. {
  1984. SvStatus_t status;
  1985. SlibInfo_t *Info=(SlibInfo_t *)handle;
  1986. dword mbufsize;
  1987. if (!handle)
  1988. return(SlibErrorBadHandle);
  1989. if (Info->Multibuf) SlibFreeBuffer(Info->Multibuf);
  1990. Info->MultibufSize=bufsize;
  1991. Info->Multibuf = buffer;
  1992. status=slibManageUserBuffer(Info, buffer, bufsize, NULL);
  1993. if (Info->Svh)
  1994. {
  1995. SvGetDecompressSize(Info->Svh, &mbufsize);
  1996. if (bufsize<(unsigned dword)mbufsize)
  1997. return(SlibErrorBufSize);
  1998. }
  1999. return(status);
  2000. }
  2001. SlibStatus_t SlibReadData(SlibHandle_t handle, SlibStream_t stream,
  2002. void **databuf, unsigned dword *databufsize,
  2003. SlibStream_t *readstream)
  2004. {
  2005. SlibInfo_t *Info=(SlibInfo_t *)handle;
  2006. int pinid;
  2007. SlibPin_t *pin;
  2008. SlibTime_t ptimestamp;
  2009. _SlibDebug(_VERBOSE_, printf("SlibReadDATA()\n") );
  2010. if (!handle)
  2011. return(SlibErrorBadHandle);
  2012. if (!databuf) /* we're querying to find out how much data is queued */
  2013. {
  2014. if (!databufsize)
  2015. return(SlibErrorBadArgument);
  2016. if (Info->Mode==SLIB_MODE_COMPRESS)
  2017. pinid=SLIB_DATA_COMPRESSED;
  2018. else if (stream==SLIB_STREAM_MAINVIDEO)
  2019. pinid=SLIB_DATA_VIDEO;
  2020. else if (stream==SLIB_STREAM_MAINAUDIO)
  2021. pinid=SLIB_DATA_AUDIO;
  2022. else
  2023. {
  2024. *databufsize=(unsigned dword)slibDataOnPins(Info); /* get amount of data on all pins */
  2025. return(SlibErrorNone);
  2026. }
  2027. *databufsize=(unsigned dword)slibDataOnPin(Info, SLIB_DATA_COMPRESSED);
  2028. return(SlibErrorNone);
  2029. }
  2030. if (Info->Mode==SLIB_MODE_COMPRESS)
  2031. {
  2032. pinid=SLIB_DATA_COMPRESSED;
  2033. stream=SLIB_STREAM_ALL;
  2034. /* flush out all compressed data */
  2035. if (Info->Sah)
  2036. ScBSFlush(SaGetDataDestination(Info->Sah));
  2037. if (Info->Svh)
  2038. ScBSFlush(SvGetDataDestination(Info->Svh));
  2039. }
  2040. else /* SLIB_MODE_DECOMPRESS */
  2041. {
  2042. if (stream==SLIB_STREAM_ALL && (Info->AudioStreams || Info->VideoStreams))
  2043. {
  2044. if (Info->AudioStreams==0) /* there's only video */
  2045. stream=SLIB_STREAM_MAINVIDEO;
  2046. else if (Info->VideoStreams==0) /* there's only audio */
  2047. stream=SLIB_STREAM_MAINAUDIO;
  2048. else if (slibDataOnPin(Info, SLIB_DATA_AUDIO)>
  2049. slibDataOnPin(Info, SLIB_DATA_VIDEO)) /* more audio than video */
  2050. stream=SLIB_STREAM_MAINAUDIO;
  2051. else
  2052. stream=SLIB_STREAM_MAINVIDEO;
  2053. }
  2054. switch (stream) /* translate stream to pin */
  2055. {
  2056. case SLIB_STREAM_MAINVIDEO:
  2057. pinid=SLIB_DATA_VIDEO;
  2058. break;
  2059. case SLIB_STREAM_MAINAUDIO:
  2060. pinid=SLIB_DATA_AUDIO;
  2061. break;
  2062. default:
  2063. return(SlibErrorBadStream);
  2064. }
  2065. }
  2066. if (readstream)
  2067. *readstream=stream;
  2068. pin=slibLoadPin(Info, pinid);
  2069. if (pin==NULL)
  2070. return(Info->Mode==SLIB_MODE_COMPRESS?SlibErrorNoData:SlibErrorBadStream);
  2071. if (stream==SLIB_STREAM_MAINVIDEO && Info->Mode==SLIB_MODE_DECOMPRESS &&
  2072. Info->VideoPTimeCode==SLIB_TIME_NONE &&
  2073. SlibTypeIsMPEG(Info->Type))
  2074. {
  2075. /* search from GOP start */
  2076. dword i, iend;
  2077. SlibTime_t nexttime;
  2078. unsigned char *tmpbuf, *prevbuf=NULL;
  2079. unsigned dword tmpsize, bytessearched=0;
  2080. tmpbuf=SlibGetBuffer(Info, pinid, &tmpsize, &ptimestamp);
  2081. if (tmpbuf==NULL)
  2082. return(SlibErrorEndOfStream);
  2083. do {
  2084. for (i=0, iend=tmpsize-3; i<iend; i++)
  2085. if (tmpbuf[i]==0&&tmpbuf[i+1]==0&&tmpbuf[i+2]==1&&
  2086. (tmpbuf[i+3]==0xB8||tmpbuf[i+3]==0xB3))
  2087. break;
  2088. if (i<iend)
  2089. {
  2090. slibInsertBufferOnPin(pin, tmpbuf+i, tmpsize-i, ptimestamp);
  2091. tmpbuf=NULL;
  2092. break;
  2093. }
  2094. else if (tmpbuf[i]==0 && tmpbuf[i+1]==0 && tmpbuf[i+2]==1)
  2095. {
  2096. prevbuf=tmpbuf+tmpsize-3;
  2097. tmpbuf=SlibGetBuffer(Info, pinid, &tmpsize, &nexttime);
  2098. if (tmpbuf==NULL)
  2099. return(SlibErrorEndOfStream);
  2100. if (nexttime!=SLIB_TIME_NONE)
  2101. ptimestamp=nexttime;
  2102. if (tmpbuf[0]==0xB8||tmpbuf[0]==0xB3)
  2103. {
  2104. slibInsertBufferOnPin(pin, tmpbuf, tmpsize, nexttime);
  2105. slibInsertBufferOnPin(pin, prevbuf, 3, ptimestamp);
  2106. tmpbuf=NULL;
  2107. break;
  2108. }
  2109. else
  2110. SlibFreeBuffer(prevbuf);
  2111. }
  2112. else if (tmpbuf[i+1]==0 && tmpbuf[i+2]==0)
  2113. {
  2114. prevbuf=tmpbuf+tmpsize-2;
  2115. tmpbuf=SlibGetBuffer(Info, pinid, &tmpsize, &nexttime);
  2116. if (tmpbuf==NULL)
  2117. return(SlibErrorEndOfStream);
  2118. if (nexttime!=SLIB_TIME_NONE)
  2119. ptimestamp=nexttime;
  2120. if (tmpbuf[0]==1 && (tmpbuf[1]==0xB8||tmpbuf[0]==0xB3))
  2121. {
  2122. slibInsertBufferOnPin(pin, tmpbuf, tmpsize, nexttime);
  2123. slibInsertBufferOnPin(pin, prevbuf, 2, ptimestamp);
  2124. tmpbuf=NULL;
  2125. break;
  2126. }
  2127. else
  2128. SlibFreeBuffer(prevbuf);
  2129. }
  2130. else if (tmpbuf[i+2]==0)
  2131. {
  2132. prevbuf=tmpbuf+tmpsize-1;
  2133. tmpbuf=SlibGetBuffer(Info, pinid, &tmpsize, &nexttime);
  2134. if (tmpbuf==NULL)
  2135. return(SlibErrorEndOfStream);
  2136. if (nexttime!=SLIB_TIME_NONE)
  2137. ptimestamp=nexttime;
  2138. if (tmpbuf[0]==0 && tmpbuf[1]==1 && (tmpbuf[2]==0xB8||tmpbuf[0]==0xB3))
  2139. {
  2140. slibInsertBufferOnPin(pin, tmpbuf, tmpsize, nexttime);
  2141. slibInsertBufferOnPin(pin, prevbuf, 1, ptimestamp);
  2142. tmpbuf=NULL;
  2143. break;
  2144. }
  2145. else
  2146. SlibFreeBuffer(prevbuf);
  2147. }
  2148. else
  2149. {
  2150. SlibFreeBuffer(tmpbuf);
  2151. tmpbuf=SlibGetBuffer(Info, pinid, &tmpsize, &nexttime);
  2152. if (tmpbuf==NULL)
  2153. return(SlibErrorEndOfStream);
  2154. if (nexttime!=SLIB_TIME_NONE)
  2155. ptimestamp=nexttime;
  2156. }
  2157. bytessearched+=tmpsize;
  2158. } while (tmpbuf && bytessearched<512*1024);
  2159. }
  2160. if (*databuf==NULL)
  2161. *databuf=SlibGetBuffer(Info, pinid, databufsize, &ptimestamp);
  2162. else
  2163. *databufsize=slibFillBufferFromPin(Info, pin, *databuf, *databufsize,
  2164. &ptimestamp);
  2165. if (Info->Mode==SLIB_MODE_DECOMPRESS)
  2166. {
  2167. if (ptimestamp!=SLIB_TIME_NONE)
  2168. switch (stream) /* set presentation timecodes */
  2169. {
  2170. case SLIB_STREAM_MAINVIDEO:
  2171. Info->VideoPTimeCode=ptimestamp;
  2172. _SlibDebug(_TIMECODE_ || _VERBOSE_,
  2173. printf("SlibReadData() VideoPTimeCode=%ld\n", ptimestamp) );
  2174. break;
  2175. case SLIB_STREAM_MAINAUDIO:
  2176. Info->AudioPTimeCode=ptimestamp;
  2177. _SlibDebug(_TIMECODE_ || _VERBOSE_,
  2178. printf("SlibReadData() AudioPTimeCode=%ld\n", ptimestamp) );
  2179. break;
  2180. }
  2181. else if (stream==SLIB_STREAM_MAINVIDEO &&
  2182. Info->VideoPTimeCode==SLIB_TIME_NONE)
  2183. Info->VideoPTimeCode=SLIB_TIME_UNKNOWN;
  2184. }
  2185. if (*databuf==NULL || *databufsize==0)
  2186. {
  2187. if (!slibDataOnPin(Info, pinid))
  2188. return(SlibErrorEndOfStream);
  2189. else
  2190. return(SlibErrorReading);
  2191. }
  2192. return(SlibErrorNone);
  2193. }
  2194. SlibStatus_t SlibReadVideo(SlibHandle_t handle, SlibStream_t stream,
  2195. void **videobuf, unsigned dword *videobufsize)
  2196. {
  2197. SlibInfo_t *Info=(SlibInfo_t *)handle;
  2198. SvStatus_t status=SvErrorNone;
  2199. unsigned char *imagebuf=NULL;
  2200. SlibTime_t startvideotime;
  2201. _SlibDebug(_VERBOSE_, printf("SlibReadVideo()\n") );
  2202. if (!handle)
  2203. return(SlibErrorBadHandle);
  2204. if (!videobuf)
  2205. return(SlibErrorBadArgument);
  2206. /*
  2207. imagesize=(Info->Width*Info->Height*3)/2;
  2208. if (videobufsize<imagesize)
  2209. return(SlibErrorBufSize);
  2210. */
  2211. if (Info->Mode!=SLIB_MODE_DECOMPRESS)
  2212. return(SlibErrorBadMode);
  2213. if (Info->VideoFormat==NULL || Info->CodecVideoFormat==NULL ||
  2214. Info->CompVideoFormat==NULL)
  2215. return(SlibErrorUnsupportedFormat);
  2216. if ((status=slibStartVideo(Info, (SlibBoolean_t)((*videobuf==NULL)?FALSE:TRUE)))
  2217. !=SlibErrorNone)
  2218. return(status);
  2219. startvideotime=Info->VideoTimeStamp;
  2220. switch(Info->VideoType)
  2221. {
  2222. #ifdef MPEG_SUPPORT
  2223. case SLIB_TYPE_MPEG1_VIDEO:
  2224. case SLIB_TYPE_MPEG2_VIDEO:
  2225. do {
  2226. _SlibDebug(_DEBUG_, printf("SvDecompressMPEG()\n") );
  2227. status = SvDecompressMPEG(Info->Svh, Info->Multibuf,
  2228. Info->MultibufSize, &imagebuf);
  2229. _SlibDebug(_WARN_ && status!=SvErrorNone,
  2230. printf("SvDecompressMPEG() %s\n",
  2231. ScGetErrorStr(status)) );
  2232. } while(status == SvErrorNotDecompressable);
  2233. if (status==SvErrorNone)
  2234. SlibAllocSubBuffer(imagebuf, Info->CodecVideoFormat->biSizeImage);
  2235. _SlibDebug(_SEEK_>1, printf("timecode=%d ms framenum=%d\n",
  2236. SvGetParamInt(Info->Svh, SV_PARAM_CALCTIMECODE),
  2237. SvGetParamInt(Info->Svh, SV_PARAM_FRAME) ) );
  2238. break;
  2239. #endif /* MPEG_SUPPORT */
  2240. #ifdef H261_SUPPORT
  2241. case SLIB_TYPE_H261:
  2242. do {
  2243. _SlibDebug(_DEBUG_, ScDebugPrintf(Info->dbg,"SvDecompressH261()\n") );
  2244. status = SvDecompressH261(Info->Svh, Info->Multibuf,
  2245. Info->MultibufSize,
  2246. &imagebuf);
  2247. } while(status == SvErrorNotDecompressable);
  2248. if (status==SvErrorNone)
  2249. SlibAllocSubBuffer(imagebuf, Info->CodecVideoFormat->biSizeImage);
  2250. break;
  2251. #endif /* H261_SUPPORT */
  2252. #ifdef H263_SUPPORT
  2253. case SLIB_TYPE_H263:
  2254. _SlibDebug(_DEBUG_, ScDebugPrintf(Info->dbg,"SvDecompress(%d bytes)\n", Info->MultibufSize) );
  2255. status=SvDecompress(Info->Svh, NULL, 0,
  2256. Info->Multibuf, Info->MultibufSize);
  2257. imagebuf=Info->Multibuf;
  2258. if (status==SvErrorNone)
  2259. SlibAllocSubBuffer(imagebuf, Info->CodecVideoFormat->biSizeImage);
  2260. break;
  2261. #endif /* H263_SUPPORT */
  2262. #ifdef JPEG_SUPPORT
  2263. case SLIB_TYPE_JPEG:
  2264. case SLIB_TYPE_MJPG:
  2265. {
  2266. unsigned dword bufsize;
  2267. unsigned char *buf;
  2268. buf=SlibGetBuffer(Info, SLIB_DATA_VIDEO, &bufsize, NULL);
  2269. if (buf)
  2270. {
  2271. /* ScDumpChar(buf, 10000, 0); */
  2272. _SlibDebug(_DEBUG_, ScDebugPrintf(Info->dbg,"SvDecompress(%d bytes)\n", bufsize) );
  2273. status=SvDecompress(Info->Svh, buf, bufsize,
  2274. Info->Multibuf, Info->MultibufSize);
  2275. imagebuf=Info->Multibuf;
  2276. SlibFreeBuffer(buf);
  2277. }
  2278. else
  2279. status=SvErrorForeign;
  2280. if (status==SvErrorNone)
  2281. SlibAllocSubBuffer(imagebuf, Info->CodecVideoFormat->biSizeImage);
  2282. }
  2283. break;
  2284. #endif /* JPEG_SUPPORT */
  2285. #ifdef HUFF_SUPPORT
  2286. case SLIB_TYPE_SHUFF:
  2287. if (*videobuf==NULL)
  2288. {
  2289. if (Info->Imagebuf==NULL &&
  2290. (Info->Imagebuf=SlibAllocBuffer(Info->ImageSize))==NULL)
  2291. return(SlibErrorMemory);
  2292. imagebuf=Info->Imagebuf;
  2293. }
  2294. else
  2295. imagebuf=*videobuf;
  2296. do {
  2297. _SlibDebug(_DEBUG_, ScDebugPrintf(Info->dbg,"SvDecompress()\n") );
  2298. status=SvDecompress(Info->Svh, NULL, 0,
  2299. imagebuf, Info->CodecVideoFormat->biSizeImage);
  2300. } while(status == SvErrorNotDecompressable);
  2301. if (status==SvErrorNone)
  2302. SlibAllocSubBuffer(imagebuf, Info->CodecVideoFormat->biSizeImage);
  2303. break;
  2304. #endif /* HUFF_SUPPORT */
  2305. case SLIB_TYPE_RASTER:
  2306. case SLIB_TYPE_YUV:
  2307. if (*videobuf && videobufsize && *videobufsize==0)
  2308. return(SlibErrorBadArgument);
  2309. imagebuf=SlibGetBuffer(Info, SLIB_DATA_VIDEO, videobufsize, NULL);
  2310. if (*videobufsize==0)
  2311. status=SvErrorEndBitstream;
  2312. _SlibDebug(_DEBUG_,
  2313. ScDebugPrintf(Info->dbg,"Video frame size = %d ImageSize=%d\n",
  2314. *videobufsize, Info->ImageSize) );
  2315. break;
  2316. default:
  2317. return(SlibErrorUnsupportedFormat);
  2318. }
  2319. if (status==SvErrorNone)
  2320. {
  2321. /* format conversion */
  2322. if (Info->Sch==NULL) /* start the format converter */
  2323. {
  2324. if (Info->Svh) /* compressed video format */
  2325. {
  2326. unsigned dword fourcc=(unsigned dword)SvGetParamInt(Info->Svh, SV_PARAM_FINALFORMAT);
  2327. if (fourcc)
  2328. {
  2329. Info->CodecVideoFormat->biCompression=fourcc;
  2330. Info->CodecVideoFormat->biBitCount=
  2331. (WORD)slibCalcBits(fourcc, Info->CodecVideoFormat->biBitCount);
  2332. }
  2333. }
  2334. else /* uncompressed video format */
  2335. memcpy(Info->CodecVideoFormat, Info->CompVideoFormat, sizeof(BITMAPINFOHEADER));
  2336. if (SconOpen(&Info->Sch, SCON_MODE_VIDEO, (void *)Info->CodecVideoFormat, (void *)Info->VideoFormat)
  2337. !=SconErrorNone)
  2338. return(SlibErrorUnsupportedFormat);
  2339. if (Info->Stride)
  2340. SconSetParamInt(Info->Sch, SCON_OUTPUT, SCON_PARAM_STRIDE, Info->Stride);
  2341. }
  2342. if (SconIsSame(Info->Sch) && *videobuf == NULL) /* no conversion */
  2343. *videobuf=imagebuf;
  2344. else
  2345. {
  2346. if (*videobuf == NULL && (*videobuf=SlibAllocBuffer(Info->ImageSize))==NULL)
  2347. return(SlibErrorMemory);
  2348. if (SconConvert(Info->Sch, imagebuf, Info->CodecVideoFormat->biSizeImage,
  2349. *videobuf, Info->ImageSize) != SconErrorNone)
  2350. {
  2351. SlibFreeBuffer(imagebuf); /* free decompressed image */
  2352. return(SlibErrorUnsupportedFormat);
  2353. }
  2354. SlibFreeBuffer(imagebuf); /* free decompressed image */
  2355. }
  2356. *videobufsize = Info->ImageSize;
  2357. /* update stats */
  2358. if (Info->stats && Info->stats->Record)
  2359. Info->stats->FramesProcessed++;
  2360. if (startvideotime==Info->VideoTimeStamp) /* video time hasn't changed */
  2361. slibAdvancePositions(Info, 1);
  2362. }
  2363. else
  2364. {
  2365. if (status==ScErrorEndBitstream ||
  2366. !slibDataOnPin(Info, SLIB_DATA_VIDEO))
  2367. {
  2368. if (Info->FileSize>0 && !Info->VideoLengthKnown)
  2369. slibUpdateLengths(Info);
  2370. _SlibDebug(_WARN_, ScDebugPrintf(Info->dbg,"SlibReadVideo() %s\n",
  2371. ScGetErrorStr(status)) );
  2372. return(SlibErrorEndOfStream);
  2373. }
  2374. _SlibDebug(_WARN_, printf("SlibReadVideo() %s\n",
  2375. ScGetErrorStr(status)) );
  2376. return(SlibErrorReading);
  2377. }
  2378. return(SlibErrorNone);
  2379. }
  2380. SlibStatus_t SlibReadAudio(SlibHandle_t handle, SlibStream_t stream,
  2381. void *audiobuf, unsigned dword *audiobufsize)
  2382. {
  2383. SlibInfo_t *Info=(SlibInfo_t *)handle;
  2384. SvStatus_t status=SaErrorNone;
  2385. unsigned dword totalbytes=0, bytes_since_timeupdate=0;
  2386. SlibTime_t startaudiotime;
  2387. #ifdef _SLIBDEBUG_
  2388. SlibTime_t calcaudiotime;
  2389. #endif
  2390. _SlibDebug(_VERBOSE_, printf("SlibReadAudio(audiobufsize=%d, time=%d)\n",
  2391. *audiobufsize, Info->AudioTimeStamp) );
  2392. if (!handle)
  2393. return(SlibErrorBadHandle);
  2394. if (Info->Mode!=SLIB_MODE_DECOMPRESS)
  2395. return(SlibErrorBadMode);
  2396. if (Info->AudioFormat==NULL)
  2397. return(SlibErrorUnsupportedFormat);
  2398. if ((status=slibStartAudio(Info))!=SlibErrorNone)
  2399. return(status);
  2400. #ifdef _SLIBDEBUG_
  2401. calcaudiotime=Info->AudioTimeStamp;
  2402. #endif
  2403. startaudiotime=Info->AudioTimeStamp;
  2404. switch(Info->AudioType)
  2405. {
  2406. case SLIB_TYPE_PCM:
  2407. totalbytes=slibFillBufferFromPin(Info,
  2408. slibGetPin(Info, SLIB_DATA_AUDIO),
  2409. (unsigned char *)audiobuf, *audiobufsize,
  2410. NULL);
  2411. if (totalbytes==0)
  2412. status=ScErrorEndBitstream;
  2413. *audiobufsize = totalbytes;
  2414. bytes_since_timeupdate = totalbytes;
  2415. break;
  2416. #ifdef MPEG_SUPPORT
  2417. case SLIB_TYPE_MPEG1_AUDIO:
  2418. {
  2419. unsigned dword bytes;
  2420. /* see if some bytes of audio are left in the temp audio buffer */
  2421. if (Info->Audiobuf && Info->AudiobufUsed>0)
  2422. {
  2423. _SlibDebug(_DEBUG_,
  2424. printf("SlibReadAudio() Audiobuf contains %d bytes\n",
  2425. Info->AudiobufUsed) );
  2426. if (*audiobufsize>=Info->AudiobufUsed)
  2427. {
  2428. memcpy(audiobuf, Info->Audiobuf, Info->AudiobufUsed);
  2429. totalbytes=Info->AudiobufUsed;
  2430. Info->AudiobufUsed=0;
  2431. }
  2432. else
  2433. {
  2434. memcpy(audiobuf, Info->Audiobuf, *audiobufsize);
  2435. totalbytes=*audiobufsize;
  2436. Info->AudiobufUsed-=*audiobufsize;
  2437. memcpy(Info->Audiobuf, Info->Audiobuf+*audiobufsize,
  2438. Info->AudiobufUsed);
  2439. }
  2440. }
  2441. /* need to alloc a temp audio buffer? */
  2442. if (!Info->Audiobuf || Info->AudiobufSize<
  2443. *audiobufsize+MPEG1_AUDIO_FRAME_SIZE*4)
  2444. {
  2445. unsigned char *newbuf;
  2446. /* enlarge Audiobuf or alloc it for the first time */
  2447. _SlibDebug(_DEBUG_,
  2448. printf("SlibReadAudio() enlarging Audiobuf: %d->%d bytes\n",
  2449. Info->AudiobufSize,*audiobufsize+MPEG1_AUDIO_FRAME_SIZE*4) );
  2450. newbuf=SlibAllocBuffer(*audiobufsize+MPEG1_AUDIO_FRAME_SIZE*4);
  2451. if (!newbuf)
  2452. return(SlibErrorMemory);
  2453. Info->AudiobufSize=*audiobufsize+MPEG1_AUDIO_FRAME_SIZE*4;
  2454. if (Info->Audiobuf)
  2455. SlibFreeBuffer(Info->Audiobuf);
  2456. Info->Audiobuf=newbuf;
  2457. Info->AudiobufUsed=0;
  2458. }
  2459. if (*audiobufsize>=MPEG1_AUDIO_FRAME_SIZE*4)
  2460. {
  2461. unsigned dword stopbytes=*audiobufsize-(MPEG1_AUDIO_FRAME_SIZE*4)+1;
  2462. while (status==SaErrorNone && totalbytes<stopbytes)
  2463. {
  2464. bytes = *audiobufsize - totalbytes;
  2465. _SlibDebug(_DEBUG_,
  2466. printf("SaDecompress(bytes=%d) in totalbytes=%d\n",
  2467. bytes, totalbytes) );
  2468. status = SaDecompress(Info->Sah, NULL, 0,
  2469. (unsigned char *)audiobuf+totalbytes, &bytes);
  2470. _SlibDebug(_DEBUG_, printf("SaDecompress() out: bytes=%d\n",
  2471. bytes) );
  2472. totalbytes += bytes;
  2473. if (Info->AudioTimeStamp!=startaudiotime)
  2474. {
  2475. startaudiotime=Info->AudioTimeStamp;
  2476. bytes_since_timeupdate=bytes;
  2477. }
  2478. else
  2479. bytes_since_timeupdate+=bytes;
  2480. }
  2481. }
  2482. if (totalbytes<*audiobufsize && status==SaErrorNone)
  2483. {
  2484. unsigned dword neededbytes=*audiobufsize-totalbytes;
  2485. while (status==SaErrorNone && Info->AudiobufUsed<neededbytes)
  2486. {
  2487. bytes = *audiobufsize - totalbytes;
  2488. _SlibDebug(_DEBUG_, printf("SaDecompress() in totalbytes=%d\n",
  2489. totalbytes) );
  2490. status = SaDecompress(Info->Sah, NULL, 0,
  2491. (unsigned char *)Info->Audiobuf+Info->AudiobufUsed, &bytes);
  2492. _SlibDebug(_DEBUG_, printf("SaDecompress() out, %d bytes\n",
  2493. bytes) );
  2494. Info->AudiobufUsed += bytes;
  2495. }
  2496. if (Info->AudiobufUsed>0)
  2497. {
  2498. if (Info->AudiobufUsed>neededbytes) /* complete buffer returned */
  2499. {
  2500. memcpy((unsigned char*)audiobuf+totalbytes,
  2501. Info->Audiobuf, neededbytes);
  2502. Info->AudiobufUsed-=neededbytes;
  2503. memcpy(Info->Audiobuf, Info->Audiobuf+neededbytes,
  2504. Info->AudiobufUsed);
  2505. totalbytes+=neededbytes;
  2506. bytes_since_timeupdate+=neededbytes;
  2507. }
  2508. else /* partially filled buffer */
  2509. {
  2510. memcpy((unsigned char*)audiobuf+totalbytes, Info->Audiobuf,
  2511. Info->AudiobufUsed);
  2512. totalbytes+=Info->AudiobufUsed;
  2513. Info->AudiobufUsed=0;
  2514. }
  2515. }
  2516. }
  2517. *audiobufsize = totalbytes;
  2518. _SlibDebug(_WARN_>1 && totalbytes>0 &&
  2519. totalbytes!=*audiobufsize,
  2520. printf("SlibReadAudio(audiobufsize=%d bytes) totalbytes=%d\n",
  2521. *audiobufsize, totalbytes) );
  2522. }
  2523. break;
  2524. #endif /* MPEG_SUPPORT */
  2525. #ifdef AC3_SUPPORT
  2526. case SLIB_TYPE_AC3_AUDIO:
  2527. {
  2528. unsigned dword bytes;
  2529. unsigned int framesize;
  2530. unsigned int buffersize;
  2531. int samplesize;
  2532. int buffers;
  2533. unsigned char *pointers[3];
  2534. int i;
  2535. if (Info->Channels>2)
  2536. {
  2537. framesize = AC3_FRAME_SIZE*((Info->BitsPerSample+7)/8)
  2538. *Info->Channels;
  2539. samplesize=Info->Channels*((Info->BitsPerSample+7)/8);
  2540. buffers = (Info->Channels+1)/2;
  2541. buffersize = (*audiobufsize/samplesize/buffers)*samplesize;
  2542. for(i=0; i<buffers; i++)
  2543. pointers[i]=(unsigned char *)audiobuf+buffersize*i;
  2544. if (*audiobufsize>=framesize)
  2545. {
  2546. while (status==SaErrorNone && totalbytes<buffersize)
  2547. {
  2548. bytes = buffersize - totalbytes;
  2549. _SlibDebug(_DEBUG_,printf("SaDecompressEx() in totalbytes=%d\n",
  2550. totalbytes) );
  2551. status = SaDecompressEx(Info->Sah, NULL, 0, pointers, &bytes);
  2552. _SlibDebug(_DEBUG_, printf("SaDecompress() out, %d bytes\n",
  2553. bytes) );
  2554. for(i=0;i<buffers;i++)
  2555. pointers[i]+=bytes;
  2556. totalbytes += bytes;
  2557. if (Info->AudioTimeStamp!=startaudiotime)
  2558. {
  2559. startaudiotime=Info->AudioTimeStamp;
  2560. bytes_since_timeupdate=bytes;
  2561. }
  2562. else
  2563. bytes_since_timeupdate+=bytes;
  2564. }
  2565. }
  2566. }
  2567. else
  2568. {
  2569. while (status==SaErrorNone && totalbytes<*audiobufsize)
  2570. {
  2571. bytes = *audiobufsize - totalbytes;
  2572. _SlibDebug(_DEBUG_, printf("SaDecompress() in totalbytes=%d\n",
  2573. totalbytes) );
  2574. status = SaDecompress(Info->Sah, NULL, 0,
  2575. (unsigned char *)audiobuf+totalbytes, &bytes);
  2576. _SlibDebug(_DEBUG_, printf("SaDecompress() out, %d bytes\n",
  2577. bytes) );
  2578. totalbytes += bytes;
  2579. if (Info->AudioTimeStamp!=startaudiotime)
  2580. {
  2581. startaudiotime=Info->AudioTimeStamp;
  2582. bytes_since_timeupdate=bytes;
  2583. }
  2584. else
  2585. bytes_since_timeupdate+=bytes;
  2586. }
  2587. }
  2588. /*
  2589. ** NOTE: The semantics are different here
  2590. ** we return the size of just one stereo pair's buffer
  2591. */
  2592. *audiobufsize = totalbytes;
  2593. _SlibDebug(_WARN_>1 && totalbytes>0 &&
  2594. totalbytes!=*audiobufsize,
  2595. printf("SlibReadAudio(audiobufsize=%d bytes) totalbytes=%d\n",
  2596. *audiobufsize, totalbytes) );
  2597. }
  2598. break;
  2599. #endif /* AC3_SUPPORT */
  2600. #ifdef G723_SUPPORT
  2601. case SLIB_TYPE_G723:
  2602. //G723 decompresses in multiples of 480 samples.
  2603. //To eliminate cumbersome buffer calculations,
  2604. // Always fill the output buffer up to multiples
  2605. // of 480 samples.To do this we iterate basically
  2606. // the below "while" loop "audiobufsize/480 times.
  2607. {
  2608. int iTimes = (int)*audiobufsize/480;
  2609. int iLoop =0;
  2610. unsigned dword bytes;
  2611. if (slibInSyncMode(Info))
  2612. {
  2613. /* in synchronous mode we can't decompress past last frame
  2614. * otherwise we may lose a frame
  2615. */
  2616. int iMaxTimes=(int)(slibDataOnPin(Info, SLIB_DATA_COMPRESSED)+
  2617. slibDataOnPin(Info, SLIB_DATA_AUDIO))/
  2618. SlibGetParamInt(handle, stream, SLIB_PARAM_MININPUTSIZE);
  2619. if (iTimes>iMaxTimes)
  2620. iTimes=iMaxTimes;
  2621. }
  2622. while (status==SaErrorNone && iLoop<iTimes)
  2623. {
  2624. bytes = *audiobufsize - totalbytes;
  2625. _SlibDebug(_DEBUG_, printf("SaDecompress() in totalbytes=%d\n",
  2626. totalbytes) );
  2627. status = SaDecompress(Info->Sah, NULL, 0,
  2628. (unsigned char *)audiobuf+totalbytes, &bytes);
  2629. _SlibDebug(_DEBUG_, printf("SaDecompress() out, %d bytes\n",
  2630. bytes) );
  2631. totalbytes += bytes;
  2632. iLoop++;
  2633. if (Info->AudioTimeStamp!=startaudiotime)
  2634. {
  2635. startaudiotime=Info->AudioTimeStamp;
  2636. bytes_since_timeupdate=bytes;
  2637. }
  2638. else
  2639. bytes_since_timeupdate+=bytes;
  2640. }
  2641. *audiobufsize = totalbytes;
  2642. _SlibDebug(_WARN_>1 && totalbytes>0 &&
  2643. totalbytes!=*audiobufsize,
  2644. printf("SlibReadAudio(audiobufsize=%d bytes) totalbytes=%d\n",
  2645. *audiobufsize, totalbytes) );
  2646. }
  2647. break;
  2648. #endif /* G723_SUPPORT */
  2649. default:
  2650. *audiobufsize = 0;
  2651. return(SlibErrorUnsupportedFormat);
  2652. }
  2653. /* as we're decompressing audiotime may be updated with timecodes */
  2654. if (Info->AudioTimeStamp==startaudiotime)
  2655. Info->AudioTimeStamp = startaudiotime + (bytes_since_timeupdate*8000)/
  2656. (Info->SamplesPerSec*Info->BitsPerSample*Info->Channels);
  2657. _SlibDebug(_TIMECODE_||_VERBOSE_,
  2658. calcaudiotime += (*audiobufsize*8000)/
  2659. (Info->SamplesPerSec*Info->BitsPerSample*Info->Channels);
  2660. printf("AudioTimeStamp=%ld calcaudiotime=%ld (diff=%ld)\n",
  2661. Info->AudioTimeStamp, calcaudiotime,
  2662. calcaudiotime-Info->AudioTimeStamp);
  2663. Info->AudioTimeStamp = calcaudiotime );
  2664. _SlibDebug(_VERBOSE_||_TIMECODE_,
  2665. printf("ReadAudio(%d) Time=%ld SamplesPerSec=%d BitsPerSample=%d Channels=%d\n",
  2666. totalbytes,
  2667. Info->AudioTimeStamp, Info->SamplesPerSec, Info->BitsPerSample,
  2668. Info->Channels) );
  2669. /* Info->SystemTimeStamp=Info->AudioTimeStamp; */
  2670. if (status==SaErrorNone)
  2671. return(SlibErrorNone);
  2672. else if (status==ScErrorEndBitstream || status==ScErrorEOI)
  2673. {
  2674. if (*audiobufsize!=0)
  2675. return(SlibErrorNone);
  2676. else
  2677. return(SlibErrorEndOfStream);
  2678. }
  2679. else
  2680. {
  2681. _SlibDebug(_WARN_ && status!=ScErrorEndBitstream
  2682. && status!=ScErrorEOI,
  2683. printf("SlibReadAudio() %s\n", ScGetErrorStr(status)) );
  2684. if (SlibIsEnd(handle, stream))
  2685. return(SlibErrorEndOfStream);
  2686. return(SlibErrorReading);
  2687. }
  2688. }
  2689. SlibStatus_t SlibWriteVideo(SlibHandle_t handle, SlibStream_t stream,
  2690. void *videobuf, unsigned dword videobufsize)
  2691. {
  2692. int compsize=0;
  2693. SlibInfo_t *Info=(SlibInfo_t *)handle;
  2694. SvStatus_t status;
  2695. _SlibDebug(_DEBUG_, printf("SlibWriteVideo()\n") );
  2696. if (!handle)
  2697. return(SlibErrorBadHandle);
  2698. if (!videobuf)
  2699. return(SlibErrorBadArgument);
  2700. if (videobufsize<(unsigned dword)Info->ImageSize)
  2701. return(SlibErrorBufSize);
  2702. if (Info->Mode!=SLIB_MODE_COMPRESS)
  2703. return(SlibErrorBadMode);
  2704. if (Info->VideoFormat==NULL || Info->CompVideoFormat==NULL)
  2705. return(SlibErrorUnsupportedFormat);
  2706. if (Info->IOError)
  2707. return(SlibErrorWriting);
  2708. if ((status=slibStartVideo(Info, FALSE))!=SlibErrorNone)
  2709. return(status);
  2710. if (Info->Sch==NULL) /* start the format converter */
  2711. {
  2712. if (SconOpen(&Info->Sch, SCON_MODE_VIDEO, (void *)Info->VideoFormat, (void *)Info->CodecVideoFormat)
  2713. !=SconErrorNone)
  2714. return(SlibErrorUnsupportedFormat);
  2715. }
  2716. if (!SconIsSame(Info->Sch)) /* need a conversion */
  2717. {
  2718. unsigned char *tmpbuf=NULL;
  2719. if (Info->CodecImagebuf==NULL &&
  2720. (Info->CodecImagebuf=SlibAllocBuffer(Info->CodecImageSize))==NULL)
  2721. return(SlibErrorMemory);
  2722. if (SconConvert(Info->Sch, videobuf, Info->ImageSize,
  2723. Info->CodecImagebuf, Info->CodecImageSize) != SconErrorNone)
  2724. return(SlibErrorUnsupportedFormat);
  2725. videobuf=Info->CodecImagebuf;
  2726. videobufsize=Info->CodecImageSize;
  2727. }
  2728. switch(Info->Type)
  2729. {
  2730. #ifdef H261_SUPPORT
  2731. case SLIB_TYPE_H261:
  2732. status = SvCompress(Info->Svh, NULL, 0, videobuf, videobufsize, &compsize);
  2733. break;
  2734. #endif /* H261_SUPPORT */
  2735. #ifdef H263_SUPPORT
  2736. case SLIB_TYPE_H263:
  2737. status = SvCompress(Info->Svh, NULL, 0, videobuf, videobufsize, &compsize);
  2738. break;
  2739. #endif /* H263_SUPPORT */
  2740. #ifdef MPEG_SUPPORT
  2741. case SLIB_TYPE_MPEG1_VIDEO:
  2742. case SLIB_TYPE_MPEG2_VIDEO:
  2743. case SLIB_TYPE_MPEG_SYSTEMS:
  2744. case SLIB_TYPE_MPEG_SYSTEMS_MPEG2:
  2745. status = SvCompress(Info->Svh, NULL, 0, videobuf, videobufsize, &compsize);
  2746. break;
  2747. #endif /* MPEG_SUPPORT */
  2748. #ifdef HUFF_SUPPORT
  2749. case SLIB_TYPE_SHUFF:
  2750. status = SvCompress(Info->Svh, NULL, 0, videobuf, videobufsize, &compsize);
  2751. break;
  2752. #endif /* HUFF_SUPPORT */
  2753. default:
  2754. return(SlibErrorUnsupportedFormat);
  2755. }
  2756. if (status==SvErrorNone && !Info->IOError)
  2757. {
  2758. if (Info->stats && Info->stats->Record)
  2759. Info->stats->FramesProcessed++;
  2760. slibAdvancePositions(Info, 1);
  2761. }
  2762. else
  2763. {
  2764. _SlibDebug(_WARN_, printf("SlibWriteVideo() %s\n",
  2765. ScGetErrorStr(status)) );
  2766. if (status==ScErrorEndBitstream || Info->IOError)
  2767. return(SlibErrorEndOfStream);
  2768. return(SlibErrorWriting);
  2769. }
  2770. return(SlibErrorNone);
  2771. }
  2772. SlibStatus_t SlibWriteAudio(SlibHandle_t handle, SlibStream_t stream,
  2773. void *audiobuf, unsigned dword audiobufsize)
  2774. {
  2775. unsigned dword compsize=0;
  2776. SlibInfo_t *Info=(SlibInfo_t *)handle;
  2777. SvStatus_t status;
  2778. _SlibDebug(_DEBUG_, printf("SlibAudioVideo()\n") );
  2779. if (!handle)
  2780. return(SlibErrorBadHandle);
  2781. if (!audiobuf)
  2782. return(SlibErrorBadArgument);
  2783. if (Info->Mode!=SLIB_MODE_COMPRESS)
  2784. return(SlibErrorBadMode);
  2785. if (Info->AudioFormat==NULL || Info->CompAudioFormat==NULL)
  2786. {
  2787. _SlibDebug(_VERBOSE_ || _WARN_,
  2788. printf("SlibWriteAudio() Audio Formats not setup\n") );
  2789. return(SlibErrorUnsupportedFormat);
  2790. }
  2791. if (Info->IOError)
  2792. return(SlibErrorWriting);
  2793. if ((status=slibStartAudio(Info))!=SlibErrorNone)
  2794. return(status);
  2795. switch(Info->Type)
  2796. {
  2797. #ifdef MPEG_SUPPORT
  2798. case SLIB_TYPE_MPEG1_AUDIO:
  2799. case SLIB_TYPE_MPEG_SYSTEMS:
  2800. case SLIB_TYPE_MPEG_SYSTEMS_MPEG2:
  2801. {
  2802. unsigned dword audiobytes;
  2803. void *audiooutbuf=NULL;
  2804. status=slibConvertAudio(Info, audiobuf, audiobufsize,
  2805. Info->SamplesPerSec, Info->BitsPerSample,
  2806. &audiooutbuf, &audiobytes,
  2807. Info->AudioFormat->nSamplesPerSec,
  2808. Info->AudioFormat->wBitsPerSample,
  2809. Info->Channels);
  2810. if (status!=SlibErrorNone)
  2811. return(status);
  2812. audiobuf=audiooutbuf;
  2813. audiobufsize=audiobytes;
  2814. if (Info->AudiobufUsed && Info->Audiobuf) /* left over audio data */
  2815. {
  2816. if (Info->AudiobufSize<Info->AudiobufUsed+audiobufsize)
  2817. {
  2818. unsigned char *newbuf;
  2819. /* enlarge Audiobuf */
  2820. _SlibDebug(_DEBUG_, printf("enlarging Audiobuf: %d->%d bytes\n",
  2821. Info->AudiobufSize,audiobufsize+4608) );
  2822. newbuf=SlibAllocBuffer(audiobufsize+4608);
  2823. if (!newbuf)
  2824. return(SlibErrorMemory);
  2825. memcpy(newbuf, Info->Audiobuf, Info->AudiobufUsed);
  2826. SlibFreeBuffer(Info->Audiobuf);
  2827. Info->AudiobufSize+=audiobufsize;
  2828. Info->Audiobuf=newbuf;
  2829. }
  2830. _SlibDebug(_DEBUG_,
  2831. printf("Appending audio data: Info->AudiobufUsed=%d\n",
  2832. Info->AudiobufUsed) );
  2833. memcpy(Info->Audiobuf+Info->AudiobufUsed, audiobuf, audiobufsize);
  2834. audiobuf=Info->Audiobuf;
  2835. audiobufsize+=Info->AudiobufUsed;
  2836. audiobytes=audiobufsize;
  2837. Info->AudiobufUsed=0;
  2838. }
  2839. status = SaCompress(Info->Sah, (unsigned char *)audiobuf,
  2840. &audiobytes, NULL, &compsize);
  2841. if (audiobytes<audiobufsize) /* save audio data not compressed */
  2842. {
  2843. _SlibDebug(_DEBUG_,
  2844. printf("audiobytes(%d)<audiobufsize(%d)\n",
  2845. audiobytes,audiobufsize) );
  2846. if (!Info->Audiobuf)
  2847. {
  2848. Info->AudiobufSize=audiobufsize+(audiobufsize-audiobytes);
  2849. Info->Audiobuf=SlibAllocBuffer(Info->AudiobufSize);
  2850. if (!Info->Audiobuf)
  2851. {
  2852. Info->AudiobufSize=0;
  2853. return(SlibErrorMemory);
  2854. }
  2855. }
  2856. memcpy(Info->Audiobuf, (unsigned char *)audiobuf+audiobytes,
  2857. audiobufsize-audiobytes);
  2858. Info->AudiobufUsed=audiobufsize-audiobytes;
  2859. }
  2860. audiobufsize=audiobytes; /* actual amount written */
  2861. if (audiooutbuf)
  2862. SlibFreeBuffer(audiooutbuf);
  2863. }
  2864. break;
  2865. #endif /* MPEG_SUPPORT */
  2866. #ifdef G723_SUPPORT
  2867. case SLIB_TYPE_G723:
  2868. {
  2869. unsigned int iNumBytesUnProcessed =0;
  2870. unsigned int iNumBytesCompressed = 0;
  2871. //You always compress in terms of frames (Frame is 480 bytes)
  2872. //So,the files with sizes which are not exactly divisible by
  2873. // 480 always leave some bytes at the end Unprocessed,Which is O.K
  2874. //Check for any Unprocessed Audio stored in Temp buff
  2875. //from the previous call to SlibWriteAudio.
  2876. if (Info->AudiobufUsed && Info->Audiobuf) /* left over audio data */
  2877. {
  2878. if (Info->AudiobufSize < Info->AudiobufUsed+audiobufsize)
  2879. {
  2880. unsigned char *newbuf;
  2881. /* enlarge Audiobuf to new Size (Current size + left over audio)*/
  2882. _SlibDebug(_DEBUG_, printf("enlarging Audiobuf: %d->%d bytes\n",
  2883. Info->AudiobufSize,audiobufsize+Info->AudiobufUsed) );
  2884. newbuf=SlibAllocBuffer(Info->AudiobufUsed+audiobufsize);
  2885. if (!newbuf)
  2886. return(SlibErrorMemory);
  2887. memcpy(newbuf, Info->Audiobuf, Info->AudiobufUsed);
  2888. SlibFreeBuffer(Info->Audiobuf);
  2889. //Info->AudiobufSize+=audiobufsize;
  2890. Info->Audiobuf=newbuf;
  2891. }
  2892. _SlibDebug(_DEBUG_,
  2893. printf("Appending audio data: Info->AudiobufUsed=%d\n",
  2894. Info->AudiobufUsed) );
  2895. memcpy(Info->Audiobuf+Info->AudiobufUsed, audiobuf, audiobufsize);
  2896. audiobuf=Info->Audiobuf;
  2897. audiobufsize+=Info->AudiobufUsed;
  2898. Info->AudiobufUsed=0;
  2899. }
  2900. iNumBytesCompressed = audiobufsize;
  2901. status = SaCompress(Info->Sah,(unsigned char *)audiobuf,
  2902. &iNumBytesCompressed, NULL,&compsize);
  2903. iNumBytesUnProcessed = audiobufsize - iNumBytesCompressed;
  2904. //Store the Unprocessed Bytes into temp buffer
  2905. if(iNumBytesUnProcessed)
  2906. {
  2907. //Allocate temp buff and store this audio.
  2908. if (!Info->Audiobuf)
  2909. {
  2910. //MVP:To reduce ReAllocations and copying of memory
  2911. //while checking for Unprocessed data (above),Allocate
  2912. // now (normal audio buff size + Unprocessed bytes) more
  2913. // memory upfront.
  2914. Info->AudiobufSize=audiobufsize + iNumBytesUnProcessed;
  2915. Info->Audiobuf=SlibAllocBuffer(Info->AudiobufSize);
  2916. if (!Info->Audiobuf)
  2917. {
  2918. Info->AudiobufSize=0;
  2919. return(SlibErrorMemory);
  2920. }
  2921. }
  2922. memcpy(Info->Audiobuf, (unsigned char *)audiobuf+iNumBytesCompressed,
  2923. iNumBytesUnProcessed);
  2924. Info->AudiobufUsed=iNumBytesUnProcessed;
  2925. }
  2926. audiobufsize=iNumBytesCompressed; /* actual amount written */
  2927. }
  2928. break;
  2929. #endif /* G723_SUPPORT */
  2930. default:
  2931. _SlibDebug(_VERBOSE_ || _WARN_,
  2932. printf("SlibWriteAudio() Unsupported Format\n") );
  2933. return(SlibErrorUnsupportedFormat);
  2934. }
  2935. if (status==SaErrorNone && !Info->IOError)
  2936. {
  2937. if (Info->AudioFormat)
  2938. Info->AudioTimeStamp += (audiobufsize*8000)/
  2939. (Info->AudioFormat->nSamplesPerSec*Info->AudioFormat->wBitsPerSample*
  2940. Info->Channels);
  2941. else
  2942. Info->AudioTimeStamp += (audiobufsize*8000)/
  2943. (Info->SamplesPerSec*Info->BitsPerSample*Info->Channels);
  2944. _SlibDebug(_VERBOSE_||_TIMECODE_,
  2945. printf("WriteAudio(%d) Time=%ld SamplesPerSec=%d BitsPerSample=%d Channels=%d\n",
  2946. audiobufsize,
  2947. Info->AudioTimeStamp, Info->SamplesPerSec, Info->BitsPerSample,
  2948. Info->Channels) );
  2949. }
  2950. else
  2951. {
  2952. _SlibDebug(_WARN_, printf("SlibWriteAudio() %s\n", ScGetErrorStr(status)) );
  2953. if (status==ScErrorEndBitstream || Info->IOError)
  2954. return(SlibErrorEndOfStream);
  2955. return(SlibErrorWriting);
  2956. }
  2957. return(SlibErrorNone);
  2958. }
  2959. /*
  2960. ** Name: slibPinReposition
  2961. ** Purpose: Called when input data stream is to be repositioned.
  2962. */
  2963. SlibStatus_t slibReposition(SlibInfo_t *Info, SlibPosition_t position)
  2964. {
  2965. SlibPin_t *pin=slibGetPin(Info, SLIB_DATA_COMPRESSED);
  2966. _SlibDebug(_DEBUG_, printf("slibReposition() VideoCodecState=%d\n",
  2967. Info->VideoCodecState));
  2968. if (pin) pin->Offset=position;
  2969. Info->VideoPTimeCode = SLIB_TIME_NONE;
  2970. Info->VideoDTimeCode = SLIB_TIME_NONE;
  2971. Info->AudioPTimeCode = SLIB_TIME_NONE;
  2972. Info->AudioDTimeCode = SLIB_TIME_NONE;
  2973. if (Info->Fd >= 0)
  2974. {
  2975. _SlibDebug(_SEEK_, printf("ScFileSeek(%d, %d)\n", Info->Fd, position) );
  2976. if (ScFileSeek(Info->Fd, position)!=NoErrors)
  2977. return(SlibErrorEndOfStream);
  2978. return(SlibErrorNone);
  2979. }
  2980. else if (Info->SlibCB)
  2981. {
  2982. SlibMessage_t result;
  2983. _SlibDebug(_VERBOSE_,
  2984. printf("slibReposition() SlibCB(SLIB_MSG_REPOSITION, %d)\n",
  2985. position) );
  2986. result=(*(Info->SlibCB))((SlibHandle_t)Info,
  2987. SLIB_MSG_REPOSITION, (SlibCBParam1_t)position,
  2988. (SlibCBParam2_t)0, (void *)Info->SlibCBUserData);
  2989. if (result!=SLIB_MSG_CONTINUE)
  2990. return(SlibErrorEndOfStream);
  2991. return(SlibErrorNone);
  2992. }
  2993. return(SlibErrorForwardOnly);
  2994. }
  2995. /*
  2996. ** Name: slibPinPrepareReposition
  2997. ** Purpose: Should be called when a stream is about to be repositioned (a seek).
  2998. ** This will empty any remaining buffers being used by the
  2999. ** CODECs and restart them.
  3000. */
  3001. void slibPinPrepareReposition(SlibInfo_t *Info, int pinid)
  3002. {
  3003. _SlibDebug(_DEBUG_, printf("slibPinPrepareReposition() VideoCodecState=%d\n",
  3004. Info->VideoCodecState));
  3005. switch(pinid)
  3006. {
  3007. case SLIB_DATA_VIDEO:
  3008. _SlibDebug(_VERBOSE_||_SEEK_>1,
  3009. printf("slibPinPrepareReposition(Video) in\n") );
  3010. if (Info->VideoCodecState==SLIB_CODEC_STATE_BEGUN && Info->Svh &&
  3011. #ifdef JPEG_SUPPORT
  3012. Info->Type != SLIB_TYPE_JPEG_AVI &&
  3013. Info->Type != SLIB_TYPE_MJPG_AVI &&
  3014. #endif /* JPEG_SUPPORT */
  3015. Info->Type != SLIB_TYPE_YUV_AVI)
  3016. {
  3017. SvDecompressEnd(Info->Svh); /* this will reset the bitstream */
  3018. Info->VideoCodecState=SLIB_CODEC_STATE_REPOSITIONING;
  3019. _SlibDebug(_DEBUG_, printf("VideoCodecState=REPOSITIONING\n"));
  3020. Info->IOError=FALSE;
  3021. }
  3022. Info->VideoPTimeCode = SLIB_TIME_NONE;
  3023. Info->VideoDTimeCode = SLIB_TIME_NONE;
  3024. Info->VideoTimeStamp = SLIB_TIME_NONE;
  3025. Info->AvgVideoTimeDiff = 0;
  3026. Info->VarVideoTimeDiff = 0;
  3027. Info->VideoFramesProcessed=0; /* reset frames processed */
  3028. break;
  3029. case SLIB_DATA_AUDIO:
  3030. _SlibDebug(_VERBOSE_||_SEEK_>1,
  3031. printf("slibPinPrepareReposition(Audio) in\n") );
  3032. if (Info->AudioCodecState==SLIB_CODEC_STATE_BEGUN && Info->Sah)
  3033. {
  3034. SaDecompressEnd(Info->Sah); /* this will reset the bitstream */
  3035. Info->AudioCodecState=SLIB_CODEC_STATE_REPOSITIONING;
  3036. _SlibDebug(_DEBUG_, printf("AudioCodecState=REPOSITIONING\n"));
  3037. Info->IOError=FALSE;
  3038. }
  3039. Info->AudioPTimeCode = SLIB_TIME_NONE;
  3040. Info->AudioDTimeCode = SLIB_TIME_NONE;
  3041. Info->AudioTimeStamp = SLIB_TIME_NONE;
  3042. break;
  3043. default:
  3044. _SlibDebug(_VERBOSE_||_SEEK_>1,
  3045. printf("slibPinPrepareReposition(%d) in\n", pinid) );
  3046. }
  3047. _SlibDebug(_VERBOSE_||_SEEK_>1, printf("slibPinPrepareReposition(%d) out\n",
  3048. pinid) );
  3049. }
  3050. void slibPinFinishReposition(SlibInfo_t *Info, int pinid)
  3051. {
  3052. _SlibDebug(_DEBUG_, printf("slibPinFinishReposition() VideoCodecState=%d\n",
  3053. Info->VideoCodecState));
  3054. switch(pinid)
  3055. {
  3056. case SLIB_DATA_VIDEO:
  3057. _SlibDebug(_VERBOSE_||_SEEK_>1,
  3058. printf("slibPinFinishReposition(Video) in\n") );
  3059. if (Info->VideoCodecState==SLIB_CODEC_STATE_REPOSITIONING &&
  3060. Info->Svh && slibGetPin(Info, SLIB_DATA_VIDEO) &&
  3061. #ifdef JPEG_SUPPORT
  3062. Info->Type != SLIB_TYPE_JPEG_AVI &&
  3063. Info->Type != SLIB_TYPE_MJPG_AVI &&
  3064. #endif /* JPEG_SUPPORT */
  3065. Info->Type != SLIB_TYPE_YUV_AVI)
  3066. slibStartVideo(Info, FALSE);
  3067. break;
  3068. case SLIB_DATA_AUDIO:
  3069. _SlibDebug(_VERBOSE_||_SEEK_>1,
  3070. printf("slibPinFinishReposition(Audio) in\n") );
  3071. if (Info->AudioCodecState==SLIB_CODEC_STATE_REPOSITIONING &&
  3072. Info->Sah && slibGetPin(Info, SLIB_DATA_AUDIO))
  3073. slibStartAudio(Info);
  3074. break;
  3075. default:
  3076. _SlibDebug(_VERBOSE_||_SEEK_>1,
  3077. printf("slibPinFinishReposition(%d) in\n", pinid) );
  3078. }
  3079. _SlibDebug(_VERBOSE_||_SEEK_>1, printf("slibPinFinishReposition(%d) out\n",
  3080. pinid) );
  3081. }
  3082. SlibBoolean_t slibUpdateLengths(SlibInfo_t *Info)
  3083. {
  3084. if (Info->FileSize>0 && !Info->VideoLengthKnown &&
  3085. (SlibTimeIsValid(Info->VideoPTimeCode) ||
  3086. SvGetParamInt(Info->Svh, SV_PARAM_CALCTIMECODE)>=1000)
  3087. )
  3088. {
  3089. if (Info->VideoTimeStamp>Info->VideoLength)
  3090. Info->VideoLength=Info->VideoTimeStamp;
  3091. Info->VideoLengthKnown=TRUE;
  3092. _SlibDebug(_SEEK_ || _TIMECODE_,
  3093. printf("slibUpdateLengths() AudioLength=%ld VideoLength=%ld\n",
  3094. Info->AudioLength, Info->VideoLength) );
  3095. return(TRUE);
  3096. }
  3097. return(FALSE);
  3098. }
  3099. SlibBoolean_t slibUpdatePositions(SlibInfo_t *Info, SlibBoolean_t exactonly)
  3100. {
  3101. SlibBoolean_t updated=FALSE;
  3102. if (!exactonly)
  3103. {
  3104. if (SlibTimeIsValid(Info->VideoTimeStamp))
  3105. updated=TRUE;
  3106. else if (SlibTimeIsValid(Info->AudioTimeStamp))
  3107. {
  3108. if (slibHasVideo(Info))
  3109. Info->VideoTimeStamp=Info->AudioTimeStamp;
  3110. updated=TRUE;
  3111. }
  3112. else if (slibHasVideo(Info))
  3113. {
  3114. Info->VideoTimeStamp=slibGetNextTimeOnPin(Info, slibGetPin(Info, SLIB_DATA_VIDEO), 500*1024);
  3115. if (SlibTimeIsValid(Info->VideoTimeStamp))
  3116. {
  3117. Info->VideoTimeStamp-=Info->VideoPTimeBase;
  3118. updated=TRUE;
  3119. }
  3120. }
  3121. }
  3122. if (!updated && (!exactonly || SlibTimeIsInValid(Info->VideoPTimeBase)) &&
  3123. SvGetParamInt(Info->Svh, SV_PARAM_CALCTIMECODE)>=1500 &&
  3124. SvGetParamInt(Info->Svh, SV_PARAM_FRAME)>24)
  3125. {
  3126. _SlibDebug(_TIMECODE_, printf("slibUpdatePositions() using video time\n") );
  3127. Info->VideoTimeStamp=SvGetParamInt(Info->Svh, SV_PARAM_CALCTIMECODE);
  3128. updated=TRUE;
  3129. }
  3130. if (updated)
  3131. {
  3132. if (Info->VideoTimeStamp>Info->VideoLength)
  3133. Info->VideoLength=Info->VideoTimeStamp;
  3134. if (SlibTimeIsInValid(Info->AudioTimeStamp) && slibHasAudio(Info))
  3135. {
  3136. /* need to update audio time */
  3137. Info->AudioTimeStamp=slibGetNextTimeOnPin(Info, slibGetPin(Info, SLIB_DATA_AUDIO), 100*1024);
  3138. if (SlibTimeIsInValid(Info->AudioTimeStamp))
  3139. Info->AudioTimeStamp=Info->VideoTimeStamp;
  3140. else
  3141. Info->AudioTimeStamp-=Info->AudioPTimeBase;
  3142. }
  3143. if (SlibTimeIsInValid(Info->VideoPTimeCode))
  3144. Info->VideoFramesProcessed=slibTimeToFrame(Info, Info->VideoTimeStamp);
  3145. }
  3146. _SlibDebug(_SEEK_ || _TIMECODE_,
  3147. printf("slibUpdatePositions() AudioTimeStamp=%ld VideoTimeStamp=%ld %s\n",
  3148. Info->AudioTimeStamp, Info->VideoTimeStamp, updated?"updated":"") );
  3149. return(updated);
  3150. }
  3151. void slibAdvancePositions(SlibInfo_t *Info, qword frames)
  3152. {
  3153. Info->VideoFramesProcessed+=frames;
  3154. if (Info->FramesPerSec)
  3155. {
  3156. if (Info->Mode==SLIB_MODE_COMPRESS ||
  3157. SlibTimeIsInValid(Info->VideoPTimeCode))
  3158. Info->VideoTimeStamp=slibFrameToTime(Info, Info->VideoFramesProcessed);
  3159. else
  3160. Info->VideoTimeStamp=Info->VideoPTimeCode - Info->VideoPTimeBase +
  3161. slibFrameToTime(Info, Info->VideoFramesProcessed);
  3162. /* Info->VideoTimeStamp+=slibFrameToTime(Info, frames); */
  3163. if (Info->VideoTimeStamp>Info->VideoLength)
  3164. Info->VideoLength=Info->VideoTimeStamp;
  3165. _SlibDebug(_TIMECODE_,
  3166. printf("slibAdvancePositions(frames=%d) VideoTimeStamp=%ld\n",
  3167. frames, Info->VideoTimeStamp) );
  3168. }
  3169. }
  3170. SlibStatus_t SlibSeek(SlibHandle_t handle, SlibStream_t stream,
  3171. SlibSeekType_t seektype, SlibPosition_t frame)
  3172. {
  3173. return(SlibSeekEx(handle, stream, seektype, frame, SLIB_UNIT_FRAMES, NULL));
  3174. }
  3175. SlibStatus_t SlibSeekEx(SlibHandle_t handle, SlibStream_t stream,
  3176. SlibSeekType_t seektype, SlibPosition_t seekpos,
  3177. SlibUnit_t seekunits, SlibSeekInfo_t *seekinfo)
  3178. {
  3179. SlibInfo_t *Info=(SlibInfo_t *)handle;
  3180. SvStatus_t status=SlibErrorNone;
  3181. SlibTime_t seektime, timediff;
  3182. unsigned int tries=0;
  3183. _SlibDebug(_SEEK_,
  3184. printf("SlibSeekEx(stream=%d,seektype=%d,pos=%ld,units=%d)\n",
  3185. stream,seektype,seekpos,seekunits) );
  3186. if (!handle)
  3187. return(SlibErrorBadHandle);
  3188. if (Info->Mode!=SLIB_MODE_DECOMPRESS && seektype!=SLIB_SEEK_RESET)
  3189. return(SlibErrorBadMode);
  3190. if (SlibSeekTypeUsesPosition(seektype))
  3191. {
  3192. switch (seekunits)
  3193. {
  3194. case SLIB_UNIT_FRAMES: /* frames */
  3195. /* we need to convert the frame to the time */
  3196. if (Info->FramesPerSec)
  3197. seektime=slibFrameToTime(Info, seekpos);
  3198. else
  3199. seektime=SLIB_TIME_NONE;
  3200. break;
  3201. case SLIB_UNIT_MS: /* milliseconds */
  3202. seektime=(seekpos<0) ? 0 : seekpos;
  3203. break;
  3204. case SLIB_UNIT_PERCENT100: /* 100th of a percent */
  3205. if (seekpos<0 || seekpos>10000)
  3206. return(SlibErrorBadPosition);
  3207. if (Info->VideoStreams==0 || stream==SLIB_STREAM_MAINAUDIO)
  3208. seektime=(seekpos * Info->AudioLength)/(SlibPosition_t)10000;
  3209. else
  3210. seektime=(seekpos * Info->VideoLength)/(SlibPosition_t)10000;
  3211. break;
  3212. default:
  3213. return(SlibErrorBadUnit);
  3214. }
  3215. /* see if the new position is past the end of the file */
  3216. if (Info->VideoLengthKnown && seektime>Info->VideoLength)
  3217. return(SlibErrorBadPosition);
  3218. }
  3219. else
  3220. seektime=(seekpos<0) ? 0 : seekpos;
  3221. if (seekinfo)
  3222. seekinfo->FramesSkipped=0;
  3223. switch(seektype)
  3224. {
  3225. case SLIB_SEEK_AHEAD:
  3226. _SlibDebug(_VERBOSE_||_SEEK_,
  3227. printf("SlibSeekEx(stream=%d,AHEAD,time=%d) VideoTimeStamp=%ld\n",
  3228. stream,seektime,Info->VideoTimeStamp) );
  3229. if (seektime<=0)
  3230. return(SlibErrorNone);
  3231. if (stream==SLIB_STREAM_MAINAUDIO || Info->VideoStreams<=0)
  3232. seektime+=Info->AudioTimeStamp;
  3233. else
  3234. seektime+=Info->VideoTimeStamp;
  3235. return(SlibSeekEx(handle, stream, SLIB_SEEK_NEXT_NEAR, seektime,
  3236. SLIB_UNIT_MS, seekinfo));
  3237. case SLIB_SEEK_NEXT_NEAR:
  3238. _SlibDebug(_VERBOSE_||_SEEK_,
  3239. printf("SlibSeekEx(stream=%d,NEXT_NEAR,time=%d) VideoTimeStamp=%ld\n",
  3240. stream,seektime,Info->VideoTimeStamp) );
  3241. status=slibStartVideo(Info, FALSE);
  3242. if (status==SlibErrorNone)
  3243. {
  3244. qword framesskipped=0;
  3245. SlibBoolean_t atkey=FALSE; /* key's must be decoded */
  3246. if (Info->Svh) /* update key spacing */
  3247. {
  3248. Info->KeySpacing=(int)SvGetParamInt(Info->Svh,
  3249. SV_PARAM_KEYSPACING);
  3250. Info->SubKeySpacing=(int)SvGetParamInt(Info->Svh,
  3251. SV_PARAM_SUBKEYSPACING);
  3252. }
  3253. timediff=seektime-Info->VideoTimeStamp;
  3254. while (status==SlibErrorNone &&
  3255. (timediff>500 ||
  3256. timediff>(Info->VideoFrameDuration*Info->KeySpacing*6)/1000))
  3257. {
  3258. status=SlibSeekEx(handle, stream, SLIB_SEEK_NEXT_KEY, 0,
  3259. SLIB_UNIT_NONE, seekinfo);
  3260. if (seekinfo) framesskipped+=seekinfo->FramesSkipped;
  3261. timediff=seektime-Info->VideoTimeStamp;
  3262. atkey=TRUE;
  3263. }
  3264. if (!atkey && status==SlibErrorNone &&
  3265. (timediff>150 ||
  3266. timediff>(Info->VideoFrameDuration*Info->SubKeySpacing*6)/1000))
  3267. {
  3268. if (SvGetParamInt(Info->Svh, SV_PARAM_FRAMETYPE)!=FRAME_TYPE_I &&
  3269. SvGetParamInt(Info->Svh, SV_PARAM_FRAMETYPE)!=FRAME_TYPE_P)
  3270. {
  3271. /* we're seeking past more than one frame */
  3272. status=SlibSeekEx(handle, stream, SLIB_SEEK_NEXT_SUBKEY, 0,
  3273. SLIB_UNIT_NONE, seekinfo);
  3274. if (seekinfo) framesskipped+=seekinfo->FramesSkipped;
  3275. timediff=seektime-Info->VideoTimeStamp;
  3276. }
  3277. atkey=TRUE;
  3278. }
  3279. while (!atkey && status==SlibErrorNone &&
  3280. timediff>Info->VideoFrameDuration/100)
  3281. {
  3282. if (SvGetParamInt(Info->Svh, SV_PARAM_FRAMETYPE)==FRAME_TYPE_B ||
  3283. SvGetParamInt(Info->Svh, SV_PARAM_FRAMETYPE)==FRAME_TYPE_NONE)
  3284. {
  3285. /* we can skip B frames without decompressing them */
  3286. status=SlibSeekEx(handle, stream, SLIB_SEEK_NEXT, 0,
  3287. SLIB_UNIT_NONE, seekinfo);
  3288. if (seekinfo) framesskipped+=seekinfo->FramesSkipped;
  3289. timediff=seektime-Info->VideoTimeStamp;
  3290. }
  3291. else
  3292. atkey=TRUE;
  3293. }
  3294. if (seekinfo) seekinfo->FramesSkipped=framesskipped;
  3295. }
  3296. return(status);
  3297. case SLIB_SEEK_NEXT:
  3298. _SlibDebug(_VERBOSE_||_SEEK_,
  3299. printf("SlibSeekEx(stream=%d,NEXT,time=%d) VideoTimeStamp=%ld\n",
  3300. stream,seektime,Info->VideoTimeStamp) );
  3301. if ((status=slibStartVideo(Info, FALSE))!=SlibErrorNone)
  3302. return(status);
  3303. #ifdef MPEG_SUPPORT
  3304. if (Info->VideoCodecState==SLIB_CODEC_STATE_BEGUN
  3305. && Info->Svh && SlibTypeIsMPEGVideo(Info->Type))
  3306. {
  3307. SvPictureInfo_t mpegPictureInfo;
  3308. unsigned char *videobuf;
  3309. /* cannot skip I or B frames without decompressing them */
  3310. if (SvGetParamInt(Info->Svh, SV_PARAM_FRAMETYPE)==FRAME_TYPE_I ||
  3311. SvGetParamInt(Info->Svh, SV_PARAM_FRAMETYPE)==FRAME_TYPE_P)
  3312. {
  3313. _SlibDebug(_DEBUG_||_SEEK_, printf("SvDecompressMPEG()\n") );
  3314. status = SvDecompressMPEG(Info->Svh, Info->Multibuf,
  3315. Info->MultibufSize, &videobuf);
  3316. _SlibDebug(_WARN_ && status!=SvErrorNone,
  3317. printf("SvDecompressMPEG() %s\n", ScGetErrorStr(status)) );
  3318. }
  3319. else
  3320. {
  3321. mpegPictureInfo.Type = SV_I_PICTURE|SV_P_PICTURE|SV_B_PICTURE;
  3322. _SlibDebug(_VERBOSE_||_SEEK_>1,
  3323. printf("SvFindNextPicture(I|P|B)\n") );
  3324. status = SvFindNextPicture(Info->Svh, &mpegPictureInfo);
  3325. _SlibDebug(_WARN_ && status!=SvErrorNone,
  3326. printf("SvFindNextPicture() %s\n", ScGetErrorStr(status)) );
  3327. }
  3328. if (status==NoErrors)
  3329. {
  3330. slibAdvancePositions(Info, 1);
  3331. if (Info->stats && Info->stats->Record)
  3332. Info->stats->FramesSkipped++;
  3333. if (seekinfo) seekinfo->FramesSkipped++;
  3334. }
  3335. else if (status==ScErrorEndBitstream)
  3336. {
  3337. if (Info->FileSize>0 && !Info->VideoLengthKnown)
  3338. slibUpdateLengths(Info);
  3339. return(SlibErrorEndOfStream);
  3340. }
  3341. return(SlibErrorNone);
  3342. }
  3343. #endif /* MPEG_SUPPORT */
  3344. return(SlibErrorReading);
  3345. case SLIB_SEEK_EXACT:
  3346. _SlibDebug(_VERBOSE_||_SEEK_,
  3347. printf("SlibSeekEx(stream=%d,EXACT,time=%d) VideoTimeStamp=%ld\n",
  3348. stream,seektime,Info->VideoTimeStamp) );
  3349. if (Info->FileSize<=0)
  3350. return(SlibErrorFileSize);
  3351. if (seektime==0 || Info->VideoStreams<=0)
  3352. return(SlibSeekEx(handle, stream, SLIB_SEEK_KEY, 0, SLIB_UNIT_MS,
  3353. seekinfo));
  3354. timediff=seektime-Info->VideoTimeStamp;
  3355. if ((stream==SLIB_STREAM_MAINVIDEO || Info->AudioStreams==0) &&
  3356. (timediff>=-20 && timediff<=20)) /* we're already near the frame */
  3357. return(SlibErrorNone);
  3358. if (Info->Svh) /* update key spacing */
  3359. Info->KeySpacing=(int)SvGetParamInt(Info->Svh, SV_PARAM_KEYSPACING);
  3360. if (timediff>(Info->KeySpacing*Info->VideoFrameDuration)/100 ||
  3361. timediff<0 ||
  3362. (stream!=SLIB_STREAM_MAINVIDEO && Info->AudioStreams>0))
  3363. {
  3364. if (Info->KeySpacing>1)
  3365. {
  3366. const SlibTime_t keytime=
  3367. (Info->VideoFrameDuration*Info->KeySpacing)/100;
  3368. if (seektime>=0 && seektime<keytime)
  3369. status=SlibSeekEx(handle, stream, SLIB_SEEK_KEY, 0,
  3370. SLIB_UNIT_MS, seekinfo);
  3371. else
  3372. status=SlibSeekEx(handle, stream, SLIB_SEEK_KEY,
  3373. seektime-(keytime*2), SLIB_UNIT_MS, seekinfo);
  3374. }
  3375. else
  3376. status=SlibSeekEx(handle, stream, SLIB_SEEK_KEY,
  3377. seektime-1000, SLIB_UNIT_MS, seekinfo);
  3378. if (status!=NoErrors) return(status);
  3379. timediff=seektime-Info->VideoTimeStamp;
  3380. }
  3381. #if 0
  3382. if (SvGetParamFloat(Info->Svh, SV_PARAM_FPS)>0)
  3383. Info->FramesPerSec=SvGetParamFloat(Info->Svh, SV_PARAM_FPS);
  3384. #endif
  3385. if (status==SlibErrorNone && timediff>=Info->VideoFrameDuration/100)
  3386. {
  3387. dword framesskipped=0;
  3388. do {
  3389. status=SlibSeekEx(handle, stream, SLIB_SEEK_NEXT, 0,
  3390. SLIB_UNIT_NONE, seekinfo);
  3391. framesskipped++;
  3392. timediff=seektime-Info->VideoTimeStamp;
  3393. } while (timediff>0 && status==SlibErrorNone);
  3394. if (seekinfo) seekinfo->FramesSkipped+=framesskipped;
  3395. /* if we skipped some frames, skip some audio too */
  3396. if (framesskipped>5 && stream==SLIB_STREAM_ALL &&
  3397. Info->AudioStreams>0)
  3398. {
  3399. slibPinPrepareReposition(Info, SLIB_DATA_AUDIO);
  3400. slibSkipAudio(Info, stream, (Info->VideoFrameDuration*
  3401. framesskipped)/100);
  3402. slibPinFinishReposition(Info, SLIB_DATA_AUDIO);
  3403. }
  3404. }
  3405. return(status);
  3406. case SLIB_SEEK_NEXT_KEY:
  3407. _SlibDebug(_VERBOSE_||_SEEK_,
  3408. printf("SlibSeekEx(stream=%d,NEXT_KEY,time=%d) VideoTimeStamp=%ld\n",
  3409. stream,seektime,Info->VideoTimeStamp) );
  3410. if ((status=slibStartVideo(Info, FALSE))!=SlibErrorNone)
  3411. return(status);
  3412. #ifdef MPEG_SUPPORT
  3413. if (Info->Svh && SlibTypeIsMPEGVideo(Info->Type))
  3414. {
  3415. SvPictureInfo_t mpegPictureInfo;
  3416. SlibTime_t vtime=Info->VideoTimeStamp;
  3417. do {
  3418. mpegPictureInfo.Type = SV_I_PICTURE;
  3419. status = SvFindNextPicture(Info->Svh, &mpegPictureInfo);
  3420. if (status==NoErrors && mpegPictureInfo.Type==SV_I_PICTURE)
  3421. {
  3422. if (Info->stats && Info->stats->Record)
  3423. Info->stats->FramesSkipped+=mpegPictureInfo.TemporalRef;
  3424. if (vtime==Info->VideoTimeStamp)
  3425. /* timecode didn't update time */
  3426. slibAdvancePositions(Info, mpegPictureInfo.TemporalRef);
  3427. vtime=Info->VideoTimeStamp;
  3428. if (seekinfo)
  3429. {
  3430. seekinfo->FramesSkipped+=mpegPictureInfo.TemporalRef;
  3431. seekinfo->VideoTimeStamp=Info->VideoTimeStamp;
  3432. seekinfo->AudioTimeStamp=Info->AudioTimeStamp;
  3433. }
  3434. return(SlibErrorNone);
  3435. }
  3436. } while (status==NoErrors);
  3437. if (seekinfo)
  3438. {
  3439. seekinfo->VideoTimeStamp=Info->VideoTimeStamp;
  3440. seekinfo->AudioTimeStamp=Info->AudioTimeStamp;
  3441. }
  3442. if (status==ScErrorEndBitstream)
  3443. {
  3444. if (Info->FileSize>0 && !Info->VideoLengthKnown)
  3445. slibUpdateLengths(Info);
  3446. return(SlibErrorEndOfStream);
  3447. }
  3448. }
  3449. _SlibDebug(_WARN_, printf("SvFindNextPicture() %s\n",
  3450. ScGetErrorStr(status)) );
  3451. #endif /* MPEG_SUPPORT */
  3452. /* do an absolute seek */
  3453. status=SlibSeekEx(handle, stream, SLIB_SEEK_KEY,
  3454. (Info->VideoStreams<=0?Info->AudioTimeStamp
  3455. :Info->VideoTimeStamp)+1000,
  3456. SLIB_UNIT_MS, seekinfo);
  3457. return(status);
  3458. case SLIB_SEEK_NEXT_SUBKEY:
  3459. _SlibDebug(_VERBOSE_||_SEEK_,
  3460. printf("SlibSeekEx(stream=%d,NEXT_SUBKEY,time=%d) VideoTime=%ld\n",
  3461. stream,seektime,Info->VideoTimeStamp) );
  3462. if ((status=slibStartVideo(Info, FALSE))!=SlibErrorNone)
  3463. return(status);
  3464. #ifdef MPEG_SUPPORT
  3465. if (Info->Svh && SlibTypeIsMPEGVideo(Info->Type))
  3466. {
  3467. SvPictureInfo_t mpegPictureInfo;
  3468. unsigned char *videobuf;
  3469. SlibTime_t vtime=Info->VideoTimeStamp;
  3470. /* cannot skip I or B frames without decompressing them */
  3471. if (SvGetParamInt(Info->Svh, SV_PARAM_FRAMETYPE)==FRAME_TYPE_I ||
  3472. SvGetParamInt(Info->Svh, SV_PARAM_FRAMETYPE)==FRAME_TYPE_P)
  3473. {
  3474. _SlibDebug(_DEBUG_||_SEEK_, printf("SvDecompressMPEG()\n") );
  3475. status = SvDecompressMPEG(Info->Svh, Info->Multibuf,
  3476. Info->MultibufSize, &videobuf);
  3477. if (vtime==Info->VideoTimeStamp /* timecode didn't update time */
  3478. && status==SvErrorNone)
  3479. slibAdvancePositions(Info, 1);
  3480. vtime=Info->VideoTimeStamp;
  3481. if (seekinfo)
  3482. seekinfo->FramesSkipped+=mpegPictureInfo.TemporalRef;
  3483. _SlibDebug(_WARN_ && status!=SvErrorNone,
  3484. printf("SvDecompressMPEG() %s\n", ScGetErrorStr(status)) );
  3485. }
  3486. do {
  3487. mpegPictureInfo.Type = SV_I_PICTURE|SV_P_PICTURE;
  3488. status = SvFindNextPicture(Info->Svh, &mpegPictureInfo);
  3489. if (Info->stats && Info->stats->Record)
  3490. Info->stats->FramesSkipped+=mpegPictureInfo.TemporalRef;
  3491. if (vtime==Info->VideoTimeStamp) /* timecode didn't update time */
  3492. slibAdvancePositions(Info, mpegPictureInfo.TemporalRef);
  3493. vtime=Info->VideoTimeStamp;
  3494. if (seekinfo)
  3495. seekinfo->FramesSkipped+=mpegPictureInfo.TemporalRef;
  3496. if (mpegPictureInfo.Type == SV_I_PICTURE ||
  3497. mpegPictureInfo.Type == SV_P_PICTURE)
  3498. {
  3499. /* found a subkey frame */
  3500. if (seekinfo)
  3501. {
  3502. seekinfo->VideoTimeStamp=Info->VideoTimeStamp;
  3503. seekinfo->AudioTimeStamp=Info->AudioTimeStamp;
  3504. }
  3505. return(SlibErrorNone);
  3506. }
  3507. } while(status==NoErrors);
  3508. if (status==ScErrorEndBitstream)
  3509. {
  3510. if (Info->FileSize>0 && !Info->VideoLengthKnown)
  3511. slibUpdateLengths(Info);
  3512. if (seekinfo)
  3513. {
  3514. seekinfo->VideoTimeStamp=Info->VideoTimeStamp;
  3515. seekinfo->AudioTimeStamp=Info->AudioTimeStamp;
  3516. }
  3517. return(SlibErrorEndOfStream);
  3518. }
  3519. }
  3520. _SlibDebug(_WARN_, printf("SvFindNextPicture() %s\n",
  3521. ScGetErrorStr(status)) );
  3522. #endif /* MPEG_SUPPORT */
  3523. /* do an absolute seek */
  3524. status=SlibSeekEx(handle, stream, SLIB_SEEK_KEY,
  3525. (Info->VideoStreams<=0?Info->AudioTimeStamp
  3526. :Info->VideoTimeStamp)+500,
  3527. SLIB_UNIT_MS, seekinfo);
  3528. return(status);
  3529. case SLIB_SEEK_KEY:
  3530. _SlibDebug(_VERBOSE_||_SEEK_,
  3531. printf("SlibSeekEx(stream=%d,KEY,time=%d) VideoTimeStamp=%ld\n",
  3532. stream,seektime,Info->VideoTimeStamp) );
  3533. if (!Info->HeaderProcessed)
  3534. {
  3535. /* At very start of file we must Start the codecs since they
  3536. * may need crucial header info
  3537. */
  3538. status=slibStartVideo(Info, FALSE);
  3539. if (status!=SlibErrorNone) return(status);
  3540. }
  3541. if (Info->FileSize<=0)
  3542. return(SlibErrorFileSize);
  3543. if (seekpos!=0 && seekunits!=SLIB_UNIT_PERCENT100 &&
  3544. (stream==SLIB_STREAM_MAINVIDEO || Info->AudioStreams==0) &&
  3545. SlibTimeIsValid(Info->VideoTimeStamp))
  3546. {
  3547. /* see if we're already near the frame */
  3548. timediff=seektime-Info->VideoTimeStamp;
  3549. if (timediff>=-33 && timediff<=33)
  3550. return(SlibErrorNone);
  3551. }
  3552. if ((seekunits==SLIB_UNIT_PERCENT100 && seekpos<=50)
  3553. || seektime<=slibTimeToFrame(Info, 6))
  3554. {
  3555. /* close to beginning */
  3556. if (seektime<=(Info->VideoFrameDuration*2)/100 &&
  3557. stream==SLIB_STREAM_MAINVIDEO) /* already close enough */
  3558. return(SlibErrorNone);
  3559. seek_to_beginning:
  3560. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINVIDEO)
  3561. slibPinPrepareReposition(Info, SLIB_DATA_VIDEO);
  3562. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINAUDIO)
  3563. slibPinPrepareReposition(Info, SLIB_DATA_AUDIO);
  3564. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINVIDEO)
  3565. slibEmptyPin(Info, SLIB_DATA_VIDEO);
  3566. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINAUDIO)
  3567. slibEmptyPin(Info, SLIB_DATA_AUDIO);
  3568. slibEmptyPin(Info, SLIB_DATA_COMPRESSED);
  3569. if ((status=slibReposition(Info, 0))!=SlibErrorNone)
  3570. return(status);
  3571. Info->IOError=FALSE;
  3572. Info->VideoTimeStamp = slibHasVideo(Info) ? 0 : SLIB_TIME_NONE;
  3573. Info->AudioTimeStamp = slibHasAudio(Info) ? 0 : SLIB_TIME_NONE;
  3574. return(SlibErrorNone);
  3575. }
  3576. else
  3577. {
  3578. qword skippedframes=0;
  3579. unsigned qword filepos;
  3580. SlibTime_t vtime;
  3581. const qword length=(Info->VideoStreams<=0) ? Info->AudioLength
  3582. : Info->VideoLength;
  3583. if (seekunits==SLIB_UNIT_PERCENT100)
  3584. {
  3585. unsigned qword bytes_between_keys=Info->TotalBitRate/(8*2);
  3586. filepos = (seekpos*Info->FileSize)/10000;
  3587. /* seek a little before the desired point */
  3588. if (bytes_between_keys>filepos)
  3589. goto seek_to_beginning;
  3590. else
  3591. filepos-=bytes_between_keys;
  3592. }
  3593. else if (length==0)
  3594. goto seek_to_beginning;
  3595. else if (Info->FileSize<0x100000000)/* be careful of mul overflow */
  3596. filepos = (seektime*Info->FileSize)/length;
  3597. else
  3598. filepos = ((seektime/100)*Info->FileSize)/(length/100);
  3599. seek_to_key:
  3600. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINVIDEO)
  3601. slibPinPrepareReposition(Info, SLIB_DATA_VIDEO);
  3602. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINAUDIO)
  3603. slibPinPrepareReposition(Info, SLIB_DATA_AUDIO);
  3604. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINVIDEO)
  3605. slibEmptyPin(Info, SLIB_DATA_VIDEO);
  3606. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINAUDIO)
  3607. slibEmptyPin(Info, SLIB_DATA_AUDIO);
  3608. slibEmptyPin(Info, SLIB_DATA_COMPRESSED);
  3609. if ((status=slibReposition(Info, filepos))!=SlibErrorNone)
  3610. return(status);
  3611. Info->IOError=FALSE;
  3612. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINVIDEO)
  3613. slibPinFinishReposition(Info, SLIB_DATA_VIDEO);
  3614. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINAUDIO)
  3615. slibPinFinishReposition(Info, SLIB_DATA_AUDIO);
  3616. vtime=Info->VideoTimeStamp;
  3617. #ifdef MPEG_SUPPORT
  3618. if (Info->Svh && SlibTypeIsMPEGVideo(Info->Type))
  3619. {
  3620. SvPictureInfo_t mpegPictureInfo;
  3621. if ((status=slibStartVideo(Info, FALSE))!=SlibErrorNone)
  3622. return(status);
  3623. mpegPictureInfo.Type = SV_I_PICTURE;
  3624. status = SvFindNextPicture(Info->Svh, &mpegPictureInfo);
  3625. _SlibDebug(_WARN_ && status!=NoErrors,
  3626. printf("SvFindNextPicture() %s\n",
  3627. ScGetErrorStr(status)) );
  3628. if (status!=NoErrors)
  3629. return(SlibErrorEndOfStream);
  3630. skippedframes=mpegPictureInfo.TemporalRef;
  3631. }
  3632. #endif /* MPEG_SUPPORT */
  3633. if (seekunits==SLIB_UNIT_PERCENT100)
  3634. {
  3635. /* See if we seeked to far ahead */
  3636. SlibPosition_t posdiff=
  3637. SlibGetParamInt(Info, SLIB_STREAM_ALL, SLIB_PARAM_PERCENT100)
  3638. -seekpos;
  3639. if (filepos>0 && posdiff>0 && tries<2)
  3640. {
  3641. tries++;
  3642. /* we're ahead by one percent or more */
  3643. /* move filepos back in the proportion that we're off by */
  3644. filepos-=(posdiff*Info->FileSize)/8000;
  3645. if (filepos<0)
  3646. goto seek_to_beginning;
  3647. goto seek_to_key;
  3648. }
  3649. }
  3650. if (slibUpdatePositions(Info, FALSE)) /* timecoded */
  3651. {
  3652. /* timecoded */
  3653. /*
  3654. * See if we seeked to far ahead
  3655. * Note: if times are way off then we should ignore them.
  3656. */
  3657. if (seekunits==SLIB_UNIT_PERCENT100) /* ignore times */
  3658. timediff=0;
  3659. else
  3660. {
  3661. timediff=seektime-Info->VideoTimeStamp;
  3662. if (timediff>-5000 && timediff<-100 && tries<3)
  3663. {
  3664. /* move filepos back in the proportion that we're off by */
  3665. filepos=(filepos*seektime)/Info->VideoTimeStamp;
  3666. if (filepos<0)
  3667. filepos=0;
  3668. tries++;
  3669. goto seek_to_key;
  3670. }
  3671. }
  3672. #ifdef MPEG_SUPPORT
  3673. if (Info->Svh && SlibTypeIsMPEGVideo(Info->Type))
  3674. {
  3675. SvPictureInfo_t mpegPictureInfo;
  3676. mpegPictureInfo.Type = SV_I_PICTURE;
  3677. while (timediff>Info->VideoFrameDuration/100 &&status==NoErrors)
  3678. {
  3679. _SlibDebug(_SEEK_>1,
  3680. printf("SlibSeekEx(KEY, %d) Find next I frame (%d/%d)\n",
  3681. seektime, SvGetParamInt(Info->Svh, SV_PARAM_CALCTIMECODE),
  3682. Info->VideoTimeStamp) );
  3683. status = SvFindNextPicture(Info->Svh, &mpegPictureInfo);
  3684. _SlibDebug(_WARN_ && status!=NoErrors,
  3685. printf("SvFindNextPicture() %s\n", ScGetErrorStr(status)) );
  3686. skippedframes+=mpegPictureInfo.TemporalRef;
  3687. if (vtime==Info->VideoTimeStamp)
  3688. /* timecode didn't update time */
  3689. slibAdvancePositions(Info, mpegPictureInfo.TemporalRef);
  3690. vtime=Info->VideoTimeStamp;
  3691. timediff=seektime-Info->VideoTimeStamp;
  3692. }
  3693. }
  3694. #endif /* MPEG_SUPPORT */
  3695. }
  3696. else
  3697. {
  3698. _SlibDebug(_SEEK_, printf("SlibSeekEx(KEY, %d) no timecode\n",
  3699. seektime) );
  3700. if (slibHasVideo(Info))
  3701. {
  3702. Info->VideoTimeStamp=seektime;
  3703. Info->VideoFramesProcessed=slibTimeToFrame(Info, seektime);
  3704. }
  3705. if (slibHasAudio(Info))
  3706. Info->AudioTimeStamp=seektime;
  3707. slibAdvancePositions(Info, skippedframes);
  3708. timediff=seektime-Info->VideoTimeStamp;
  3709. }
  3710. if (Info->stats && Info->stats->Record)
  3711. Info->stats->FramesSkipped+=skippedframes;
  3712. if (seekinfo) seekinfo->FramesSkipped=skippedframes;
  3713. #if 0
  3714. if (Info->Svh)
  3715. Info->FramesPerSec=SvGetParamFloat(Info->Svh, SV_PARAM_FPS);
  3716. #endif
  3717. /* if we skipped some frames, skip some audio too */
  3718. if (skippedframes>5 && stream==SLIB_STREAM_ALL && slibHasAudio(Info))
  3719. {
  3720. slibPinPrepareReposition(Info, SLIB_DATA_AUDIO);
  3721. slibSkipAudio(Info, stream, (Info->VideoFrameDuration*
  3722. skippedframes)/100);
  3723. slibPinFinishReposition(Info, SLIB_DATA_AUDIO);
  3724. if (SlibTimeIsInValid(Info->AudioTimeStamp))
  3725. {
  3726. Info->AudioTimeStamp=slibGetNextTimeOnPin(Info, slibGetPin(Info, SLIB_DATA_AUDIO), 100*1024);
  3727. if (SlibTimeIsInValid(Info->AudioTimeStamp))
  3728. Info->AudioTimeStamp=Info->VideoTimeStamp;
  3729. else
  3730. Info->AudioTimeStamp-=Info->AudioPTimeBase;
  3731. }
  3732. }
  3733. if (status==ScErrorEndBitstream)
  3734. {
  3735. if (Info->FileSize>0 && !Info->VideoLengthKnown)
  3736. slibUpdateLengths(Info);
  3737. return(SlibErrorEndOfStream);
  3738. }
  3739. else if (status!=NoErrors)
  3740. return(SlibErrorReading);
  3741. return(SlibErrorNone);
  3742. }
  3743. break;
  3744. case SLIB_SEEK_RESET:
  3745. _SlibDebug(_VERBOSE_||_SEEK_,
  3746. printf("SlibSeekEx(stream=%d,RESET,time=%d) VideoTimeStamp=%ld\n",
  3747. stream,seektime,Info->VideoTimeStamp) );
  3748. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINVIDEO)
  3749. slibPinPrepareReposition(Info, SLIB_DATA_VIDEO);
  3750. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINAUDIO)
  3751. slibPinPrepareReposition(Info, SLIB_DATA_AUDIO);
  3752. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINVIDEO)
  3753. slibEmptyPin(Info, SLIB_DATA_VIDEO);
  3754. if (stream==SLIB_STREAM_ALL || stream==SLIB_STREAM_MAINAUDIO)
  3755. slibEmptyPin(Info, SLIB_DATA_AUDIO);
  3756. if (stream==SLIB_STREAM_MAINAUDIO)
  3757. slibPinFinishReposition(Info, SLIB_DATA_AUDIO);
  3758. if (stream==SLIB_STREAM_ALL)
  3759. {
  3760. slibEmptyPin(Info, SLIB_DATA_COMPRESSED);
  3761. Info->BytesProcessed = 0;
  3762. }
  3763. Info->HeaderProcessed = FALSE;
  3764. return(SlibErrorNone);
  3765. case SLIB_SEEK_RESYNC:
  3766. seekpos=SlibGetParamInt(Info, SLIB_STREAM_ALL, SLIB_PARAM_PERCENT100);
  3767. if (seekpos<0 ||
  3768. (SlibTimeIsValid(Info->VideoTimeStamp) &&
  3769. Info->VideoTimeStamp<slibFrameToTime(Info, 6)))
  3770. seekpos=0;
  3771. _SlibDebug(_VERBOSE_||_SEEK_,
  3772. printf("SlibSeekEx(stream=%d,RESYNC) seekpos=%ld\n",
  3773. stream, seekpos) );
  3774. return(SlibSeekEx(handle, SLIB_STREAM_ALL, SLIB_SEEK_KEY, seekpos,
  3775. SLIB_UNIT_PERCENT100, seekinfo));
  3776. default:
  3777. _SlibDebug(_VERBOSE_||_SEEK_||_WARN_,
  3778. printf("SlibSeekEx(stream=%d,seektype=%d,time=%d) VideoTimeStamp=%ld Bad seek type\n",
  3779. stream,seektype,seektime,Info->VideoTimeStamp) );
  3780. }
  3781. return(SlibErrorForwardOnly);
  3782. }
  3783. SlibList_t *SlibQueryList(SlibQueryType_t qtype)
  3784. {
  3785. switch(qtype)
  3786. {
  3787. case SLIB_QUERY_TYPES: return(_listTypes);
  3788. case SLIB_QUERY_COMP_TYPES: return(_listCompressTypes);
  3789. case SLIB_QUERY_DECOMP_TYPES: return(_listDecompressTypes);
  3790. case SLIB_QUERY_ERRORS: return(_listErrors);
  3791. default: return(NULL);
  3792. }
  3793. }
  3794. char *SlibQueryForDesc(SlibQueryType_t qtype, int enumval)
  3795. {
  3796. SlibList_t *entry=SlibQueryList(qtype);
  3797. if (entry)
  3798. entry=SlibFindEnumEntry(entry, enumval);
  3799. if (entry)
  3800. return(entry->Desc);
  3801. else
  3802. return(NULL);
  3803. }
  3804. int SlibQueryForEnum(SlibQueryType_t qtype, char *name)
  3805. {
  3806. SlibList_t *list=SlibQueryList(qtype);
  3807. if (!list)
  3808. return(-1);
  3809. while (list->Name)
  3810. {
  3811. if (strcmp(list->Name, name)==0)
  3812. return(list->Enum);
  3813. list++;
  3814. }
  3815. return(-1);
  3816. }
  3817. SlibBoolean_t SlibIsEnd(SlibHandle_t handle, SlibStream_t stream)
  3818. {
  3819. SlibInfo_t *Info=(SlibInfo_t *)handle;
  3820. SlibBoolean_t isend=FALSE;
  3821. if (!handle)
  3822. isend=TRUE;
  3823. else if (stream==SLIB_STREAM_MAINAUDIO)
  3824. {
  3825. isend=SlibPeekBuffer(Info, SLIB_DATA_AUDIO, NULL, NULL)==NULL?TRUE:FALSE;
  3826. if (isend && Info->Sah) /* see if the audio codec still has data */
  3827. {
  3828. ScBitstream_t *bs=SaGetDataSource(Info->Sah);
  3829. if (bs && !bs->EOI) isend=FALSE;
  3830. }
  3831. }
  3832. else if (stream==SLIB_STREAM_MAINVIDEO)
  3833. {
  3834. isend=SlibPeekBuffer(Info, SLIB_DATA_VIDEO, NULL, NULL)==NULL?TRUE:FALSE;
  3835. if (isend && Info->Svh) /* see if the video codec still has data */
  3836. {
  3837. ScBitstream_t *bs=SvGetDataSource(Info->Svh);
  3838. if (bs && !bs->EOI) isend=FALSE;
  3839. }
  3840. }
  3841. else if (SlibPeekBuffer(Info, SLIB_DATA_AUDIO, NULL, NULL)==NULL &&
  3842. SlibPeekBuffer(Info, SLIB_DATA_VIDEO, NULL, NULL)==NULL &&
  3843. SlibPeekBuffer(Info, SLIB_DATA_COMPRESSED, NULL, NULL)==NULL)
  3844. {
  3845. ScBitstream_t *bs;
  3846. isend=TRUE;
  3847. if (Info->Svh) /* see if the video codec still has data */
  3848. {
  3849. bs=SvGetDataSource(Info->Svh);
  3850. if (bs && !bs->EOI) isend=FALSE;
  3851. }
  3852. if (isend && Info->Sah) /* see if the audio codec still has data */
  3853. {
  3854. bs=SaGetDataSource(Info->Sah);
  3855. if (bs && !bs->EOI) isend=FALSE;
  3856. }
  3857. }
  3858. _SlibDebug(_VERBOSE_,
  3859. printf("SlibIsEnd() %s\n",isend?"TRUE":"FALSE"));
  3860. return(isend);
  3861. }
  3862. SlibStatus_t SlibClose(SlibHandle_t handle)
  3863. {
  3864. SlibInfo_t *Info=(SlibInfo_t *)handle;
  3865. _SlibDebug(_DEBUG_, printf("SlibClose\n") );
  3866. if (!handle)
  3867. return(SlibErrorBadHandle);
  3868. /* close video codec */
  3869. if (Info->Svh)
  3870. {
  3871. if (Info->VideoCodecState==SLIB_CODEC_STATE_BEGUN)
  3872. {
  3873. _SlibDebug(_DEBUG_, printf("SvDecompress/CompressEnd()\n") );
  3874. if (Info->Mode==SLIB_MODE_DECOMPRESS)
  3875. SvDecompressEnd(Info->Svh);
  3876. else if (Info->Mode==SLIB_MODE_COMPRESS)
  3877. SvCompressEnd(Info->Svh);
  3878. Info->VideoCodecState=SLIB_CODEC_STATE_INITED;
  3879. }
  3880. _SlibDebug(_DEBUG_, printf("SvCloseCodec()\n") );
  3881. SvCloseCodec(Info->Svh);
  3882. }
  3883. Info->VideoCodecState=SLIB_CODEC_STATE_NONE;
  3884. /* close audio codec */
  3885. if (Info->Sah)
  3886. {
  3887. if (Info->AudioCodecState==SLIB_CODEC_STATE_BEGUN)
  3888. {
  3889. if (Info->Mode==SLIB_MODE_DECOMPRESS)
  3890. SaDecompressEnd(Info->Sah);
  3891. else if (Info->Mode==SLIB_MODE_COMPRESS)
  3892. SaCompressEnd(Info->Sah);
  3893. Info->AudioCodecState=SLIB_CODEC_STATE_INITED;
  3894. }
  3895. _SlibDebug(_DEBUG_, printf("SaCloseCodec()\n") );
  3896. SaCloseCodec(Info->Sah);
  3897. }
  3898. Info->AudioCodecState=SLIB_CODEC_STATE_NONE;
  3899. if (Info->Mode==SLIB_MODE_COMPRESS && Info->HeaderProcessed)
  3900. slibCommitBuffers(Info, TRUE);
  3901. /* close format converter */
  3902. if (Info->Sch)
  3903. {
  3904. SconClose(Info->Sch);
  3905. Info->Sch=NULL;
  3906. }
  3907. /* close data sources */
  3908. if (Info->Fd>=0)
  3909. {
  3910. _SlibDebug(_DEBUG_, printf("ScFileClose(%d)\n",Info->Fd) );
  3911. ScFileClose(Info->Fd);
  3912. Info->Fd=-1;
  3913. }
  3914. slibRemovePins(Info);
  3915. /* slibDumpMemory(); */
  3916. if (Info->SlibCB)
  3917. {
  3918. SlibMessage_t result;
  3919. _SlibDebug(_VERBOSE_,
  3920. printf("SlibClose() SlibCB(SLIB_MSG_CLOSE)\n") );
  3921. result=(*(Info->SlibCB))((SlibHandle_t)Info,
  3922. SLIB_MSG_CLOSE, (SlibCBParam1_t)0,
  3923. (SlibCBParam2_t)0, (void *)Info->SlibCBUserData);
  3924. Info->SlibCB=NULL;
  3925. }
  3926. /* free memory */
  3927. if (Info->stats) ScFree(Info->stats);
  3928. if (Info->CompVideoFormat) ScFree(Info->CompVideoFormat);
  3929. if (Info->CodecVideoFormat) ScFree(Info->CodecVideoFormat);
  3930. if (Info->VideoFormat) ScFree(Info->VideoFormat);
  3931. if (Info->AudioFormat) ScFree(Info->AudioFormat);
  3932. if (Info->CompAudioFormat) ScFree(Info->CompAudioFormat);
  3933. if (Info->Imagebuf) SlibFreeBuffer(Info->Imagebuf);
  3934. if (Info->CodecImagebuf) SlibFreeBuffer(Info->CodecImagebuf);
  3935. if (Info->IntImagebuf) SlibFreeBuffer(Info->IntImagebuf);
  3936. if (Info->Audiobuf) SlibFreeBuffer(Info->Audiobuf);
  3937. if (Info->Multibuf) /* free all outstanding allocations on Multibuf */
  3938. while (SlibFreeBuffer(Info->Multibuf)==SlibErrorNone);
  3939. ScFree(Info);
  3940. _SlibDebug(_WARN_ && SlibMemUsed()>0, printf("SlibClose() mem used=%d\n",
  3941. SlibMemUsed()) );
  3942. return(SlibErrorNone);
  3943. }
  3944. /*
  3945. SlibStatus_t SlibGetInfo(SlibHandle_t handle, SlibInfo_t *info)
  3946. {
  3947. if (!handle)
  3948. return(SlibErrorBadHandle);
  3949. if (!info)
  3950. return(SlibErrorBadArgument);
  3951. memcpy(info, handle, sizeof(SlibInfo_t));
  3952. return(SlibErrorNone);
  3953. }
  3954. */