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.

3922 lines
128 KiB

  1. /*
  2. * @DEC_COPYRIGHT@
  3. */
  4. /*
  5. * HISTORY
  6. * $Log: slib_buffer.c,v $
  7. * Revision 1.1.6.26 1996/12/13 18:19:07 Hans_Graves
  8. * Check for valid pin pointer in slibGetNextTimeOnPin().
  9. * [1996/12/13 18:08:27 Hans_Graves]
  10. *
  11. * Revision 1.1.6.25 1996/12/10 19:21:58 Hans_Graves
  12. * Fix MPEG Systems encoding bug.
  13. * [1996/12/10 19:15:33 Hans_Graves]
  14. *
  15. * Revision 1.1.6.24 1996/12/04 22:34:32 Hans_Graves
  16. * Enable AC3 detection in PRIVATE packets.
  17. * [1996/12/04 22:18:48 Hans_Graves]
  18. *
  19. * Revision 1.1.6.23 1996/12/03 23:15:16 Hans_Graves
  20. * Fixed updating of offset value for buffers on pins.
  21. * [1996/12/03 23:09:51 Hans_Graves]
  22. *
  23. * Revision 1.1.6.22 1996/12/03 00:08:33 Hans_Graves
  24. * Handling of End Of Sequence points. Added PERCENT100 support.
  25. * [1996/12/03 00:06:03 Hans_Graves]
  26. *
  27. * Revision 1.1.6.21 1996/11/18 23:07:36 Hans_Graves
  28. * Make use of presentation timestamps. Make seeking time-based.
  29. * [1996/11/18 22:47:40 Hans_Graves]
  30. *
  31. * Revision 1.1.6.20 1996/11/13 16:10:56 Hans_Graves
  32. * Skip AC3 header in private packets.
  33. * [1996/11/13 16:03:50 Hans_Graves]
  34. *
  35. * Revision 1.1.6.19 1996/11/11 18:21:07 Hans_Graves
  36. * Added AC3 support for multiplexed streams.
  37. * [1996/11/11 18:00:27 Hans_Graves]
  38. *
  39. * Revision 1.1.6.18 1996/11/08 21:51:06 Hans_Graves
  40. * Added AC3 support. Fixed Program Stream demultiplexing.
  41. * [1996/11/08 21:31:43 Hans_Graves]
  42. *
  43. * Revision 1.1.6.17 1996/10/31 21:58:09 Hans_Graves
  44. * Turned of debugging code.
  45. * [1996/10/31 21:57:56 Hans_Graves]
  46. *
  47. * Revision 1.1.6.16 1996/10/31 21:55:47 Hans_Graves
  48. * Fix bad multiplexing when encoding to MPEG Systems.
  49. * [1996/10/31 21:15:01 Hans_Graves]
  50. *
  51. * Revision 1.1.6.15 1996/10/29 17:04:59 Hans_Graves
  52. * Add padding packets support for MPEG Systems Encoding.
  53. * [1996/10/29 17:04:45 Hans_Graves]
  54. *
  55. * Revision 1.1.6.14 1996/10/28 17:32:32 Hans_Graves
  56. * MME-1402, 1431, 1435: Timestamp related changes.
  57. * [1996/10/28 17:23:03 Hans_Graves]
  58. *
  59. * Revision 1.1.6.13 1996/10/17 00:23:34 Hans_Graves
  60. * Fix buffer problems after SlibQueryData() calls.
  61. * [1996/10/17 00:19:14 Hans_Graves]
  62. *
  63. * Revision 1.1.6.12 1996/10/15 17:34:13 Hans_Graves
  64. * Added MPEG-2 Program Stream support.
  65. * [1996/10/15 17:30:30 Hans_Graves]
  66. *
  67. * Revision 1.1.6.11 1996/10/12 17:18:54 Hans_Graves
  68. * Added parsing of Decode and Presentation timestamps with MPEG Transport.
  69. * [1996/10/12 17:01:55 Hans_Graves]
  70. *
  71. * Revision 1.1.6.10 1996/10/03 19:14:24 Hans_Graves
  72. * Added Presentation and Decoding timestamp support.
  73. * [1996/10/03 19:10:38 Hans_Graves]
  74. *
  75. * Revision 1.1.6.9 1996/09/29 22:19:41 Hans_Graves
  76. * Added debugging printf's
  77. * [1996/09/29 21:30:27 Hans_Graves]
  78. *
  79. * Revision 1.1.6.8 1996/09/25 19:16:48 Hans_Graves
  80. * Added SLIB_INTERNAL define.
  81. * [1996/09/25 19:01:53 Hans_Graves]
  82. *
  83. * Revision 1.1.6.7 1996/09/18 23:46:48 Hans_Graves
  84. * MPEG2 Systems parsing fixes. Added Audio presentation timestamps to MPEG1 Systems writing
  85. * [1996/09/18 22:06:07 Hans_Graves]
  86. *
  87. * Revision 1.1.6.6 1996/08/09 20:51:48 Hans_Graves
  88. * Fix callbacks with user buffers
  89. * [1996/08/09 20:11:06 Hans_Graves]
  90. *
  91. * Revision 1.1.6.5 1996/07/19 02:11:13 Hans_Graves
  92. * Added support for SLIB_MSG_BUFDONE with user buffers.
  93. * [1996/07/19 02:02:53 Hans_Graves]
  94. *
  95. * Revision 1.1.6.4 1996/06/07 18:26:12 Hans_Graves
  96. * Merge MME-01326. Encoded MPEG-1 Systems files now include Presentation timestamps
  97. * [1996/06/07 17:54:11 Hans_Graves]
  98. *
  99. * Revision 1.1.6.3 1996/05/10 21:17:27 Hans_Graves
  100. * Add Callback support.
  101. * [1996/05/10 20:58:39 Hans_Graves]
  102. *
  103. * Revision 1.1.6.2 1996/05/07 19:56:22 Hans_Graves
  104. * Added HUFF_SUPPORT.
  105. * [1996/05/07 17:20:50 Hans_Graves]
  106. *
  107. * Revision 1.1.4.10 1996/05/02 17:10:35 Hans_Graves
  108. * Better checking for NULL pointers in ParseMpeg2Systems(). Fixes MME-01234
  109. * [1996/05/02 17:05:46 Hans_Graves]
  110. *
  111. * Revision 1.1.4.9 1996/04/24 22:33:46 Hans_Graves
  112. * MPEG encoding bitrate fixups.
  113. * [1996/04/24 22:27:13 Hans_Graves]
  114. *
  115. * Revision 1.1.4.8 1996/04/23 15:36:42 Hans_Graves
  116. * Added MPEG 1 Systems packet recovery
  117. * [1996/04/23 15:35:23 Hans_Graves]
  118. *
  119. * Revision 1.1.4.7 1996/04/19 21:52:24 Hans_Graves
  120. * MPEG 1 Systems writing enhancements
  121. * [1996/04/19 21:47:53 Hans_Graves]
  122. *
  123. * Revision 1.1.4.6 1996/04/01 19:07:54 Hans_Graves
  124. * And some error checking
  125. * [1996/04/01 19:04:37 Hans_Graves]
  126. *
  127. * Revision 1.1.4.5 1996/04/01 16:23:16 Hans_Graves
  128. * NT porting
  129. * [1996/04/01 16:16:00 Hans_Graves]
  130. *
  131. * Revision 1.1.4.4 1996/03/29 22:21:35 Hans_Graves
  132. * Added MPEG/JPEG/H261_SUPPORT ifdefs
  133. * [1996/03/29 21:57:01 Hans_Graves]
  134. *
  135. * Added MPEG-I Systems encoding support
  136. * [1996/03/27 21:55:57 Hans_Graves]
  137. *
  138. * Revision 1.1.4.3 1996/03/12 16:15:52 Hans_Graves
  139. * Changed hard coded File buffer size to param
  140. * [1996/03/12 15:57:23 Hans_Graves]
  141. *
  142. * Revision 1.1.4.2 1996/03/08 18:46:46 Hans_Graves
  143. * Increased Buffer size
  144. * [1996/03/08 18:40:59 Hans_Graves]
  145. *
  146. * Revision 1.1.2.13 1996/02/23 22:17:09 Hans_Graves
  147. * Fixed bad handling of large packets in ParseMpeg1()
  148. * [1996/02/23 21:56:15 Hans_Graves]
  149. *
  150. * Revision 1.1.2.12 1996/02/21 22:52:46 Hans_Graves
  151. * Fixed MPEG 2 systems stuff
  152. * [1996/02/21 22:51:11 Hans_Graves]
  153. *
  154. * Revision 1.1.2.11 1996/02/19 20:09:29 Hans_Graves
  155. * Debugging message clean-up
  156. * [1996/02/19 20:08:34 Hans_Graves]
  157. *
  158. * Revision 1.1.2.10 1996/02/19 18:03:58 Hans_Graves
  159. * Fixed a number of MPEG related bugs
  160. * [1996/02/19 17:57:43 Hans_Graves]
  161. *
  162. * Revision 1.1.2.9 1996/02/13 18:47:50 Hans_Graves
  163. * Fix some Seek related bugs
  164. * [1996/02/13 18:40:40 Hans_Graves]
  165. *
  166. * Revision 1.1.2.8 1996/02/07 23:23:57 Hans_Graves
  167. * Added SEEK_EXACT. Fixed most frame counting problems.
  168. * [1996/02/07 23:20:34 Hans_Graves]
  169. *
  170. * Revision 1.1.2.7 1996/02/06 22:54:07 Hans_Graves
  171. * Seek fix-ups. More accurate MPEG frame counts.
  172. * [1996/02/06 22:45:02 Hans_Graves]
  173. *
  174. * Revision 1.1.2.6 1996/01/30 22:23:09 Hans_Graves
  175. * Added AVI YUV support
  176. * [1996/01/30 22:21:41 Hans_Graves]
  177. *
  178. * Revision 1.1.2.5 1996/01/15 16:26:31 Hans_Graves
  179. * Reorganized Parsing, Added Wave file support
  180. * [1996/01/15 15:46:56 Hans_Graves]
  181. *
  182. * Revision 1.1.2.4 1996/01/11 16:17:32 Hans_Graves
  183. * Added MPEG II Systems decode support
  184. * [1996/01/11 16:12:38 Hans_Graves]
  185. *
  186. * Revision 1.1.2.3 1996/01/08 16:41:34 Hans_Graves
  187. * Added MPEG II decoding support
  188. * [1996/01/08 15:53:07 Hans_Graves]
  189. *
  190. * Revision 1.1.2.2 1995/12/08 20:01:23 Hans_Graves
  191. * Creation. Split off from slib_api.c
  192. * [1995/12/08 19:57:18 Hans_Graves]
  193. *
  194. * $EndLog$
  195. */
  196. /*****************************************************************************
  197. ** Copyright (c) Digital Equipment Corporation, 1995 **
  198. ** **
  199. ** All Rights Reserved. Unpublished rights reserved under the copyright **
  200. ** laws of the United States. **
  201. ** **
  202. ** The software contained on this media is proprietary to and embodies **
  203. ** the confidential technology of Digital Equipment Corporation. **
  204. ** Possession, use, duplication or dissemination of the software and **
  205. ** media is authorized only pursuant to a valid written license from **
  206. ** Digital Equipment Corporation. **
  207. ** **
  208. ** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
  209. ** Government is subject to restrictions as set forth in Subparagraph **
  210. ** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
  211. ******************************************************************************/
  212. /*
  213. #define _SLIBDEBUG_
  214. */
  215. #ifdef WIN32
  216. #include <io.h>
  217. #endif
  218. #include <stdio.h>
  219. #ifdef _SHM_
  220. #include <sys/ipc.h> /* shared memory */
  221. #endif
  222. #define SLIB_INTERNAL
  223. #include "slib.h"
  224. #include "SC_err.h"
  225. #include "mpeg.h"
  226. #include "avi.h"
  227. #ifdef _SLIBDEBUG_
  228. #include "sc_debug.h"
  229. #define _DEBUG_ 0 /* detailed debuging statements: if >1 more detail */
  230. #define _VERBOSE_ 0 /* show progress */
  231. #define _VERIFY_ 1 /* verify correct operation */
  232. #define _WARN_ 1 /* warnings about strange behavior: 2=lower warnings */
  233. #define _MEMORY_ 0 /* memory debugging: if >1 more detail */
  234. #define _WRITE_ 0 /* data writing debugging */
  235. #define _TIMECODE_ 0 /* timecode/timestamp debugging */
  236. #define _PARSE_ 0 /* parsing debugging */
  237. #endif
  238. /************************** Memory Allocation ***********************/
  239. typedef struct slibMemory_s {
  240. unsigned char *address;
  241. long shmid;
  242. unsigned dword size;
  243. int count;
  244. ScBoolean_t user;
  245. SlibInfo_t *sinfo;
  246. void *uinfo; /* userdata */
  247. struct slibMemory_s *next;
  248. } slibMemory_t;
  249. static slibMemory_t *_slibMemoryList = NULL;
  250. static slibMemory_t *_slibMemoryListTail = NULL;
  251. static dword _slibMemoryCount = 0;
  252. static unsigned qword _slibMemoryUsed = 0L;
  253. #ifdef WIN32
  254. static HANDLE _slibMemoryMutex = NULL;
  255. #define slibInitMemoryMutex() if (_slibMemoryMutex==NULL) \
  256. _slibMemoryMutex=CreateMutex(NULL, FALSE, NULL)
  257. #define slibFreeMemoryMutex() if (_slibMemoryMutex!=NULL) \
  258. CloseHandle(_slibMemoryMutex); _slibMemoryMutex=NULL
  259. #define slibEnterMemorySection() WaitForSingleObject(_slibMemoryMutex, 5000);
  260. #define slibExitMemorySection() ReleaseMutex(_slibMemoryMutex)
  261. #else
  262. #define slibInitMemoryMutex()
  263. #define slibFreeMemoryMutex()
  264. #define slibEnterMemorySection()
  265. #define slibExitMemorySection()
  266. #endif
  267. void slibDumpMemory()
  268. {
  269. if (_slibMemoryList)
  270. {
  271. slibMemory_t *tmpmem = _slibMemoryList;
  272. while (tmpmem)
  273. {
  274. printf("address: %p size: %d count: %d user: %s\n",
  275. tmpmem->address, tmpmem->size, tmpmem->count,
  276. tmpmem->user ? "TRUE" : "FALSE");
  277. tmpmem = tmpmem->next;
  278. }
  279. }
  280. else
  281. printf("No memory allocated\n");
  282. }
  283. unsigned qword SlibMemUsed()
  284. {
  285. return(_slibMemoryUsed);
  286. }
  287. void *SlibAllocBuffer(unsigned dword bytes)
  288. {
  289. unsigned char *address;
  290. _SlibDebug(_MEMORY_,
  291. printf("SlibAllocBuffer(%d) MemoryCount=%d Used=%d\n",
  292. bytes, _slibMemoryCount, _slibMemoryUsed));
  293. if (bytes<=0)
  294. return(NULL);
  295. address=ScAlloc(bytes);
  296. if (address)
  297. {
  298. slibMemory_t *tmpmem = ScAlloc(sizeof(slibMemory_t));
  299. if (!tmpmem)
  300. {
  301. ScFree(address);
  302. return(NULL);
  303. }
  304. tmpmem->address = address;
  305. tmpmem->shmid = -1;
  306. tmpmem->size = bytes;
  307. tmpmem->count = 1;
  308. tmpmem->user = FALSE;
  309. tmpmem->sinfo = NULL;
  310. tmpmem->uinfo = NULL;
  311. slibInitMemoryMutex();
  312. slibEnterMemorySection();
  313. tmpmem->next = _slibMemoryList;
  314. if (_slibMemoryList == NULL)
  315. _slibMemoryListTail = tmpmem;
  316. _slibMemoryList = tmpmem;
  317. _slibMemoryCount++;
  318. _slibMemoryUsed+=bytes;
  319. slibExitMemorySection();
  320. }
  321. _SlibDebug(_WARN_ && address==NULL,
  322. printf("SlibAllocBuffer() couldn't alloc\n") );
  323. return(address);
  324. }
  325. /*
  326. ** Name: SlibAllocBufferEx
  327. ** Desc: Allocate a buffer that is associated with a specific handle
  328. */
  329. void *SlibAllocBufferEx(SlibHandle_t handle, unsigned dword bytes)
  330. {
  331. unsigned char *address;
  332. _SlibDebug(_MEMORY_,
  333. printf("SlibAllocBufferEx(%p, bytes=%d) MemoryCount=%d Used=%d\n",
  334. handle, bytes, _slibMemoryCount, _slibMemoryUsed));
  335. if (bytes<=0)
  336. return(NULL);
  337. address=ScAlloc(bytes);
  338. if (address)
  339. {
  340. slibMemory_t *tmpmem = ScAlloc(sizeof(slibMemory_t));
  341. if (!tmpmem)
  342. {
  343. ScFree(address);
  344. return(NULL);
  345. }
  346. tmpmem->address = address;
  347. tmpmem->shmid = -1;
  348. tmpmem->size = bytes;
  349. tmpmem->count = 1;
  350. tmpmem->user = FALSE;
  351. tmpmem->sinfo = handle;
  352. tmpmem->uinfo = NULL;
  353. slibInitMemoryMutex();
  354. slibEnterMemorySection();
  355. tmpmem->next = _slibMemoryList;
  356. if (_slibMemoryList == NULL)
  357. _slibMemoryListTail = tmpmem;
  358. _slibMemoryList = tmpmem;
  359. _slibMemoryCount++;
  360. _slibMemoryUsed+=bytes;
  361. slibExitMemorySection();
  362. }
  363. _SlibDebug(_WARN_ && address==NULL,
  364. printf("SlibAllocBufferEx() couldn't alloc\n") );
  365. return(address);
  366. }
  367. void *SlibAllocSharedBuffer(unsigned dword bytes, int *shmid)
  368. {
  369. unsigned char *address;
  370. long id;
  371. _SlibDebug(_MEMORY_, printf("SlibAllocSharedBuffer(%d)\n", bytes) );
  372. if (bytes<=0)
  373. return(NULL);
  374. #ifdef _SHM_
  375. id = shmget(IPC_PRIVATE, bytes, IPC_CREAT|0777);
  376. if (id < 0)
  377. return(NULL);
  378. address = (unsigned char *)shmat(id, 0, 0);
  379. if (address == ((caddr_t) -1))
  380. return(NULL);
  381. #else
  382. address=(unsigned char *)ScPaMalloc(bytes);
  383. id=0;
  384. #endif
  385. if (address)
  386. {
  387. slibMemory_t *tmpmem = ScAlloc(sizeof(slibMemory_t));
  388. _SlibDebug((_MEMORY_||_WARN_) && (((unsigned dword)address)&0x03),
  389. printf("SlibAllocSharedBuffer(%d) Unaligned address=%p shmid=%d\n",
  390. bytes, address, id) );
  391. if (!tmpmem)
  392. {
  393. #ifdef _SHM_
  394. shmdt (address);
  395. shmctl(id, IPC_RMID, 0);
  396. #else
  397. ScPaFree(address);
  398. #endif
  399. return(NULL);
  400. }
  401. tmpmem->address = address;
  402. tmpmem->shmid = id;
  403. _SlibDebug(_MEMORY_ && id>=0,
  404. printf("SlibAllocSharedBuffer(%d) address=%p shmid=%d\n",
  405. bytes, address, id) );
  406. tmpmem->size = bytes;
  407. tmpmem->count = 1;
  408. tmpmem->user = FALSE;
  409. tmpmem->sinfo = NULL;
  410. tmpmem->uinfo = NULL;
  411. slibInitMemoryMutex();
  412. slibEnterMemorySection();
  413. tmpmem->next = _slibMemoryList;
  414. if (_slibMemoryList == NULL)
  415. _slibMemoryListTail = tmpmem;
  416. _slibMemoryList = tmpmem;
  417. _slibMemoryCount++;
  418. _slibMemoryUsed+=bytes;
  419. slibExitMemorySection();
  420. if (shmid)
  421. *shmid = id;
  422. }
  423. return(address);
  424. }
  425. dword SlibGetSharedBufferID(void *address)
  426. {
  427. dword shmid=-1;
  428. _SlibDebug(_MEMORY_,
  429. printf("SlibGetSharedBufferID(%p) _slibMemoryCount=%d\n",
  430. address, _slibMemoryCount));
  431. slibEnterMemorySection();
  432. if (_slibMemoryList)
  433. {
  434. slibMemory_t *tmpmem = _slibMemoryList;
  435. while (tmpmem)
  436. {
  437. if ((unsigned char *)address>=tmpmem->address &&
  438. (unsigned char *)address<tmpmem->address+tmpmem->size)
  439. {
  440. shmid=tmpmem->shmid;
  441. break;
  442. }
  443. tmpmem = tmpmem->next;
  444. }
  445. }
  446. slibExitMemorySection();
  447. return(shmid);
  448. }
  449. /*
  450. ** Name: SlibValidBuffer
  451. ** Desc: Check if an address is in a SLIB allocated buffer.
  452. */
  453. SlibBoolean_t SlibValidBuffer(void *address)
  454. {
  455. SlibBoolean_t isvalid=FALSE;
  456. _SlibDebug(_MEMORY_,
  457. printf("SlibValidBuffer(%p) _slibMemoryCount=%d\n",
  458. address, _slibMemoryCount));
  459. slibEnterMemorySection();
  460. if (_slibMemoryList)
  461. {
  462. slibMemory_t *tmpmem = _slibMemoryList;
  463. while (tmpmem)
  464. {
  465. if ((unsigned char *)address>=tmpmem->address &&
  466. (unsigned char *)address<tmpmem->address+tmpmem->size)
  467. {
  468. isvalid=TRUE;
  469. break;
  470. }
  471. tmpmem = tmpmem->next;
  472. }
  473. }
  474. slibExitMemorySection();
  475. return(isvalid);
  476. }
  477. SlibStatus_t SlibFreeBuffer(void *address)
  478. {
  479. _SlibDebug(_MEMORY_>1,
  480. printf("SlibFreeBuffer(%p) MemoryCount=%d Used=%d\n",
  481. address, _slibMemoryCount, _slibMemoryUsed));
  482. slibEnterMemorySection();
  483. if (_slibMemoryList)
  484. {
  485. slibMemory_t *tmpmem = _slibMemoryList;
  486. slibMemory_t *lastmem = NULL;
  487. while (tmpmem)
  488. {
  489. if ((unsigned char *)address>=tmpmem->address &&
  490. (unsigned char *)address<tmpmem->address+tmpmem->size)
  491. {
  492. if (--tmpmem->count>0) /* memory was allocated more than once */
  493. {
  494. slibExitMemorySection();
  495. return(SlibErrorNone);
  496. }
  497. _SlibDebug(_MEMORY_,
  498. printf("SlibFreeBuffer(%p) final free: shmid=%d size=%d\n",
  499. tmpmem->address, tmpmem->shmid, tmpmem->size) );
  500. /* remove memory from mem list */
  501. if (tmpmem == _slibMemoryList)
  502. _slibMemoryList = tmpmem->next;
  503. else
  504. lastmem->next = tmpmem->next;
  505. if (tmpmem == _slibMemoryListTail)
  506. _slibMemoryListTail = lastmem;
  507. /* now actually free the memory */
  508. if (tmpmem->user)
  509. {
  510. if (tmpmem->sinfo && tmpmem->sinfo->SlibCB)
  511. {
  512. slibExitMemorySection();
  513. _SlibDebug(_VERBOSE_,
  514. printf("SlibFreeBuffer() SlibCB(SLIB_MSG_BUFDONE, %p, %d)\n",
  515. tmpmem->address, tmpmem->size) );
  516. tmpmem->user=FALSE;
  517. (*(tmpmem->sinfo->SlibCB))((SlibHandle_t)tmpmem->sinfo,
  518. SLIB_MSG_BUFDONE, (SlibCBParam1_t)tmpmem->address,
  519. (SlibCBParam2_t)tmpmem->size,
  520. tmpmem->uinfo?tmpmem->uinfo
  521. :(void *)tmpmem->sinfo->SlibCBUserData);
  522. slibEnterMemorySection();
  523. }
  524. }
  525. else if (tmpmem->shmid < 0)
  526. {
  527. _SlibDebug(_MEMORY_, printf("SlibFreeBuffer() ScFree(%p) %d bytes\n",
  528. tmpmem->address, tmpmem->size) );
  529. ScFree(tmpmem->address);
  530. }
  531. else /* shared memory */
  532. #ifdef _SHM_
  533. {
  534. _SlibDebug(_MEMORY_, printf("SlibFreeBuffer() shmdt(%p) %d bytes\n",
  535. tmpmem->address, tmpmem->size) );
  536. shmdt (tmpmem->address);
  537. shmctl(tmpmem->shmid, IPC_RMID, 0);
  538. }
  539. #else
  540. {
  541. _SlibDebug(_MEMORY_,
  542. printf("SlibFreeBuffer() ScPaFree(%p) %d bytes\n",
  543. tmpmem->address, tmpmem->size) );
  544. ScPaFree(tmpmem->address);
  545. }
  546. #endif
  547. _slibMemoryCount--;
  548. _slibMemoryUsed-=tmpmem->size;
  549. ScFree(tmpmem);
  550. slibExitMemorySection();
  551. if (_slibMemoryList==NULL) /* last memory in list was freed */
  552. {
  553. slibFreeMemoryMutex();
  554. }
  555. return(SlibErrorNone);
  556. }
  557. lastmem = tmpmem;
  558. _SlibDebug(_VERIFY_ && (tmpmem == tmpmem->next),
  559. printf("SlibFreeBuffer() tmpmem == tmpmem->next\n");
  560. return(SlibErrorMemory) );
  561. _SlibDebug(_VERIFY_ && (tmpmem->next==_slibMemoryList),
  562. printf("SlibFreeBuffer() tmpmem->next == _slibMemoryList\n");
  563. return(SlibErrorMemory) );
  564. tmpmem = tmpmem->next;
  565. }
  566. }
  567. _SlibDebug(_WARN_, printf("SlibFreeBuffer(%p) couldn't free\n",address) );
  568. slibExitMemorySection();
  569. return(SlibErrorBadArgument);
  570. }
  571. /*
  572. ** Name: SlibFreeBuffers
  573. ** Purpose: Free all buffers associated with a handle.
  574. ** If handle==NULL free all memory.
  575. */
  576. SlibStatus_t SlibFreeBuffers(SlibHandle_t handle)
  577. {
  578. _SlibDebug(_MEMORY_>1,
  579. printf("SlibFreeBuffers() MemoryCount=%d Used=%d\n",
  580. _slibMemoryCount, _slibMemoryUsed));
  581. slibEnterMemorySection();
  582. if (_slibMemoryList)
  583. {
  584. slibMemory_t *tmpmem = _slibMemoryList;
  585. slibMemory_t *lastmem = NULL, *nextmem=NULL;
  586. while (tmpmem)
  587. {
  588. nextmem = tmpmem->next;
  589. if (handle==NULL || tmpmem->sinfo==handle)
  590. {
  591. _SlibDebug(_MEMORY_,
  592. printf("SlibFreeBuffer(%p) final free: shmid=%d size=%d\n",
  593. tmpmem->address, tmpmem->shmid, tmpmem->size) );
  594. /* remove memory from mem list */
  595. if (tmpmem == _slibMemoryList)
  596. _slibMemoryList = tmpmem->next;
  597. else
  598. lastmem->next = tmpmem->next;
  599. if (tmpmem == _slibMemoryListTail)
  600. _slibMemoryListTail = lastmem;
  601. /* now actually free the memory */
  602. if (tmpmem->user)
  603. {
  604. if (tmpmem->sinfo && tmpmem->sinfo->SlibCB)
  605. {
  606. slibExitMemorySection();
  607. _SlibDebug(_VERBOSE_,
  608. printf("SlibFreeBuffer() SlibCB(SLIB_MSG_BUFDONE, %p, %d)\n",
  609. tmpmem->address, tmpmem->size) );
  610. tmpmem->user=FALSE;
  611. (*(tmpmem->sinfo->SlibCB))((SlibHandle_t)tmpmem->sinfo,
  612. SLIB_MSG_BUFDONE, (SlibCBParam1_t)tmpmem->address,
  613. (SlibCBParam2_t)tmpmem->size,
  614. tmpmem->uinfo?tmpmem->uinfo
  615. :(void *)tmpmem->sinfo->SlibCBUserData);
  616. slibEnterMemorySection();
  617. }
  618. }
  619. else if (tmpmem->shmid < 0)
  620. {
  621. _SlibDebug(_MEMORY_, printf("SlibFreeBuffer() ScFree(%p) %d bytes\n",
  622. tmpmem->address, tmpmem->size) );
  623. ScFree(tmpmem->address);
  624. }
  625. else /* shared memory */
  626. #ifdef _SHM_
  627. {
  628. _SlibDebug(_MEMORY_, printf("SlibFreeBuffer() shmdt(%p) %d bytes\n",
  629. tmpmem->address, tmpmem->size) );
  630. shmdt (tmpmem->address);
  631. shmctl(tmpmem->shmid, IPC_RMID, 0);
  632. }
  633. #else
  634. {
  635. _SlibDebug(_MEMORY_,
  636. printf("SlibFreeBuffer() ScPaFree(%p) %d bytes\n",
  637. tmpmem->address, tmpmem->size) );
  638. ScPaFree(tmpmem->address);
  639. }
  640. #endif
  641. _slibMemoryCount--;
  642. _slibMemoryUsed-=tmpmem->size;
  643. ScFree(tmpmem);
  644. if (_slibMemoryList==NULL) /* last memory in list was freed */
  645. {
  646. slibExitMemorySection();
  647. slibFreeMemoryMutex();
  648. return(SlibErrorNone);
  649. }
  650. }
  651. lastmem = tmpmem;
  652. _SlibDebug(_VERIFY_ && (tmpmem == nextmem),
  653. printf("SlibFreeBuffer() tmpmem == tmpmem->next\n");
  654. return(SlibErrorMemory) );
  655. _SlibDebug(_VERIFY_ && (nextmem==_slibMemoryList),
  656. printf("SlibFreeBuffer() tmpmem->next == _slibMemoryList\n");
  657. return(SlibErrorMemory) );
  658. tmpmem = nextmem;
  659. }
  660. }
  661. slibExitMemorySection();
  662. return(SlibErrorNone);
  663. }
  664. /*
  665. ** Name: SlibAllocSubBuffer
  666. ** Purpose: Allocate a subsection of a buffer.
  667. */
  668. SlibStatus_t SlibAllocSubBuffer(void *address, unsigned dword bytes)
  669. {
  670. _SlibDebug(_MEMORY_>1, printf("SlibAllocSubBuffer() _slibMemoryCount=%d\n",
  671. _slibMemoryCount) );
  672. slibEnterMemorySection();
  673. if (_slibMemoryList)
  674. {
  675. slibMemory_t *tmpmem = _slibMemoryList;
  676. while (tmpmem)
  677. {
  678. if ((unsigned char *)address>=tmpmem->address &&
  679. (unsigned char *)address<tmpmem->address+tmpmem->size)
  680. {
  681. if ((char *)address+bytes>tmpmem->address+tmpmem->size)
  682. {
  683. _SlibDebug(_VERIFY_,
  684. printf("SlibAllocSubBuffer(bytes=%d) out of range by %d bytes\n",
  685. bytes,(unsigned long)(tmpmem->address+tmpmem->size)
  686. -(unsigned long)((char *)address+bytes)) );
  687. slibExitMemorySection();
  688. return(SlibErrorMemory);
  689. }
  690. tmpmem->count++;
  691. slibExitMemorySection();
  692. return(SlibErrorNone);
  693. }
  694. _SlibDebug(_VERIFY_ && (tmpmem == tmpmem->next),
  695. printf("SlibAllocSubBuffer() tmpmem == tmpmem->next\n");
  696. return(SlibErrorMemory) );
  697. _SlibDebug(_VERIFY_ && (tmpmem->next==_slibMemoryList),
  698. printf("SlibAllocSubBuffer() tmpmem->next == _slibMemoryList\n");
  699. return(SlibErrorMemory) );
  700. tmpmem = tmpmem->next;
  701. }
  702. }
  703. _SlibDebug(_WARN_ && address==NULL,
  704. printf("SlibAllocSubBuffer() couldn't alloc\n") );
  705. slibExitMemorySection();
  706. return(SlibErrorBadArgument);
  707. }
  708. /*
  709. ** Name: SlibManageUserBuffer
  710. ** Purpose: Add a user's buffer to the memory queue, in order to keep
  711. ** track of it.
  712. */
  713. SlibStatus_t slibManageUserBuffer(SlibInfo_t *Info, void *address,
  714. unsigned dword bytes, void *userdata)
  715. {
  716. _SlibDebug(_MEMORY_, printf("slibManageUserBuffer() _slibMemoryCount=%d\n",
  717. _slibMemoryCount) );
  718. slibEnterMemorySection();
  719. if (_slibMemoryList)
  720. {
  721. slibMemory_t *tmpmem = _slibMemoryList;
  722. while (tmpmem)
  723. {
  724. if ((unsigned char *)address>=tmpmem->address &&
  725. (unsigned char *)address<tmpmem->address+tmpmem->size)
  726. {
  727. if ((char *)address+bytes>tmpmem->address+tmpmem->size)
  728. {
  729. _SlibDebug(_VERIFY_,
  730. printf("SlibAllocSubBuffer(bytes=%d) out of range by %d bytes\n",
  731. bytes,(unsigned long)(tmpmem->address+tmpmem->size)
  732. -(unsigned long)((char *)address+bytes)) );
  733. slibExitMemorySection();
  734. return(SlibErrorMemory);
  735. }
  736. if (tmpmem->user == TRUE) /* already a user buffer */
  737. tmpmem->count++;
  738. else
  739. tmpmem->user = TRUE;
  740. if (Info)
  741. tmpmem->sinfo=Info;
  742. if (userdata)
  743. tmpmem->uinfo = userdata;
  744. _SlibDebug(_MEMORY_,
  745. printf("slibManageUserBuffer() Allocated by SLIB: %p\n",
  746. address) );
  747. slibExitMemorySection();
  748. return(SlibErrorNone);
  749. }
  750. tmpmem = tmpmem->next;
  751. }
  752. }
  753. if (address)
  754. {
  755. slibMemory_t *tmpmem = ScAlloc(sizeof(slibMemory_t));
  756. if (!tmpmem)
  757. return(SlibErrorMemory);
  758. tmpmem->address = address;
  759. tmpmem->shmid = -1;
  760. tmpmem->size = bytes;
  761. tmpmem->count = 1; /* was not allocated by SLIB */
  762. tmpmem->user = TRUE;
  763. tmpmem->sinfo = Info;
  764. tmpmem->uinfo = userdata;
  765. tmpmem->next = _slibMemoryList;
  766. if (_slibMemoryList == NULL)
  767. _slibMemoryListTail = tmpmem;
  768. _slibMemoryList = tmpmem;
  769. _slibMemoryCount++;
  770. _slibMemoryUsed+=bytes;
  771. _SlibDebug(_MEMORY_,
  772. printf("slibManageUserBuffer() New memory entry\n") );
  773. slibExitMemorySection();
  774. return(SlibErrorNone);
  775. }
  776. slibExitMemorySection();
  777. return(SlibErrorBadArgument);
  778. }
  779. /************************** Internal Buffer Stuff ***********************/
  780. #define _getbyte(var) \
  781. if (top==bot) { \
  782. var = *buf++; \
  783. if (--bufsize==0) { \
  784. if (discard) { \
  785. SlibFreeBuffer(bufstart); \
  786. buf=bufstart=slibGetBufferFromPin(Info, pin, &bufsize, NULL); \
  787. } \
  788. else \
  789. buf=slibPeekNextBufferOnPin(Info, pin, buf-1, &bufsize, NULL); \
  790. if (!buf) return(NULL); \
  791. } \
  792. } else var=sbyte[top++];
  793. #define _storebyte(val) if (top==bot) {top=0; bot=1; sbyte[0]=val; } \
  794. else sbyte[bot++]=val;
  795. unsigned char *slibSearchBuffersOnPin(SlibInfo_t *Info, SlibPin_t *pin,
  796. unsigned char *lastbuf, unsigned dword *size,
  797. unsigned dword code, int codebytes,
  798. ScBoolean_t discard)
  799. {
  800. unsigned char *buf, *bufstart;
  801. unsigned char abyte, byte0, byte1, byte2, byte3, sbyte[16];
  802. int bot, top;
  803. unsigned dword bufsize;
  804. _SlibDebug(_DEBUG_>1,
  805. printf("slibSearchBuffersOnPin(%s, code=0x%08lX, codebytes=%d)\n",
  806. pin->name, code, codebytes) );
  807. if (!Info || !pin)
  808. return(NULL);
  809. for (top=codebytes-1; top>=0; top--)
  810. {
  811. sbyte[top]=code & 0xFF;
  812. code>>=8;
  813. }
  814. byte0=sbyte[0];
  815. byte1=sbyte[1];
  816. byte2=sbyte[2];
  817. byte3=sbyte[3];
  818. top=bot=0;
  819. if (lastbuf)
  820. {
  821. buf=bufstart=lastbuf;
  822. bufsize=*size;
  823. }
  824. else if (discard)
  825. {
  826. buf=bufstart=slibGetBufferFromPin(Info, pin, &bufsize, NULL);
  827. }
  828. else
  829. buf=slibPeekBufferOnPin(Info, pin, &bufsize, NULL);
  830. if (!buf || codebytes<=0 || !bufsize)
  831. {
  832. _SlibDebug(_WARN_ && buf==lastbuf,
  833. printf("slibSearchBuffersOnPin(%s) no search made\n",pin->name) );
  834. return(buf);
  835. }
  836. /*
  837. ScDumpChar(buf,bufsize,0);
  838. */
  839. while (buf)
  840. {
  841. /*
  842. printf("level=0 top=%d bot=%d\n", top, bot);
  843. printf("buf=%p abyte=%d\n",buf, abyte);
  844. */
  845. _getbyte(abyte);
  846. if (abyte == byte0)
  847. {
  848. if (codebytes==1)
  849. {
  850. if (discard)
  851. { SlibAllocSubBuffer(buf, bufsize); SlibFreeBuffer(bufstart); }
  852. *size=bufsize;
  853. return(buf);
  854. }
  855. _getbyte(abyte);
  856. if (abyte == byte1)
  857. {
  858. if (codebytes==2)
  859. {
  860. if (discard)
  861. { SlibAllocSubBuffer(buf, bufsize); SlibFreeBuffer(bufstart); }
  862. *size=bufsize;
  863. return(buf);
  864. }
  865. _getbyte(abyte);
  866. if (abyte == byte2)
  867. {
  868. if (codebytes==3)
  869. {
  870. if (discard)
  871. { SlibAllocSubBuffer(buf, bufsize); SlibFreeBuffer(bufstart); }
  872. *size=bufsize;
  873. return(buf);
  874. }
  875. _getbyte(abyte);
  876. if (abyte == byte3)
  877. {
  878. if (codebytes==4)
  879. {
  880. if (discard)
  881. { SlibAllocSubBuffer(buf, bufsize); SlibFreeBuffer(bufstart); }
  882. *size=bufsize;
  883. return(buf);
  884. }
  885. }
  886. else
  887. {
  888. _storebyte(byte1);
  889. _storebyte(byte2);
  890. _storebyte(abyte);
  891. }
  892. }
  893. else
  894. {
  895. _storebyte(byte1);
  896. _storebyte(abyte);
  897. }
  898. }
  899. else
  900. _storebyte(abyte);
  901. }
  902. }
  903. _SlibDebug(_DEBUG_, printf("slibSearchBuffersOnPin() Not found\n") );
  904. return(NULL);
  905. }
  906. #define _getbyte2(var) \
  907. if (top==bot) { \
  908. var = *buf++; totallen++; \
  909. if (--bufsize==0) { \
  910. buf=slibPeekNextBufferOnPin(Info, pin, buf-1, &bufsize, NULL); \
  911. if (!buf) { \
  912. _SlibDebug(_VERBOSE_,printf("slibCountCodesOnPin() out (EOI)\n")); \
  913. return(count); } \
  914. } \
  915. } else var=sbyte[top++];
  916. /*
  917. ** Name: slibCountCodesOnPin
  918. ** Description: Count the occurrances of a particular code in a Pin's
  919. ** data stream.
  920. ** maxlen: 0 counts till end of data
  921. ** -1 counts buffers already loaded on pin
  922. */
  923. dword slibCountCodesOnPin(SlibInfo_t *Info, SlibPin_t *pin,
  924. unsigned dword code, int codebytes,
  925. unsigned dword maxlen)
  926. {
  927. unsigned char *buf;
  928. unsigned char abyte, byte0, byte1, byte2, byte3, sbyte[16];
  929. int bot, top, count=0;
  930. unsigned dword bufsize;
  931. unsigned long totallen=0;
  932. _SlibDebug((_DEBUG_||_WARN_) && (!pin || !pin->name),
  933. printf("slibCountCodesOnPin() bad pin\n") );
  934. if (!Info || !pin)
  935. return(count);
  936. _SlibDebug(_DEBUG_||_VERBOSE_,
  937. printf("slibCountCodesOnPin(%s) in\n", pin->name) );
  938. for (top=codebytes-1; top>=0; top--)
  939. {
  940. sbyte[top]=code & 0xFF;
  941. code>>=8;
  942. }
  943. byte0=sbyte[0];
  944. byte1=sbyte[1];
  945. byte2=sbyte[2];
  946. byte3=sbyte[3];
  947. top=bot=0;
  948. buf=slibPeekBufferOnPin(Info, pin, &bufsize, NULL);
  949. if (!buf || codebytes<=0)
  950. return(count);
  951. while (buf && (maxlen<=0 || totallen<maxlen))
  952. {
  953. _getbyte2(abyte);
  954. if (abyte == byte0)
  955. {
  956. if (codebytes==1)
  957. {
  958. count++;
  959. top=bot=0;
  960. continue;
  961. }
  962. _getbyte2(abyte);
  963. if (abyte == byte1)
  964. {
  965. if (codebytes==2)
  966. {
  967. count++;
  968. top=bot=0;
  969. continue;
  970. }
  971. _getbyte2(abyte);
  972. if (abyte == byte2)
  973. {
  974. if (codebytes==3)
  975. {
  976. count++;
  977. top=bot=0;
  978. continue;
  979. }
  980. _getbyte2(abyte);
  981. if (abyte == byte3)
  982. {
  983. if (codebytes==4)
  984. {
  985. count++;
  986. top=bot=0;
  987. continue;
  988. }
  989. }
  990. else
  991. {
  992. _storebyte(byte1);
  993. _storebyte(byte2);
  994. _storebyte(abyte);
  995. }
  996. }
  997. else
  998. {
  999. _storebyte(byte1);
  1000. _storebyte(abyte);
  1001. }
  1002. }
  1003. else
  1004. _storebyte(abyte);
  1005. }
  1006. }
  1007. _SlibDebug(_VERBOSE_, printf("slibCountCodesOnPin() out\n") );
  1008. return(count);
  1009. }
  1010. /*
  1011. ** Name: SlibGetBuffer
  1012. ** Purpose: Read the next buffer from the data source.
  1013. */
  1014. unsigned char *SlibGetBuffer(SlibInfo_t *Info, int pinid,
  1015. unsigned dword *psize, SlibTime_t *ptime)
  1016. {
  1017. unsigned char *address=NULL;
  1018. SlibPin_t *pin;
  1019. _SlibDebug(_DEBUG_>1, printf("SlibGetBuffer\n") );
  1020. if (!Info)
  1021. return(NULL);
  1022. if (!psize)
  1023. return(NULL);
  1024. pin=slibLoadPin(Info, pinid);
  1025. if (pin)
  1026. return(slibGetBufferFromPin(Info, pin, psize, ptime));
  1027. else
  1028. {
  1029. if (psize)
  1030. *psize=0;
  1031. if (ptime)
  1032. *ptime=SLIB_TIME_NONE;
  1033. _SlibDebug(_WARN_,
  1034. printf("SlibGetBuffer(pinid=%d) couldn't get\n",pinid) );
  1035. return(NULL);
  1036. }
  1037. }
  1038. /*
  1039. ** Name: SlibPeekBuffer
  1040. ** Purpose: Read the next buffer from the data source.
  1041. */
  1042. unsigned char *SlibPeekBuffer(SlibInfo_t *Info, int pinid,
  1043. unsigned dword *psize, SlibTime_t *ptime)
  1044. {
  1045. unsigned char *address=NULL;
  1046. SlibPin_t *pin;
  1047. _SlibDebug(_DEBUG_>1, printf("SlibPeekBuffer\n") );
  1048. if (!Info)
  1049. return(NULL);
  1050. pin=slibLoadPin(Info, pinid);
  1051. if (pin)
  1052. return(slibPeekBufferOnPin(Info, pin, psize, ptime));
  1053. else
  1054. {
  1055. if (psize)
  1056. *psize=0;
  1057. if (ptime)
  1058. *ptime=SLIB_TIME_NONE;
  1059. _SlibDebug(_WARN_,
  1060. printf("SlibPeekBuffer(pinid=%d) couldn't peek\n",pinid) );
  1061. return(NULL);
  1062. }
  1063. }
  1064. /************************** Pins ***********************/
  1065. SlibBoolean_t slibPinOverflowing(SlibInfo_t *Info, SlibPin_t *pin)
  1066. {
  1067. if (pin==NULL)
  1068. return(TRUE);
  1069. /*
  1070. _SlibDebug(_WARN_ && pin->DataSize>(Info->OverflowSize*2)/3,
  1071. printf("Data almost overflowing: %d bytes\n", pin->DataSize) );
  1072. */
  1073. return(pin->DataSize>(long)Info->OverflowSize ? TRUE : FALSE);
  1074. }
  1075. void slibRemovePins(SlibInfo_t *Info)
  1076. {
  1077. _SlibDebug(_VERBOSE_, printf("slibRemovePins()\n") );
  1078. while (Info->Pins)
  1079. slibRemovePin(Info, Info->Pins->ID);
  1080. }
  1081. void slibEmptyPins(SlibInfo_t *Info)
  1082. {
  1083. SlibPin_t *pin=Info->Pins;
  1084. _SlibDebug(_VERBOSE_, printf("slibEmptyPins()\n") );
  1085. while (pin)
  1086. {
  1087. slibEmptyPin(Info, pin->ID);
  1088. pin = pin->next;
  1089. }
  1090. }
  1091. SlibPin_t *slibGetPin(SlibInfo_t *Info, int pinid)
  1092. {
  1093. SlibPin_t *pin=Info->Pins;
  1094. while (pin)
  1095. {
  1096. if (pin->ID == pinid)
  1097. return(pin);
  1098. pin = pin->next;
  1099. }
  1100. return(NULL);
  1101. }
  1102. SlibPin_t *slibRenamePin(SlibInfo_t *Info, int oldpinid,
  1103. int newpinid, char *newname)
  1104. {
  1105. SlibPin_t *pin=Info->Pins;
  1106. pin=slibGetPin(Info, oldpinid);
  1107. if (pin==NULL) /* pin doesn't exist */
  1108. return(NULL);
  1109. /* if a pin with the new ID already exists, delete it */
  1110. slibRemovePin(Info, newpinid);
  1111. /* rename it */
  1112. pin->ID=newpinid;
  1113. if (newname)
  1114. strcpy(pin->name, newname);
  1115. return(pin);
  1116. }
  1117. SlibPin_t *slibAddPin(SlibInfo_t *Info, int pinid, char *name)
  1118. {
  1119. SlibPin_t *pin=Info->Pins, *newpin;
  1120. int i;
  1121. _SlibDebug(_DEBUG_||_VERBOSE_, printf("slibAddPin(%s)\n",name) );
  1122. while (pin)
  1123. {
  1124. if (pin->ID == pinid)
  1125. return(pin);
  1126. pin = pin->next;
  1127. }
  1128. if ((newpin = ScAlloc(sizeof(SlibPin_t)))==NULL)
  1129. return(NULL);
  1130. newpin->ID = pinid;
  1131. for (i=0; i<(sizeof(newpin->name)-1) && name && *name; i++)
  1132. newpin->name[i]=*name++;
  1133. newpin->name[i]=0;
  1134. newpin->next=Info->Pins;
  1135. newpin->Buffers=NULL;
  1136. newpin->BuffersTail=NULL;
  1137. newpin->BufferCount=0;
  1138. newpin->DataSize=0;
  1139. newpin->Offset=0;
  1140. Info->Pins = newpin;
  1141. Info->PinCount++;
  1142. return(newpin);
  1143. }
  1144. /*
  1145. ** Name: slibAddBufferToPin
  1146. ** Purpose: Add a buffer to data source buffer queue.
  1147. */
  1148. SlibStatus_t slibAddBufferToPin(SlibPin_t *pin,
  1149. void *buffer, unsigned dword size, SlibTime_t time)
  1150. {
  1151. SlibBuffer_t *newbuf;
  1152. _SlibDebug(_DEBUG_,
  1153. printf("slibAddBufferToPin(%s, %d)\n", pin->name, size) );
  1154. _SlibDebug(_WARN_ && size==0,
  1155. printf("slibAddBufferToPin(%s, %p, size=%d)\n", pin->name, buffer, size) );
  1156. if (!pin || !buffer || !size)
  1157. return(SlibErrorBadArgument);
  1158. if ((newbuf = ScAlloc(sizeof(SlibBuffer_t)))==NULL)
  1159. return(SlibErrorMemory);
  1160. newbuf->address = buffer;
  1161. newbuf->size = size;
  1162. if (pin->BuffersTail)
  1163. newbuf->offset = pin->BuffersTail->offset+pin->BuffersTail->size;
  1164. else
  1165. newbuf->offset = pin->Offset;
  1166. newbuf->time = time;
  1167. newbuf->next = NULL;
  1168. if (pin->BuffersTail==NULL)
  1169. pin->Buffers=newbuf;
  1170. else
  1171. pin->BuffersTail->next=newbuf;
  1172. pin->BuffersTail = newbuf;
  1173. pin->BufferCount++;
  1174. pin->DataSize+=newbuf->size;
  1175. return(SlibErrorNone);
  1176. }
  1177. /*
  1178. ** Name: slibInsertBufferOnPin
  1179. ** Purpose: Add a buffer at the head of a data source's buffer queue.
  1180. */
  1181. SlibStatus_t slibInsertBufferOnPin(SlibPin_t *pin, void *buffer,
  1182. unsigned dword size, SlibTime_t time)
  1183. {
  1184. SlibBuffer_t *newbuf;
  1185. _SlibDebug(_DEBUG_>1,
  1186. printf("slibInsertBufferOnPin(%s, size=%d)\n", pin->name, size) );
  1187. _SlibDebug((_WARN_ && !_DEBUG_) && size==0,
  1188. printf("slibInsertBufferOnPin(%s, size=%d)\n", pin->name, size) );
  1189. if (!pin || !buffer || !size)
  1190. return(SlibErrorBadArgument);
  1191. if ((newbuf = ScAlloc(sizeof(SlibBuffer_t)))==NULL)
  1192. return(SlibErrorMemory);
  1193. newbuf->address = buffer;
  1194. newbuf->size = size;
  1195. pin->Offset-=size;
  1196. newbuf->offset = pin->Offset;
  1197. newbuf->time = time;
  1198. newbuf->next = pin->Buffers;
  1199. pin->Buffers=newbuf;
  1200. if (pin->BuffersTail == NULL)
  1201. pin->BuffersTail = newbuf;
  1202. pin->BufferCount++;
  1203. pin->DataSize+=newbuf->size;
  1204. return(SlibErrorNone);
  1205. }
  1206. qword slibSkipDataOnPin(SlibInfo_t *Info, SlibPin_t *pin,
  1207. qword totalbytes)
  1208. {
  1209. qword skippedbytes=0;
  1210. _SlibDebug(_VERBOSE_ || 1, printf("slibSkipDataOnPin() in\n") );
  1211. if (pin && totalbytes>0)
  1212. {
  1213. qword startsize;
  1214. unsigned char *buf;
  1215. unsigned dword size;
  1216. SlibTime_t time, newtime;
  1217. startsize=pin->DataSize;
  1218. buf=slibGetBufferFromPin(Info, pin, &size, &time);
  1219. while (buf && skippedbytes+size<totalbytes)
  1220. {
  1221. skippedbytes+=size;
  1222. SlibFreeBuffer(buf);
  1223. buf=slibGetBufferFromPin(Info, pin, &size, &newtime);
  1224. if (newtime!=SLIB_TIME_NONE)
  1225. time=newtime;
  1226. }
  1227. if (buf && skippedbytes+size>=totalbytes)
  1228. {
  1229. size-=(unsigned dword)(totalbytes-skippedbytes);
  1230. if (size) /* put remainer of buffer back on pin */
  1231. {
  1232. SlibAllocSubBuffer(buf+totalbytes-skippedbytes, size);
  1233. slibInsertBufferOnPin(pin, buf+totalbytes-skippedbytes, size, time);
  1234. }
  1235. SlibFreeBuffer(buf);
  1236. skippedbytes=totalbytes;
  1237. }
  1238. _SlibDebug(_WARN_ && pin->DataSize+skippedbytes!=startsize,
  1239. printf("slibSkipDataOnPin() Skipped %d bytes, startsize=%d newsize=%d\n",
  1240. skippedbytes, startsize, pin->DataSize) );
  1241. }
  1242. _SlibDebug(_VERBOSE_ || 1, printf("slibSkipDataOnPin() out\n") );
  1243. return(skippedbytes);
  1244. }
  1245. unsigned dword slibFillBufferFromPin(SlibInfo_t *Info, SlibPin_t *pin,
  1246. unsigned char *fillbuf, unsigned dword bufsize,
  1247. SlibTime_t *ptime)
  1248. {
  1249. unsigned dword filledbytes=0;
  1250. if (pin && fillbuf)
  1251. {
  1252. unsigned char *buf;
  1253. unsigned dword size;
  1254. SlibTime_t time, nexttime=SLIB_TIME_NONE;
  1255. buf=slibGetBufferFromPin(Info, pin, &size, &time);
  1256. while (buf && size<bufsize)
  1257. {
  1258. memcpy(fillbuf, buf, size);
  1259. bufsize-=size;
  1260. filledbytes+=size;
  1261. fillbuf+=size;
  1262. SlibFreeBuffer(buf);
  1263. buf=slibGetBufferFromPin(Info, pin, &size, &nexttime);
  1264. if (time==SLIB_TIME_NONE)
  1265. time=nexttime;
  1266. }
  1267. if (buf && size>=bufsize)
  1268. {
  1269. memcpy(fillbuf, buf, bufsize);
  1270. size-=bufsize;
  1271. if (size) /* put remainer of buffer back on pin */
  1272. {
  1273. SlibAllocSubBuffer(buf+bufsize, size);
  1274. slibInsertBufferOnPin(pin, buf+bufsize, size, nexttime);
  1275. }
  1276. SlibFreeBuffer(buf);
  1277. filledbytes+=bufsize;
  1278. }
  1279. if (ptime)
  1280. *ptime=time;
  1281. }
  1282. return(filledbytes);
  1283. }
  1284. word slibGetWordFromPin(SlibInfo_t *Info, SlibPin_t *pin)
  1285. {
  1286. word value=0;
  1287. if (pin)
  1288. {
  1289. unsigned char *buf;
  1290. unsigned dword size;
  1291. SlibTime_t time;
  1292. buf=slibGetBufferFromPin(Info, pin, &size, &time);
  1293. if (buf && size>=sizeof(value))
  1294. {
  1295. value=((int)buf[3]<<24) | (int)buf[2]<<16 |
  1296. (int)buf[1]<<8 | (int)buf[0];
  1297. size-=sizeof(value);
  1298. if (size) /* put remainer of buffer back on pin */
  1299. {
  1300. SlibAllocSubBuffer(buf+sizeof(value), size);
  1301. slibInsertBufferOnPin(pin, buf+sizeof(value), size, time);
  1302. }
  1303. SlibFreeBuffer(buf);
  1304. }
  1305. }
  1306. return(value);
  1307. }
  1308. dword slibGetDWordFromPin(SlibInfo_t *Info, SlibPin_t *pin)
  1309. {
  1310. dword value=0;
  1311. if (pin)
  1312. {
  1313. unsigned char *buf;
  1314. unsigned dword size;
  1315. SlibTime_t time;
  1316. _SlibDebug(_VERBOSE_, printf("slibGetDWordFromPin(%s)\n", pin->name) );
  1317. buf=slibGetBufferFromPin(Info, pin, &size, &time);
  1318. if (buf && size>=sizeof(value))
  1319. {
  1320. value=((int)buf[3]<<24) | (int)buf[2]<<16 |
  1321. (int)buf[1]<<8 | (int)buf[0];
  1322. size-=sizeof(value);
  1323. if (size) /* put remainer of buffer back on pin */
  1324. {
  1325. SlibAllocSubBuffer(buf+sizeof(value), size);
  1326. slibInsertBufferOnPin(pin, buf+sizeof(value), size, time);
  1327. }
  1328. SlibFreeBuffer(buf);
  1329. }
  1330. }
  1331. return(value);
  1332. }
  1333. SlibStatus_t slibRemovePin(SlibInfo_t *Info, int pinid)
  1334. {
  1335. SlibPin_t *lastpin=NULL, *pin=Info->Pins;
  1336. SlibBuffer_t *lastbuf, *buf;
  1337. _SlibDebug(_VERBOSE_, printf("slibRemovePin(%d)\n", pinid) );
  1338. while (pin)
  1339. {
  1340. if (pin->ID == pinid)
  1341. {
  1342. if (lastpin)
  1343. lastpin->next = pin->next;
  1344. else
  1345. Info->Pins = pin->next;
  1346. buf=pin->Buffers;
  1347. while (buf)
  1348. {
  1349. if (buf->address)
  1350. SlibFreeBuffer(buf->address);
  1351. lastbuf=buf;
  1352. buf=lastbuf->next;
  1353. ScFree(lastbuf);
  1354. }
  1355. ScFree(pin);
  1356. Info->PinCount--;
  1357. return(TRUE);
  1358. }
  1359. lastpin = pin;
  1360. pin = pin->next;
  1361. }
  1362. return(FALSE);
  1363. }
  1364. SlibStatus_t slibEmptyPin(SlibInfo_t *Info, int pinid)
  1365. {
  1366. SlibPin_t *pin=Info->Pins;
  1367. SlibBuffer_t *lastbuf, *buf;
  1368. _SlibDebug(_DEBUG_ || _VERBOSE_, printf("slibEmptyPin(%d)\n",pinid) );
  1369. while (pin)
  1370. {
  1371. if (pin->ID == pinid)
  1372. {
  1373. buf=pin->Buffers;
  1374. while (buf)
  1375. {
  1376. pin->Offset+=buf->size;
  1377. if (buf->address)
  1378. if (SlibFreeBuffer(buf->address))
  1379. {
  1380. _SlibDebug(_WARN_,
  1381. printf("slibEmptyPin(%d) freeing buffer %p failed\n",
  1382. pinid, buf->address));
  1383. }
  1384. lastbuf=buf;
  1385. buf=buf->next;
  1386. ScFree(lastbuf);
  1387. }
  1388. pin->Buffers = NULL;
  1389. pin->BuffersTail = NULL;
  1390. pin->BufferCount = 0;
  1391. pin->DataSize = 0;
  1392. return(TRUE);
  1393. }
  1394. pin = pin->next;
  1395. }
  1396. _SlibDebug(_WARN_, printf("slibEmptyPin(%d) Unable to locate pin\n",pinid) );
  1397. return(FALSE);
  1398. }
  1399. SlibPin_t *slibLoadPin(SlibInfo_t *Info, int pinid)
  1400. {
  1401. SlibPin_t *pin;
  1402. _SlibDebug(_DEBUG_>1, printf("slibLoadPin(%d)\n",pinid) );
  1403. if ((pin=slibGetPin(Info, pinid))==NULL)
  1404. {
  1405. switch(pinid)
  1406. {
  1407. case SLIB_DATA_COMPRESSED: pin=slibAddPin(Info, pinid, "Input");
  1408. break;
  1409. case SLIB_DATA_VIDEO: pin=slibAddPin(Info, pinid, "Video");
  1410. break;
  1411. case SLIB_DATA_AUDIO: pin=slibAddPin(Info, pinid, "Audio");
  1412. break;
  1413. }
  1414. }
  1415. if (pin)
  1416. {
  1417. if (pin->Buffers)
  1418. return(pin);
  1419. else if (Info->Mode==SLIB_MODE_DECOMPRESS)
  1420. {
  1421. pin=slibPreLoadPin(Info, pin);
  1422. if (pin && pin->Buffers)
  1423. return(pin);
  1424. }
  1425. _SlibDebug(_WARN_,
  1426. if (Info->Mode!=SLIB_MODE_DECOMPRESS)
  1427. printf("slibLoadPin(%d) Mode is not SLIB_MODE_DECOMPRESS\n", pinid);
  1428. else
  1429. printf("slibLoadPin(%d) Unable to load pin\n", pinid));
  1430. return(NULL);
  1431. }
  1432. return(NULL);
  1433. }
  1434. qword slibDataOnPin(SlibInfo_t *Info, int pinid)
  1435. {
  1436. SlibPin_t *pin=slibGetPin(Info, pinid);
  1437. if (!pin || pin->Buffers==NULL)
  1438. return((qword)0);
  1439. else
  1440. return(pin->DataSize>0?pin->DataSize:(qword)1);
  1441. }
  1442. qword slibDataOnPins(SlibInfo_t *Info)
  1443. {
  1444. SlibPin_t *pin=Info->Pins;
  1445. qword totalbytes=(qword)0;
  1446. while (pin)
  1447. {
  1448. if (pin->DataSize>0)
  1449. totalbytes+=pin->DataSize;
  1450. pin = pin->next;
  1451. }
  1452. _SlibDebug(_VERBOSE_, printf("slibDataOnPins() returns %d\n", totalbytes) );
  1453. return(totalbytes);
  1454. }
  1455. /************************** Data Stream helper functions **************/
  1456. #ifdef MPEG_SUPPORT
  1457. #define PACKET_SIZE 0x8F0
  1458. #define PACKET_BUFFER_SIZE 0x8F0+50
  1459. #define BYTES_PER_PACK 0x1200
  1460. #define PTIME_ADJUST 300
  1461. #define AUDIOTIME_ADJUST 10
  1462. #endif
  1463. void slibValidateBitrates(SlibInfo_t *Info)
  1464. {
  1465. if (Info->Svh)
  1466. Info->VideoBitRate=(dword)SvGetParamInt(Info->Svh, SV_PARAM_BITRATE);
  1467. if (Info->Sah)
  1468. Info->AudioBitRate=(dword)SaGetParamInt(Info->Sah, SA_PARAM_BITRATE);
  1469. _SlibDebug(_VERBOSE_, printf("AudioBitRate=%d VideoBitRate=%d\n",
  1470. Info->AudioBitRate,Info->VideoBitRate) );
  1471. #ifdef MPEG_SUPPORT
  1472. if (Info->Type==SLIB_TYPE_MPEG_SYSTEMS ||
  1473. Info->Type==SLIB_TYPE_MPEG_SYSTEMS_MPEG2)
  1474. {
  1475. qword totalbitrate=Info->AudioBitRate+Info->VideoBitRate;
  1476. if (Info->Mode==SLIB_MODE_COMPRESS)
  1477. {
  1478. Info->KeySpacing=(int)SvGetParamInt(Info->Svh, SV_PARAM_KEYSPACING);
  1479. Info->SubKeySpacing=(int)SvGetParamInt(Info->Svh, SV_PARAM_SUBKEYSPACING);
  1480. }
  1481. totalbitrate+=(9*(totalbitrate/(PACKET_SIZE-3)))+ /* Packet headers */
  1482. (qword)(4*8*Info->FramesPerSec)+ /* Presentation timestamps */
  1483. (qword)(4*8*Info->FramesPerSec*10/ /* Decoding */
  1484. Info->SubKeySpacing); /* timestamps */
  1485. Info->MuxBitRate=(dword)(12*(totalbitrate/BYTES_PER_PACK));/*Pack Headers*/
  1486. }
  1487. #endif
  1488. Info->TotalBitRate=Info->AudioBitRate+Info->VideoBitRate+Info->MuxBitRate;
  1489. }
  1490. /************************** Data Stream Writers ***********************/
  1491. #ifdef MPEG_SUPPORT
  1492. static int slibCreateMpegPackHeader(unsigned char *buf,
  1493. unsigned qword sys_clock,
  1494. unsigned dword mux_rate)
  1495. {
  1496. buf[0]=0x00;
  1497. buf[1]=0x00;
  1498. buf[2]=0x01;
  1499. buf[3]=MPEG_PACK_START_BASE;
  1500. /* store system clock */
  1501. buf[4]=0x21|(unsigned char)(((sys_clock>>30)&0x07)<<1);
  1502. buf[5]=(unsigned char)(sys_clock>>22)&0xFF;
  1503. buf[6]=0x01|(unsigned char)((sys_clock>>14)&0xFE);
  1504. buf[7]=(unsigned char)((sys_clock>>7)&0xFF);
  1505. buf[8]=0x01|(unsigned char)((sys_clock<<1)&0xFE);
  1506. /* store mux rate */
  1507. buf[9]=0x80|(unsigned char)((mux_rate>>15)&0xEF);
  1508. buf[10]=(unsigned char)(mux_rate>>7)&0xFF;
  1509. buf[11]=0x01|(unsigned char)((mux_rate<<1)&0xFE);
  1510. return(12); /* bytes written */
  1511. }
  1512. /*
  1513. ** Function: slibWriteMpeg1Systems()
  1514. ** Descript: Writes out MPEG Video & Audio data conatined on Pins.
  1515. ** Returns: TRUE if data was written, otherwise FALSE.
  1516. */
  1517. static SlibBoolean_t slibWriteMpeg1Systems(SlibInfo_t *Info,
  1518. SlibBoolean_t flush)
  1519. {
  1520. SlibPin_t *audiopin, *videopin;
  1521. unsigned char *buf=NULL;
  1522. unsigned dword size=0, len;
  1523. unsigned char packet_data[PACKET_BUFFER_SIZE];
  1524. unsigned dword header_len;
  1525. SlibTime_t ptimestamp, dtimestamp, timediff=0;
  1526. SlibTime_t atime=SLIB_TIME_NONE, vtime=SLIB_TIME_NONE;
  1527. const unsigned dword std_audio_buf_size=Info->AudioBitRate ?
  1528. Info->AudioBitRate/8000 : 32;
  1529. const unsigned dword std_video_buf_size=Info->VideoBitRate ?
  1530. Info->VideoBitRate/25000 : 46;
  1531. int i;
  1532. _SlibDebug(_VERBOSE_||_WRITE_,
  1533. printf("slibWriteMpeg1Systems(flush=%d) BytesProcessed=%ld\n",
  1534. flush, Info->BytesProcessed) );
  1535. videopin = slibGetPin(Info, SLIB_DATA_VIDEO);
  1536. audiopin = slibGetPin(Info, SLIB_DATA_AUDIO);
  1537. if (!videopin && !audiopin)
  1538. return(FALSE);
  1539. if (!Info->HeaderProcessed || Info->BytesSincePack>=BYTES_PER_PACK)
  1540. {
  1541. /* mux_rate is in units of 50 bytes/s rounded up */
  1542. unsigned dword mux_rate=Info->TotalBitRate/(50*8)
  1543. + ((Info->TotalBitRate%(50*8))?1:0);
  1544. Info->SystemTimeStamp=(Info->BytesProcessed*8000)/Info->TotalBitRate;
  1545. _SlibDebug(_VERBOSE_ || _WRITE_,
  1546. printf(" TotalBitRate=%d sys_clock=%d (%d ms) BytesSincePack=%d\n",
  1547. Info->TotalBitRate, Info->SystemTimeStamp*90,
  1548. Info->SystemTimeStamp, Info->BytesSincePack) );
  1549. len=slibCreateMpegPackHeader(packet_data,
  1550. Info->SystemTimeStamp*90, /* 90 Khz clock */
  1551. mux_rate);
  1552. if (slibPutBuffer(Info, packet_data, len)==SlibErrorNone)
  1553. {
  1554. Info->BytesProcessed+=len;
  1555. Info->BytesSincePack+=len;
  1556. if (Info->BytesSincePack>=BYTES_PER_PACK)
  1557. Info->BytesSincePack-=BYTES_PER_PACK;
  1558. }
  1559. }
  1560. if (!Info->HeaderProcessed)
  1561. {
  1562. if (!Info->IOError)
  1563. {
  1564. /* mux_rate is in units of 50 bytes/s rounded up */
  1565. unsigned dword mux_rate=Info->TotalBitRate/(50*8)
  1566. + ((Info->TotalBitRate%(50*8))?1:0);
  1567. /******** systems header **********/
  1568. header_len=6+3*(Info->AudioStreams+Info->VideoStreams);
  1569. packet_data[0]=0x00;
  1570. packet_data[1]=0x00;
  1571. packet_data[2]=0x01;
  1572. packet_data[3]=(unsigned char)MPEG_SYSTEM_HEADER_START;
  1573. packet_data[4]=header_len>>8;
  1574. packet_data[5]=header_len & 0xFF;
  1575. packet_data[6]=0x80|((mux_rate>>15)&0xEF);
  1576. packet_data[7]=(mux_rate>>7)&0xFF;
  1577. packet_data[8]=0x01|((mux_rate<<1)&0xFE);
  1578. /* audio_bound(6 bits) + fixed_flag(1) + CSPS_falg(1) */
  1579. packet_data[9]=0x05;
  1580. /* sys_audio_lock_flag(1)+sys_video_lock_flag(1)+marker(1)+
  1581. video_bound(5 bits) */
  1582. packet_data[10]=0x80|0x40|0x20|0x01;
  1583. packet_data[11]=0xFF; /* reserved byte */
  1584. len=12;
  1585. for (i=0; i<Info->VideoStreams; i++)
  1586. {
  1587. packet_data[len++]=MPEG_VIDEO_STREAM_BASE+i;
  1588. packet_data[len++]=0xE0 | (std_video_buf_size>>8);
  1589. packet_data[len++]=std_video_buf_size & 0xFF;
  1590. }
  1591. for (i=0; i<Info->AudioStreams; i++)
  1592. {
  1593. packet_data[len++]=MPEG_AUDIO_STREAM_BASE+i;
  1594. packet_data[len++]=0xC0 | (std_audio_buf_size>>8);
  1595. packet_data[len++]=std_audio_buf_size & 0xFF;
  1596. }
  1597. _SlibDebug(_VERBOSE_ || _WRITE_,
  1598. printf("slibPutBuffer(%d) %d bytes of system header\n",
  1599. Info->Fd, len) );
  1600. if (slibPutBuffer(Info, packet_data, len)==SlibErrorNone)
  1601. {
  1602. Info->BytesProcessed+=len;
  1603. Info->BytesSincePack+=len;
  1604. }
  1605. }
  1606. Info->HeaderProcessed=TRUE;
  1607. }
  1608. atime=slibGetNextTimeOnPin(Info, audiopin, PACKET_SIZE-3);
  1609. vtime=slibGetNextTimeOnPin(Info, videopin, PACKET_SIZE-3);
  1610. if (SlibTimeIsInValid(atime))
  1611. atime=Info->LastAudioPTimeCode;
  1612. if (SlibTimeIsInValid(vtime))
  1613. vtime=Info->LastVideoPTimeCode;
  1614. if (!flush &&
  1615. (audiopin->DataSize<PACKET_SIZE-3 || videopin->DataSize<PACKET_SIZE-3))
  1616. return(TRUE); /* we need more data before writing */
  1617. if (!flush && audiopin && SlibTimeIsValid(atime) &&
  1618. videopin && SlibTimeIsValid(vtime))
  1619. timediff=atime-vtime-AUDIOTIME_ADJUST;
  1620. else
  1621. timediff=0;
  1622. /* write out complete Audio and/or Video packets */
  1623. while (!Info->IOError &&
  1624. ((audiopin && timediff<=0 && audiopin->DataSize>=PACKET_SIZE-3) ||
  1625. (videopin && timediff>=0 && videopin->DataSize>=PACKET_SIZE-3)))
  1626. {
  1627. Info->SystemTimeStamp=(Info->BytesProcessed*8000)/Info->TotalBitRate;
  1628. _SlibDebug(_VERBOSE_ || _WRITE_,
  1629. printf(" TotalBitRate=%d sys_clock=%d (%d ms) BytesProcessed=%ld\n",
  1630. Info->TotalBitRate, Info->SystemTimeStamp*90,
  1631. Info->SystemTimeStamp, Info->BytesProcessed) );
  1632. if (Info->BytesSincePack>=BYTES_PER_PACK)
  1633. {
  1634. /* mux_rate is in units of 50 bytes/s rounded up */
  1635. unsigned dword mux_rate=Info->TotalBitRate/(50*8)
  1636. + ((Info->TotalBitRate%(50*8))?1:0);
  1637. Info->SystemTimeStamp=(Info->BytesProcessed*8000)/Info->TotalBitRate;
  1638. _SlibDebug(_VERBOSE_ || _WRITE_,
  1639. printf(" TotalBitRate=%d sys_clock=%d (%d ms) mux_rate=%d BytesSincePack=%d\n",
  1640. Info->TotalBitRate, Info->SystemTimeStamp*90,
  1641. Info->SystemTimeStamp, mux_rate, Info->BytesSincePack) );
  1642. len=slibCreateMpegPackHeader(packet_data,
  1643. Info->SystemTimeStamp*90, /* 90 Khz clock */
  1644. mux_rate);
  1645. if (slibPutBuffer(Info, packet_data, len)==SlibErrorNone)
  1646. {
  1647. Info->BytesProcessed+=len;
  1648. Info->BytesSincePack+=len;
  1649. Info->BytesSincePack-=BYTES_PER_PACK;
  1650. }
  1651. }
  1652. if ((SlibTimeIsValid(atime) && atime-Info->SystemTimeStamp>300) ||
  1653. (SlibTimeIsValid(vtime) && vtime-Info->SystemTimeStamp>300))
  1654. {
  1655. /* we need a Padding packet */
  1656. _SlibDebug(_WRITE_||_TIMECODE_, printf("Padding\n") );
  1657. packet_data[0]=0x00;
  1658. packet_data[1]=0x00;
  1659. packet_data[2]=0x01;
  1660. packet_data[3]=MPEG_PADDING_STREAM_BASE;
  1661. packet_data[4]=PACKET_SIZE>>8; /* packet size - high byte */
  1662. packet_data[5]=PACKET_SIZE&0xFF; /* packet size - low byte */
  1663. packet_data[6]=0xFF;
  1664. packet_data[7]=0x0F; /* no presentation or time stamps */
  1665. size=PACKET_SIZE+6;
  1666. for (len=8; len<size; len++)
  1667. packet_data[len]=0xFF;
  1668. if (slibPutBuffer(Info, packet_data, size)==SlibErrorNone)
  1669. {
  1670. Info->BytesProcessed+=size;
  1671. Info->BytesSincePack+=size;
  1672. Info->PacketCount++;
  1673. }
  1674. }
  1675. else if (!flush && (atime>0 || vtime>0) &&
  1676. (atime+300<Info->SystemTimeStamp &&
  1677. vtime+300<Info->SystemTimeStamp))
  1678. {
  1679. /* we're not able to keep the bitrate low enough */
  1680. /* increase the Mux rate */
  1681. dword oldrate=Info->TotalBitRate;
  1682. SlibTime_t mintime=(vtime<atime) ? atime : vtime;
  1683. if (atime>0 && vtime>0)
  1684. mintime=(vtime<atime) ? vtime : atime;
  1685. Info->TotalBitRate=(dword)((Info->BytesProcessed*8000)/mintime);
  1686. if (Info->TotalBitRate==oldrate)
  1687. Info->TotalBitRate+=50*8;
  1688. Info->MuxBitRate=Info->TotalBitRate-Info->VideoBitRate-Info->AudioBitRate;
  1689. _SlibDebug(_WRITE_||_TIMECODE_,
  1690. printf("Bad Mux rate: atime=%ld vtime=%ld systime=%ld total=%ld -> %ld\n",
  1691. atime, vtime, Info->SystemTimeStamp, oldrate, Info->TotalBitRate) );
  1692. }
  1693. if (audiopin && timediff<=0 && audiopin->DataSize>=PACKET_SIZE-3)
  1694. {
  1695. packet_data[0]=0x00;
  1696. packet_data[1]=0x00;
  1697. packet_data[2]=0x01;
  1698. packet_data[3]=MPEG_AUDIO_STREAM_BASE;
  1699. packet_data[4]=PACKET_SIZE>>8; /* packet size - high byte */
  1700. packet_data[5]=PACKET_SIZE&0xFF; /* packet size - low byte */
  1701. /* 01 + STD_buffer_scale + STD_buffer_size[12..8] */
  1702. packet_data[6]=0x40 | 0x00 | (std_audio_buf_size>>8);
  1703. packet_data[7]=std_audio_buf_size & 0xFF;
  1704. ptimestamp=slibGetNextTimeOnPin(Info, audiopin, PACKET_SIZE-3);
  1705. if (SlibTimeIsValid(ptimestamp))
  1706. {
  1707. unsigned qword sys_clock=ptimestamp*90; /* 90 Khz clock */
  1708. _SlibDebug(_WRITE_||_TIMECODE_,
  1709. printf("LastAudioPTimeCode=%ld\n", Info->LastAudioPTimeCode) );
  1710. _SlibDebug(_WARN_ && (ptimestamp-(qword)Info->SystemTimeStamp>400 ||
  1711. (qword)Info->SystemTimeStamp-ptimestamp>400),
  1712. printf("Bad MuxRate(%d): SystemTimeStamp=%d ptimestamp=%d\n",
  1713. Info->SystemTimeStamp, ptimestamp) );
  1714. Info->LastAudioPTimeCode=ptimestamp;
  1715. sys_clock+=PTIME_ADJUST*90;
  1716. packet_data[8]=0x21|(unsigned char)(((sys_clock>>30)&0x07)<<1);
  1717. packet_data[9]=(unsigned char)(sys_clock>>22)&0xFF;
  1718. packet_data[10]=0x01|(unsigned char)((sys_clock>>14)&0xFE);
  1719. packet_data[11]=(unsigned char)((sys_clock>>7)&0xFF);
  1720. packet_data[12]=0x01|(unsigned char)((sys_clock<<1)&0xFE);
  1721. size=slibFillBufferFromPin(Info, audiopin, packet_data+13,
  1722. PACKET_SIZE-7, NULL);
  1723. size+=13;
  1724. }
  1725. else
  1726. {
  1727. packet_data[8]=0x0F; /* no presentation or time stamps */
  1728. size=slibFillBufferFromPin(Info, audiopin, packet_data+9,
  1729. PACKET_SIZE-3, NULL);
  1730. size+=9;
  1731. }
  1732. _SlibDebug(_VERBOSE_ || _WRITE_,
  1733. printf("slibPutBuffer(%d) %d bytes of audio\n", Info->Fd, size) );
  1734. if (slibPutBuffer(Info, packet_data, size)==SlibErrorNone)
  1735. {
  1736. Info->BytesProcessed+=size;
  1737. Info->BytesSincePack+=size;
  1738. Info->PacketCount++;
  1739. }
  1740. }
  1741. if (videopin && !Info->IOError && timediff>=0 &&
  1742. videopin->DataSize>=PACKET_SIZE-3)
  1743. {
  1744. packet_data[0]=0x00;
  1745. packet_data[1]=0x00;
  1746. packet_data[2]=0x01;
  1747. packet_data[3]=MPEG_VIDEO_STREAM_BASE;
  1748. packet_data[4]=PACKET_SIZE>>8; /* packet size - high byte */
  1749. packet_data[5]=PACKET_SIZE&0xFF; /* packet size - low byte */
  1750. /* 01 + STD_buffer_scale + STD_buffer_size[12..8] */
  1751. packet_data[6]=0x40 | 0x20 | (std_video_buf_size>>8);
  1752. packet_data[7]=std_video_buf_size & 0xFF;
  1753. /* store presentation time stamp */
  1754. ptimestamp=slibGetNextTimeOnPin(Info, videopin, PACKET_SIZE-3);
  1755. if (SlibTimeIsValid(ptimestamp))
  1756. {
  1757. unsigned qword sys_clock=ptimestamp*90; /* 90 Khz clock */
  1758. _SlibDebug(_WRITE_||_TIMECODE_,
  1759. printf("LastVideoPTimeCode=%ld LastVideoDTimeCode=%ld\n",
  1760. Info->LastVideoPTimeCode,
  1761. Info->LastVideoDTimeCode) );
  1762. if (SlibTimeIsInValid(Info->LastVideoDTimeCode))
  1763. dtimestamp=ptimestamp-(qword)(1000/Info->FramesPerSec);
  1764. else if (ptimestamp-Info->LastVideoPTimeCode>33*3)
  1765. dtimestamp=Info->LastVideoDTimeCode;
  1766. else
  1767. dtimestamp=SLIB_TIME_NONE;
  1768. Info->LastVideoPTimeCode=ptimestamp;
  1769. sys_clock+=PTIME_ADJUST*90;
  1770. packet_data[8]=(dtimestamp!=SLIB_TIME_NONE)?0x30:0x20;
  1771. packet_data[8]|=0x01|(unsigned char)(((sys_clock>>30)&0x07)<<1);
  1772. packet_data[9]=(unsigned char)(sys_clock>>22)&0xFF;
  1773. packet_data[10]=0x01|(unsigned char)((sys_clock>>14)&0xFE);
  1774. packet_data[11]=(unsigned char)((sys_clock>>7)&0xFF);
  1775. packet_data[12]=0x01|(unsigned char)((sys_clock<<1)&0xFE);
  1776. if (dtimestamp!=SLIB_TIME_NONE)
  1777. {
  1778. sys_clock=dtimestamp*90; /* 90 Khz clock */
  1779. Info->LastVideoDTimeCode=ptimestamp;
  1780. sys_clock+=PTIME_ADJUST*90;
  1781. packet_data[13]=0x01|(unsigned char)(((sys_clock>>30)&0x07)<<1);
  1782. packet_data[14]=(unsigned char)(sys_clock>>22)&0xFF;
  1783. packet_data[15]=0x01|(unsigned char)((sys_clock>>14)&0xFE);
  1784. packet_data[16]=(unsigned char)((sys_clock>>7)&0xFF);
  1785. packet_data[17]=0x01|(unsigned char)((sys_clock<<1)&0xFE);
  1786. size=slibFillBufferFromPin(Info, videopin, packet_data+18,
  1787. PACKET_SIZE-12, NULL);
  1788. size+=18;
  1789. }
  1790. else
  1791. {
  1792. size=slibFillBufferFromPin(Info, videopin, packet_data+13,
  1793. PACKET_SIZE-7, NULL);
  1794. size+=13;
  1795. }
  1796. }
  1797. else
  1798. {
  1799. packet_data[8]=0x0F; /* no presentation or time stamps */
  1800. size=slibFillBufferFromPin(Info, videopin, packet_data+9,
  1801. PACKET_SIZE-3, NULL);
  1802. size+=9;
  1803. }
  1804. _SlibDebug(_VERBOSE_ || _WRITE_,
  1805. printf("slibPutBuffer(%d) %d bytes of video\n", Info->Fd, size) );
  1806. if (slibPutBuffer(Info, packet_data, size)==SlibErrorNone)
  1807. {
  1808. Info->BytesProcessed+=size;
  1809. Info->BytesSincePack+=size;
  1810. Info->PacketCount++;
  1811. }
  1812. }
  1813. /* need to wait until we get enough data on both audio and video pin */
  1814. if (audiopin && videopin && !flush &&
  1815. (audiopin->DataSize<PACKET_SIZE-3 || videopin->DataSize<PACKET_SIZE-3))
  1816. {
  1817. _SlibDebug(_VERBOSE_ || _WRITE_,
  1818. printf("atime=%d vtime=%ld audiodata=%d videodata=%d\n",
  1819. atime, vtime, audiopin->DataSize, videopin->DataSize) );
  1820. break;
  1821. }
  1822. /* recalculate time differences */
  1823. timediff=slibGetNextTimeOnPin(Info, audiopin, PACKET_SIZE-3);
  1824. if (SlibTimeIsValid(timediff)) atime=timediff;
  1825. timediff=slibGetNextTimeOnPin(Info, videopin, PACKET_SIZE-3);
  1826. if (SlibTimeIsValid(timediff)) vtime=timediff;
  1827. if (!flush && audiopin && SlibTimeIsValid(atime) &&
  1828. videopin && SlibTimeIsValid(vtime))
  1829. timediff=atime-vtime-AUDIOTIME_ADJUST;
  1830. else
  1831. timediff=0;
  1832. }
  1833. /* flushing: write out remained Audio and/or Video data */
  1834. if (flush && !Info->IOError)
  1835. {
  1836. if (audiopin && audiopin->DataSize)
  1837. {
  1838. packet_data[0]=0x00;
  1839. packet_data[1]=0x00;
  1840. packet_data[2]=0x01;
  1841. packet_data[3]=MPEG_AUDIO_STREAM_BASE;
  1842. packet_data[4]=(unsigned char)((audiopin->DataSize+3)>>8);
  1843. packet_data[5]=(unsigned char)((audiopin->DataSize+3)&0xFF);
  1844. packet_data[6]=0x40 | (std_audio_buf_size>>8);
  1845. packet_data[7]=std_audio_buf_size & 0xFF;
  1846. packet_data[8]=0x0F; /* no presentation or time stamps */
  1847. size=slibFillBufferFromPin(Info, audiopin, packet_data+9,
  1848. (unsigned long)audiopin->DataSize, NULL);
  1849. size+=9;
  1850. _SlibDebug(_VERBOSE_ || _WRITE_,
  1851. printf("slibPutBuffer(%d) %d bytes of audio (flush)\n", Info->Fd, size));
  1852. if (slibPutBuffer(Info, packet_data, size)==SlibErrorNone)
  1853. {
  1854. Info->BytesProcessed+=size;
  1855. Info->BytesSincePack+=size;
  1856. Info->PacketCount++;
  1857. }
  1858. }
  1859. if (videopin && videopin->DataSize && !Info->IOError)
  1860. {
  1861. packet_data[0]=0x00;
  1862. packet_data[1]=0x00;
  1863. packet_data[2]=0x01;
  1864. packet_data[3]=MPEG_VIDEO_STREAM_BASE;
  1865. packet_data[4]=(unsigned char)((videopin->DataSize+3)>>8);
  1866. packet_data[5]=(unsigned char)((videopin->DataSize+3)&0xFF);
  1867. packet_data[6]=0x60 | (std_video_buf_size>>8);
  1868. packet_data[7]=std_video_buf_size & 0xFF;
  1869. packet_data[8]=0x0F; /* no presentation or time stamps */
  1870. size=slibFillBufferFromPin(Info,videopin,packet_data+9,
  1871. (unsigned long)videopin->DataSize, NULL);
  1872. size+=9;
  1873. _SlibDebug(_VERBOSE_ || _WRITE_,
  1874. printf("slibPutBuffer(%d) %d bytes of video (flush)\n",
  1875. Info->Fd, size) );
  1876. if (slibPutBuffer(Info, packet_data, size)==SlibErrorNone)
  1877. {
  1878. Info->BytesProcessed+=size;
  1879. Info->BytesSincePack+=size;
  1880. Info->PacketCount++;
  1881. }
  1882. }
  1883. }
  1884. if (flush && !Info->IOError) /* write End-Of-Sequence code */
  1885. {
  1886. unsigned char sys_trailer[4] = { 0x00, 0x00, 0x01, 0xB9 };
  1887. if (slibPutBuffer(Info, sys_trailer, sizeof(sys_trailer))==SlibErrorNone)
  1888. {
  1889. Info->BytesProcessed+=sizeof(sys_trailer);
  1890. Info->BytesSincePack+=sizeof(sys_trailer);
  1891. }
  1892. }
  1893. return(TRUE);
  1894. }
  1895. #endif /* MPEG_SUPPORT */
  1896. #ifdef MPEG_SUPPORT
  1897. /*
  1898. ** Function: slibWriteMpegAudio()
  1899. ** Descript: Writes out MPEG Audio stream data contained on Audio Pin.
  1900. ** Returns: TRUE if data was written, otherwise FALSE.
  1901. */
  1902. static SlibBoolean_t slibWriteMpegAudio(SlibInfo_t *Info, SlibBoolean_t flush)
  1903. {
  1904. SlibPin_t *srcpin=NULL;
  1905. unsigned char *buf=NULL;
  1906. unsigned dword size=0;
  1907. _SlibDebug(_VERBOSE_, printf("slibWriteMpegAudio()\n") );
  1908. if ((srcpin = slibGetPin(Info, SLIB_DATA_AUDIO))==NULL)
  1909. return(FALSE);
  1910. while ((buf=slibGetBufferFromPin(Info, srcpin, &size, NULL))!=NULL)
  1911. {
  1912. _SlibDebug(_VERBOSE_ || _WRITE_,
  1913. printf("==SlibErrorNone(%d) %d bytes\n", Info->Fd, size) );
  1914. if (slibPutBuffer(Info, buf, size)==SlibErrorNone)
  1915. Info->HeaderProcessed=TRUE;
  1916. }
  1917. return(TRUE);
  1918. }
  1919. #endif /* MPEG_SUPPORT */
  1920. #ifdef MPEG_SUPPORT
  1921. /*
  1922. ** Function: slibWriteMpegVideo()
  1923. ** Descript: Writes out MPEG Video stream data contained on Video Pin.
  1924. ** Returns: TRUE if data was written, otherwise FALSE.
  1925. */
  1926. static SlibBoolean_t slibWriteMpegVideo(SlibInfo_t *Info, SlibBoolean_t flush)
  1927. {
  1928. SlibPin_t *srcpin=NULL;
  1929. unsigned char *buf=NULL;
  1930. unsigned dword size=0;
  1931. _SlibDebug(_VERBOSE_, printf("slibWriteMpegVideo()\n") );
  1932. if ((srcpin = slibGetPin(Info, SLIB_DATA_VIDEO))==NULL)
  1933. return(FALSE);
  1934. while ((buf=slibGetBufferFromPin(Info, srcpin, &size, NULL))!=NULL)
  1935. {
  1936. if (slibPutBuffer(Info, buf, size)==SlibErrorNone)
  1937. Info->HeaderProcessed=TRUE;
  1938. }
  1939. return(TRUE);
  1940. }
  1941. #endif /* MPEG_SUPPORT */
  1942. #ifdef H261_SUPPORT
  1943. /*
  1944. ** Function: slibWriteH261()
  1945. ** Descript: Writes out H261 Video stream data contained on Video Pin.
  1946. ** Returns: TRUE if data was written, otherwise FALSE.
  1947. */
  1948. static SlibBoolean_t slibWriteH261(SlibInfo_t *Info, SlibBoolean_t flush)
  1949. {
  1950. SlibPin_t *srcpin=NULL;
  1951. unsigned char *buf=NULL;
  1952. unsigned dword size=0;
  1953. _SlibDebug(_VERBOSE_, printf("slibWriteH261()\n") );
  1954. if ((srcpin = slibGetPin(Info, SLIB_DATA_VIDEO))==NULL)
  1955. return(FALSE);
  1956. while ((buf=slibGetBufferFromPin(Info, srcpin, &size, NULL))!=NULL)
  1957. {
  1958. if (slibPutBuffer(Info, buf, size)==SlibErrorNone)
  1959. Info->HeaderProcessed=TRUE;
  1960. }
  1961. return(TRUE);
  1962. }
  1963. #endif /* H261_SUPPORT */
  1964. #ifdef H263_SUPPORT
  1965. /*
  1966. ** Function: slibWriteH263()
  1967. ** Descript: Writes out H263 Video stream data contained on Video Pin.
  1968. ** Returns: TRUE if data was written, otherwise FALSE.
  1969. */
  1970. static SlibBoolean_t slibWriteH263(SlibInfo_t *Info, SlibBoolean_t flush)
  1971. {
  1972. SlibPin_t *srcpin=NULL;
  1973. unsigned char *buf=NULL;
  1974. unsigned dword size=0;
  1975. _SlibDebug(_VERBOSE_, printf("slibWriteH263()\n") );
  1976. if ((srcpin = slibGetPin(Info, SLIB_DATA_VIDEO))==NULL)
  1977. return(FALSE);
  1978. while ((buf=slibGetBufferFromPin(Info, srcpin, &size, NULL))!=NULL)
  1979. {
  1980. if (slibPutBuffer(Info, buf, size)==SlibErrorNone)
  1981. Info->HeaderProcessed=TRUE;
  1982. }
  1983. return(TRUE);
  1984. }
  1985. #endif /* H263_SUPPORT */
  1986. #ifdef HUFF_SUPPORT
  1987. /*
  1988. ** Function: slibWriteSlibHuff()
  1989. ** Descript: Writes out SLIB Huff Video stream data contained on Video Pin.
  1990. ** Returns: TRUE if data was written, otherwise FALSE.
  1991. */
  1992. static SlibBoolean_t slibWriteSlibHuff(SlibInfo_t *Info, SlibBoolean_t flush)
  1993. {
  1994. SlibPin_t *srcpin=NULL;
  1995. unsigned char *buf=NULL;
  1996. unsigned dword size=0;
  1997. _SlibDebug(_VERBOSE_, printf("slibWriteSlibHuff()\n") );
  1998. if ((srcpin = slibGetPin(Info, SLIB_DATA_VIDEO))==NULL)
  1999. return(FALSE);
  2000. if (!Info->HeaderProcessed)
  2001. {
  2002. if (!Info->IOError)
  2003. {
  2004. char header[] = { 'S','L','I','B','H','U','F','F' };
  2005. _SlibDebug(_VERBOSE_ || _WRITE_,
  2006. printf("slibPutBuffer(%d) %d bytes of header\n",
  2007. Info->Fd, sizeof(header)) );
  2008. slibPutBuffer(Info, header, sizeof(header));
  2009. }
  2010. Info->HeaderProcessed=TRUE;
  2011. }
  2012. while ((buf=slibGetBufferFromPin(Info, srcpin, &size, NULL))!=NULL)
  2013. {
  2014. _SlibDebug(_VERBOSE_ || _WRITE_,
  2015. printf("slibPutBuffer(%d) %d bytes\n", Info->Fd, size) );
  2016. slibPutBuffer(Info, buf, size);
  2017. }
  2018. return(TRUE);
  2019. }
  2020. #endif /* HUFF_SUPPORT */
  2021. #ifdef G723_SUPPORT
  2022. /*
  2023. ** Function: slibWriteG723Audio()
  2024. ** Descript: Writes out G723 Audio stream data contained on Audio Pin.
  2025. ** Returns: TRUE if data was written, otherwise FALSE.
  2026. */
  2027. static SlibBoolean_t slibWriteG723Audio(SlibInfo_t *Info, SlibBoolean_t flush)
  2028. {
  2029. SlibPin_t *srcpin=NULL;
  2030. unsigned char *buf=NULL;
  2031. unsigned dword size=0;
  2032. _SlibDebug(_VERBOSE_, printf("slibWriteG723Audio()\n") );
  2033. if ((srcpin = slibGetPin(Info, SLIB_DATA_AUDIO))==NULL)
  2034. return(FALSE);
  2035. //MVP: There is no header to write for G723 codec
  2036. //After successful first "Write" set the "headerProcessed to TRUE
  2037. if (!Info->HeaderProcessed)
  2038. {
  2039. if ((buf=slibGetBufferFromPin(Info, srcpin, &size, NULL))!=NULL)
  2040. slibPutBuffer(Info, buf, size);
  2041. //Set Header processed flag to True
  2042. if (!Info->IOError)
  2043. Info->HeaderProcessed=TRUE;
  2044. }
  2045. while ((buf=slibGetBufferFromPin(Info, srcpin, &size, NULL))!=NULL)
  2046. slibPutBuffer(Info, buf, size);
  2047. return(TRUE);
  2048. }
  2049. #endif /* G723_SUPPORT */
  2050. /*
  2051. ** Name: slibCommitBuffers
  2052. ** Desc: Move buffers queued for output to there destination.
  2053. */
  2054. SlibBoolean_t slibCommitBuffers(SlibInfo_t *Info, SlibBoolean_t flush)
  2055. {
  2056. SlibPin_t *srcpin=NULL;
  2057. unsigned char *buf=NULL;
  2058. unsigned dword size=0;
  2059. switch (Info->Type)
  2060. {
  2061. #ifdef H261_SUPPORT
  2062. case SLIB_TYPE_H261:
  2063. slibWriteH261(Info, flush);
  2064. break;
  2065. #endif /* H261_SUPPORT */
  2066. #ifdef H263_SUPPORT
  2067. case SLIB_TYPE_H263:
  2068. slibWriteH263(Info, flush);
  2069. break;
  2070. #endif /* H263_SUPPORT */
  2071. #ifdef MPEG_SUPPORT
  2072. case SLIB_TYPE_MPEG1_VIDEO:
  2073. case SLIB_TYPE_MPEG2_VIDEO:
  2074. slibWriteMpegVideo(Info, flush);
  2075. break;
  2076. case SLIB_TYPE_MPEG1_AUDIO:
  2077. slibWriteMpegAudio(Info, flush);
  2078. break;
  2079. case SLIB_TYPE_MPEG_SYSTEMS:
  2080. case SLIB_TYPE_MPEG_SYSTEMS_MPEG2:
  2081. slibWriteMpeg1Systems(Info, flush);
  2082. break;
  2083. #endif /* MPEG_SUPPORT */
  2084. #ifdef HUFF_SUPPORT
  2085. case SLIB_TYPE_SHUFF:
  2086. slibWriteSlibHuff(Info, flush);
  2087. break;
  2088. #endif /* HUFF_SUPPORT */
  2089. #ifdef G723_SUPPORT
  2090. case SLIB_TYPE_G723:
  2091. slibWriteG723Audio(Info, flush);
  2092. break;
  2093. #endif /* G723_SUPPORT */
  2094. default:
  2095. _SlibDebug(_VERBOSE_ || _WARN_,
  2096. printf("slibCommitBuffers() Unknown type\n") );
  2097. return(FALSE);
  2098. }
  2099. return(Info->IOError ? FALSE : TRUE);
  2100. }
  2101. /************************** Data Stream Parsers ***********************/
  2102. /*
  2103. ** Function: slibParseWave()
  2104. ** Descript: Parse Wave (RIFF) and add Audio data to Audio Pin.
  2105. ** Returns: TRUE if data was added to dstpin, otherwise FALSE.
  2106. */
  2107. SlibBoolean_t slibParseWave(SlibInfo_t *Info, SlibPin_t *srcpin,
  2108. SlibPin_t *dstpin)
  2109. {
  2110. if (!srcpin)
  2111. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  2112. if (!dstpin)
  2113. dstpin = slibGetPin(Info, SLIB_DATA_AUDIO);
  2114. if (srcpin && dstpin)
  2115. {
  2116. unsigned char *buf;
  2117. unsigned dword size;
  2118. SlibTime_t time;
  2119. if (Info->AudioTimeStamp==0)
  2120. {
  2121. /* Discard header data from Compressed Pin */
  2122. buf = slibSearchBuffersOnPin(Info, srcpin,
  2123. NULL, &size, RIFF_DATA, 4, TRUE);
  2124. if (buf)
  2125. {
  2126. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  2127. slibGetDWordFromPin(Info, srcpin); /* discard Chunk size */
  2128. Info->AudioTimeStamp=1;
  2129. }
  2130. }
  2131. if ((buf=slibGetBufferFromPin(Info, srcpin, &size, &time))!=NULL)
  2132. {
  2133. _SlibDebug(_DEBUG_, printf("slibParseWave() adding %d bytes\n", size));
  2134. slibAddBufferToPin(dstpin, buf, size, time);
  2135. return(TRUE);
  2136. }
  2137. }
  2138. return(FALSE);
  2139. }
  2140. #ifdef AC3_SUPPORT
  2141. /*
  2142. ** Function: slibParseAC3Audio()
  2143. ** Descript: Parse Dolby AC-3 Audio stream and add Audio data to Audio Pin.
  2144. ** Returns: TRUE if data was added to dstpin, otherwise FALSE.
  2145. */
  2146. SlibBoolean_t slibParseAC3Audio(SlibInfo_t *Info, SlibPin_t *srcpin,
  2147. SlibPin_t *dstpin)
  2148. {
  2149. _SlibDebug(_DEBUG_, printf("slibParseMpegAudio()\n"));
  2150. if (!srcpin)
  2151. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  2152. if (!dstpin)
  2153. dstpin = slibGetPin(Info, SLIB_DATA_AUDIO);
  2154. if (srcpin && dstpin)
  2155. {
  2156. unsigned char *buf;
  2157. unsigned dword size;
  2158. SlibTime_t time;
  2159. if ((buf=slibGetBufferFromPin(Info, srcpin, &size, &time))!=NULL)
  2160. {
  2161. slibAddBufferToPin(dstpin, buf, size, time);
  2162. _SlibDebug(_DEBUG_, printf("slibParseAC3Audio() added %d bytes\n",
  2163. size));
  2164. return(TRUE);
  2165. }
  2166. }
  2167. return(FALSE);
  2168. }
  2169. #endif /* AC3_SUPPORT */
  2170. #ifdef MPEG_SUPPORT
  2171. /*
  2172. ** Function: slibParseMpegAudio()
  2173. ** Descript: Parse MPEG Audio stream and add Audio data to Audio Pin.
  2174. ** Returns: TRUE if data was added to dstpin, otherwise FALSE.
  2175. */
  2176. SlibBoolean_t slibParseMpegAudio(SlibInfo_t *Info, SlibPin_t *srcpin,
  2177. SlibPin_t *dstpin)
  2178. {
  2179. _SlibDebug(_DEBUG_, printf("slibParseMpegAudio()\n"));
  2180. if (!srcpin)
  2181. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  2182. if (!dstpin)
  2183. dstpin = slibGetPin(Info, SLIB_DATA_AUDIO);
  2184. if (srcpin && dstpin)
  2185. {
  2186. unsigned char *buf;
  2187. unsigned dword size;
  2188. SlibTime_t time;
  2189. if ((buf=slibGetBufferFromPin(Info, srcpin, &size, &time))!=NULL)
  2190. {
  2191. slibAddBufferToPin(dstpin, buf, size, time);
  2192. _SlibDebug(_DEBUG_, printf("slibParseMpegAudio() added %d bytes\n",
  2193. size));
  2194. return(TRUE);
  2195. }
  2196. }
  2197. return(FALSE);
  2198. }
  2199. #endif /* MPEG_SUPPORT */
  2200. #ifdef MPEG_SUPPORT
  2201. /*
  2202. ** Function: slibParseMpegVideo()
  2203. ** Descript: Parse MPEG Video stream and add Video data to Video Pin.
  2204. ** Returns: TRUE if data was added to dstpin, otherwise FALSE.
  2205. */
  2206. SlibBoolean_t slibParseMpegVideo(SlibInfo_t *Info, SlibPin_t *srcpin,
  2207. SlibPin_t *dstpin)
  2208. {
  2209. _SlibDebug(_DEBUG_, printf("slibParseMpegVideo()\n"));
  2210. if (!srcpin)
  2211. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  2212. if (!dstpin)
  2213. dstpin = slibGetPin(Info, SLIB_DATA_VIDEO);
  2214. if (srcpin && dstpin)
  2215. {
  2216. unsigned char *buf;
  2217. unsigned dword size;
  2218. SlibTime_t time;
  2219. if ((buf=slibGetBufferFromPin(Info, srcpin, &size, &time))!=NULL)
  2220. {
  2221. slibAddBufferToPin(dstpin, buf, size, time);
  2222. _SlibDebug(_DEBUG_, printf("slibParseMpegVideo() added %d bytes\n",
  2223. size));
  2224. return(TRUE);
  2225. }
  2226. _SlibDebug(_DEBUG_,
  2227. printf("slibParseMpegVideo() couldn't get COMPRESSED data\n"));
  2228. }
  2229. _SlibDebug(_DEBUG_, printf("slibParseMpegVideo() pins not ready\n"));
  2230. return(FALSE);
  2231. }
  2232. #endif /* MPEG_SUPPORT */
  2233. #ifdef MPEG_SUPPORT
  2234. #define skipbytes(b) if (size<=b) { \
  2235. oldsize = size; SlibFreeBuffer(bufstart); \
  2236. buf=bufstart=slibGetBufferFromPin(Info, srcpin, &size, NULL); \
  2237. if (!buf) return(FALSE); \
  2238. buf+=b-oldsize; size-=b-oldsize; \
  2239. } else { buf+=b; size-=b; }
  2240. /*
  2241. ** Function: slibParseMpeg1Sytems()
  2242. ** Descript: Parse MPEG I Systems stream and add Video data to Video Pin
  2243. ** and Audio to the Audio Pin.
  2244. ** Returns: TRUE if data was added to fillpin, otherwise FALSE.
  2245. */
  2246. SlibBoolean_t slibParseMpeg1Systems(SlibInfo_t *Info, SlibPin_t *srcpin,
  2247. SlibPin_t *fillpin)
  2248. {
  2249. if (!srcpin)
  2250. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  2251. _SlibDebug(_DEBUG_ || _PARSE_, printf("slibParseMpeg1Systems()\n"));
  2252. if (srcpin)
  2253. {
  2254. unsigned char abyte, packettype;
  2255. unsigned dword PacketLength;
  2256. unsigned char *buf, *bufstart=NULL;
  2257. unsigned dword size, oldsize;
  2258. SlibTime_t ptimestamp=SLIB_TIME_NONE;
  2259. SlibPin_t *dstpin;
  2260. while ((buf = bufstart = slibSearchBuffersOnPin(Info, srcpin, NULL,
  2261. &size, MPEG_START_CODE, MPEG_START_CODE_LEN/8, TRUE))!=NULL)
  2262. {
  2263. _SlibDebug(_VERIFY_ && size<1, printf("Insufficient bytes #1\n") );
  2264. packettype = *buf;
  2265. skipbytes(1);
  2266. if (packettype > 0xBB) /* it's a packet */
  2267. {
  2268. _SlibDebug(_DEBUG_||_PARSE_, printf("Found Packet size=%d\n", size));
  2269. PacketLength=(unsigned dword)(*buf<<8);
  2270. skipbytes(1);
  2271. PacketLength|=(unsigned dword)*buf;
  2272. skipbytes(1);
  2273. _SlibDebug(_DEBUG_||_PARSE_, printf(" PacketLength=%d\n",PacketLength));
  2274. while (*buf == 0xFF) /* Stuffing bytes */
  2275. {
  2276. skipbytes(1);
  2277. PacketLength--;
  2278. }
  2279. _SlibDebug(_VERIFY_ && size<1, printf("Insufficient bytes #3\n") );
  2280. abyte=*buf;
  2281. if ((abyte & 0xC0)==0x40) /* STD_buffer stuff */
  2282. {
  2283. skipbytes(2);
  2284. PacketLength-=2;
  2285. abyte=*buf;
  2286. }
  2287. _SlibDebug(_VERIFY_ && size<1, printf("Insufficient bytes #4\n") );
  2288. if ((abyte & 0xF0)==0x20 || (abyte & 0xF0)==0x30)
  2289. {
  2290. if (packettype!=Info->VideoMainStream &&
  2291. packettype!=Info->AudioMainStream)
  2292. {
  2293. skipbytes(5); /* skip Presentation Time Stamp */
  2294. PacketLength-=5;
  2295. if ((abyte & 0xF0)==0x30) /* skip Decoding timestamp */
  2296. {
  2297. skipbytes(5);
  2298. PacketLength-=5;
  2299. }
  2300. }
  2301. else
  2302. {
  2303. /* Presentation Time Stamp */
  2304. ptimestamp=(*buf)&0x0E; ptimestamp<<=7;
  2305. skipbytes(1);
  2306. ptimestamp|=(*buf); ptimestamp<<=8;
  2307. skipbytes(1);
  2308. ptimestamp|=(*buf)&0xFE; ptimestamp<<=7;
  2309. skipbytes(1);
  2310. ptimestamp|=(*buf); ptimestamp<<=7;
  2311. skipbytes(1);
  2312. ptimestamp|=(*buf)&0xFE;
  2313. skipbytes(1);
  2314. ptimestamp/=90;
  2315. if (packettype==Info->VideoMainStream)
  2316. {
  2317. if (!SlibTimeIsValid(Info->VideoPTimeBase) ||
  2318. ptimestamp<Info->VideoPTimeBase)
  2319. {
  2320. Info->VideoPTimeBase=ptimestamp;
  2321. _SlibDebug(_PARSE_ || _TIMECODE_,
  2322. printf("slibParseMpeg1Systems() VideoPTimeBase=%ld\n",
  2323. Info->VideoPTimeBase));
  2324. }
  2325. }
  2326. else if (packettype==Info->AudioMainStream)
  2327. {
  2328. if (!SlibTimeIsValid(Info->AudioPTimeBase) ||
  2329. ptimestamp<Info->AudioPTimeBase)
  2330. {
  2331. Info->AudioPTimeBase=ptimestamp;
  2332. _SlibDebug(_PARSE_ || _TIMECODE_,
  2333. printf("slibParseMpeg1Systems() AudioPTimeBase=%ld\n",
  2334. Info->AudioPTimeBase));
  2335. }
  2336. }
  2337. PacketLength-=5;
  2338. /* Decoding timestamp */
  2339. if ((abyte & 0xF0)==0x30)
  2340. {
  2341. SlibTime_t dtimestamp;
  2342. dtimestamp=(*buf)&0x0E; dtimestamp<<=7;
  2343. skipbytes(1);
  2344. dtimestamp|=(*buf); dtimestamp<<=8;
  2345. skipbytes(1);
  2346. dtimestamp|=(*buf)&0xFE; dtimestamp<<=7;
  2347. skipbytes(1);
  2348. dtimestamp|=(*buf); dtimestamp<<=7;
  2349. skipbytes(1);
  2350. dtimestamp|=(*buf)&0xFE;
  2351. skipbytes(1);
  2352. dtimestamp/=90;
  2353. if (packettype==Info->VideoMainStream)
  2354. {
  2355. _SlibDebug(_TIMECODE_,
  2356. printf("Video DTimeCode=%d\n", dtimestamp) );
  2357. Info->VideoDTimeCode=dtimestamp;
  2358. }
  2359. else if (packettype==Info->AudioMainStream)
  2360. {
  2361. _SlibDebug(_TIMECODE_,
  2362. printf("Audio DTimeCode=%d\n", dtimestamp) );
  2363. Info->AudioDTimeCode=dtimestamp;
  2364. }
  2365. PacketLength-=5;
  2366. }
  2367. }
  2368. }
  2369. else if (abyte != 0x0F)
  2370. {
  2371. _SlibDebug(_VERIFY_, printf("Last byte before data not 0x0F\n") );
  2372. /* add remaining buffer data back to input pin */
  2373. if (size)
  2374. {
  2375. SlibAllocSubBuffer(buf, size);
  2376. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  2377. }
  2378. SlibFreeBuffer(bufstart);
  2379. _SlibDebug(_VERIFY_, printf("Searching for next packet\n") );
  2380. continue; /* try to recover */
  2381. }
  2382. else
  2383. {
  2384. skipbytes(1);
  2385. PacketLength--;
  2386. }
  2387. if (packettype==Info->VideoMainStream)
  2388. dstpin = slibGetPin(Info, SLIB_DATA_VIDEO);
  2389. else if (packettype==Info->AudioMainStream)
  2390. dstpin = slibGetPin(Info, SLIB_DATA_AUDIO);
  2391. else
  2392. dstpin = NULL;
  2393. if (dstpin && slibPinOverflowing(Info, dstpin))
  2394. {
  2395. slibPinPrepareReposition(Info, dstpin->ID);
  2396. _SlibDebug(_WARN_,
  2397. printf("Skipped data on Overflowing pin %s: time %d->",
  2398. dstpin->name, Info->VideoTimeStamp) );
  2399. if (dstpin->ID == SLIB_DATA_VIDEO)
  2400. {
  2401. dword frames=slibCountCodesOnPin(Info, dstpin,
  2402. MPEG_PICTURE_START, 4, Info->OverflowSize/2);
  2403. if (Info->FramesPerSec)
  2404. Info->VideoTimeStamp+=slibFrameToTime(Info, frames);
  2405. }
  2406. _SlibDebug(_WARN_,
  2407. printf("new videotime=%ld\n", Info->VideoTimeStamp) );
  2408. slibSkipDataOnPin(Info, dstpin, Info->OverflowSize/2);
  2409. slibPinFinishReposition(Info, dstpin->ID);
  2410. if (dstpin->ID == SLIB_DATA_VIDEO) /* move to key frame */
  2411. SlibSeek((SlibHandle_t *)Info, SLIB_STREAM_MAINVIDEO,
  2412. SLIB_SEEK_NEXT_KEY, 0);
  2413. }
  2414. if (dstpin && !slibPinOverflowing(Info, dstpin))
  2415. {
  2416. _SlibDebug(_DEBUG_>1, printf("Adding Packet %X\n", packettype) );
  2417. /* add the packet to the destination pin */
  2418. while (PacketLength>size)
  2419. {
  2420. _SlibDebug(_WARN_>1,
  2421. printf("PacketLength=%d but buffer is %d bytes\n",
  2422. PacketLength, size) );
  2423. _SlibDebug(_VERIFY_ && Info->Fd>=0 && size>Info->FileBufSize,
  2424. printf("#1 size = %d\n", size));
  2425. if (size)
  2426. {
  2427. SlibAllocSubBuffer(buf, size);
  2428. slibAddBufferToPin(dstpin, buf, size, ptimestamp);
  2429. ptimestamp=SLIB_TIME_NONE;
  2430. PacketLength-=size;
  2431. }
  2432. SlibFreeBuffer(bufstart);
  2433. buf=bufstart=slibGetBufferFromPin(Info, srcpin, &size, NULL);
  2434. if (!buf)
  2435. return(fillpin==dstpin ? TRUE : FALSE);
  2436. }
  2437. if (PacketLength)
  2438. {
  2439. SlibAllocSubBuffer(buf, PacketLength);
  2440. slibAddBufferToPin(dstpin, buf, PacketLength, ptimestamp);
  2441. ptimestamp=SLIB_TIME_NONE;
  2442. size-=PacketLength;
  2443. buf+=PacketLength;
  2444. _SlibDebug(_VERIFY_ && Info->Fd>=0 && size>Info->FileBufSize,
  2445. printf("#3 size = %d\n", size));
  2446. }
  2447. /* add remaining buffer data back to input pin */
  2448. if (size)
  2449. {
  2450. SlibAllocSubBuffer(buf, size);
  2451. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  2452. }
  2453. SlibFreeBuffer(bufstart);
  2454. if (fillpin==dstpin)
  2455. return(TRUE);
  2456. if (fillpin==NULL)
  2457. return(FALSE);
  2458. }
  2459. else /* dump the packet */
  2460. {
  2461. _SlibDebug(_WARN_ && dstpin,
  2462. printf("Dumping packet %X (Overflow)\n", packettype) );
  2463. _SlibDebug((_WARN_>1 && !dstpin)||packettype==Info->VideoMainStream
  2464. ||packettype==Info->AudioMainStream,
  2465. printf("Dumping packet %X (No pin)\n", packettype) );
  2466. while (PacketLength>size)
  2467. {
  2468. PacketLength-=size;
  2469. SlibFreeBuffer(bufstart);
  2470. buf=bufstart=slibGetBufferFromPin(Info, srcpin, &size, NULL);
  2471. _SlibDebug(_VERIFY_ && !buf,
  2472. printf("Dumping Packet: no more buffers\n"));
  2473. if (buf==NULL)
  2474. return(FALSE);
  2475. }
  2476. buf+=PacketLength;
  2477. size-=PacketLength;
  2478. _SlibDebug(_VERIFY_ && Info->Fd>=0 && size>Info->FileBufSize,
  2479. printf("#5 size = %d\n", size));
  2480. /* add remaining buffer data back to input pin */
  2481. if (size)
  2482. {
  2483. SlibAllocSubBuffer(buf, size);
  2484. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  2485. }
  2486. SlibFreeBuffer(bufstart);
  2487. ptimestamp=SLIB_TIME_NONE;
  2488. }
  2489. } /* packet */
  2490. else /* put buffer back on the input pin */
  2491. {
  2492. _SlibDebug(_DEBUG_, printf("Not a packet %X - putting back buffer\n",
  2493. packettype) );
  2494. _SlibDebug(_VERIFY_ && Info->Fd>=0 && size>Info->FileBufSize,
  2495. printf("#6 size = %d\n", size));
  2496. if (size)
  2497. {
  2498. SlibAllocSubBuffer(buf, size);
  2499. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  2500. }
  2501. SlibFreeBuffer(bufstart);
  2502. }
  2503. } /* while */
  2504. }
  2505. return(FALSE);
  2506. }
  2507. #endif /* MPEG_SUPPORT */
  2508. #ifdef MPEG_SUPPORT
  2509. static SlibBoolean_t slibParsePESHeader(SlibInfo_t *Info, SlibPin_t *srcpin,
  2510. unsigned char **bufferstart, unsigned char **buffer,
  2511. unsigned dword *buffersize,
  2512. int *headerlen, unsigned dword *packetlen,
  2513. int *packettype, SlibTime_t *ptimestamp)
  2514. {
  2515. unsigned dword bytesprocessed=0;
  2516. unsigned dword PES_packet_length=0;
  2517. unsigned char *buf, *bufstart;
  2518. unsigned dword size, oldsize, header_len;
  2519. _SlibDebug(_DEBUG_||_VERBOSE_||_PARSE_, printf("slibParsePESHeader()\n"));
  2520. if (*buffer==NULL)
  2521. {
  2522. *packettype=0;
  2523. _SlibDebug(_VERIFY_,
  2524. buf=slibPeekBufferOnPin(Info, srcpin, &size, NULL);
  2525. if (buf && size>=8 && (buf[0]!=0x00 || buf[1]!=0x00 || buf[2]!=0x01))
  2526. ScDebugPrintf(Info->dbg,
  2527. "slibParsePESHeader() lost start code: %02X %02X %02X %02X %02X %02X %02X %02X\n",
  2528. buf[0], buf[1], buf[2], buf[3],
  2529. buf[4], buf[5], buf[6], buf[7]) );
  2530. do {
  2531. size=0;
  2532. buf = bufstart = slibSearchBuffersOnPin(Info, srcpin, NULL,
  2533. &size, MPEG_START_CODE, MPEG_START_CODE_LEN/8, TRUE);
  2534. if (!buf) return(FALSE);
  2535. *packettype=*buf;
  2536. if (*packettype>0xBB) /* useful packet start code */
  2537. {
  2538. skipbytes(1); /* skip packettype */
  2539. break;
  2540. }
  2541. _SlibDebug(_DEBUG_||_PARSE_,
  2542. ScDebugPrintf(Info->dbg,
  2543. "slibParsePESHeader() skipping packettype=%02X\n", *packettype));
  2544. /* put buffer back on the input pin */
  2545. if (size)
  2546. {
  2547. SlibAllocSubBuffer(buf, size);
  2548. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  2549. }
  2550. SlibFreeBuffer(bufstart);
  2551. } while (1);
  2552. }
  2553. else
  2554. {
  2555. buf=*buffer;
  2556. bufstart=*bufferstart;
  2557. size=*buffersize;
  2558. _SlibDebug(_VERIFY_ && size<4, ScDebugPrintf(Info->dbg,"Insufficient bytes #5\n") );
  2559. if (buf[0]==0x00 && buf[1]==0x00 && buf[2]==0x01)
  2560. {
  2561. *packettype=buf[3];
  2562. if (*packettype>0xBB)
  2563. {
  2564. skipbytes(4); /* skip start code */
  2565. bytesprocessed+=4;
  2566. }
  2567. }
  2568. else
  2569. *packettype=0;
  2570. }
  2571. if (*packettype>0xBB) /* useful packet start code */
  2572. {
  2573. unsigned short PTS_DTS_flags;
  2574. _SlibDebug(_DEBUG_||_PARSE_,
  2575. printf("slibParsePESHeader() packettype=%02X\n", *packettype));
  2576. _SlibDebug(_VERIFY_ && size<4, ScDebugPrintf(Info->dbg,"Insufficient bytes #6\n") );
  2577. /* PES_packet_length */
  2578. PES_packet_length=((unsigned dword)buf[0])<<8;
  2579. skipbytes(1);
  2580. PES_packet_length|=buf[0];
  2581. skipbytes(1);
  2582. bytesprocessed+=2;
  2583. if (*packettype==MPEG_PROGRAM_STREAM ||
  2584. *packettype==MPEG_PADDING_STREAM_BASE ||
  2585. *packettype==MPEG_PRIVATE_STREAM2_BASE)
  2586. {
  2587. PTS_DTS_flags=0;
  2588. header_len=0;
  2589. _SlibDebug(_DEBUG_||_PARSE_,
  2590. ScDebugPrintf(Info->dbg,"PES Packet 0x%02X, Length=%d, Header Len=%d\n",
  2591. *packettype, PES_packet_length, header_len));
  2592. }
  2593. else
  2594. {
  2595. /* PES_packet_length-=18; */
  2596. /* PES header stuff */
  2597. _SlibDebug(_PARSE_ && size>4, ScDebugPrintf(Info->dbg,
  2598. "PES Packet 0x%02X, header stuff: 0x%02X %02X %02X %02X\n",
  2599. *packettype, buf[0], buf[1], buf[2], buf[3]));
  2600. skipbytes(1);
  2601. PTS_DTS_flags=buf[0]>>6;
  2602. skipbytes(1);
  2603. header_len=buf[0];/* get PES header len */
  2604. skipbytes(1); /* PES header len */
  2605. bytesprocessed+=3;
  2606. PES_packet_length-=3;
  2607. PES_packet_length-=header_len;
  2608. _SlibDebug(_DEBUG_||_PARSE_,
  2609. ScDebugPrintf(Info->dbg,
  2610. "PES Packet 0x%02X, Length=%d, Header Len=%d, PTS_DTS_flags=%d\n",
  2611. *packettype, PES_packet_length, header_len, PTS_DTS_flags ));
  2612. if (header_len>0 && (PTS_DTS_flags==2 || PTS_DTS_flags==3))
  2613. {
  2614. /* Presentation Time Stamp */
  2615. unsigned long timestamp;
  2616. timestamp=(*buf)&0x0E; timestamp<<=7;
  2617. skipbytes(1);
  2618. timestamp|=(*buf); timestamp<<=8;
  2619. skipbytes(1);
  2620. timestamp|=(*buf)&0xFE; timestamp<<=7;
  2621. skipbytes(1);
  2622. timestamp|=(*buf); timestamp<<=7;
  2623. skipbytes(1);
  2624. timestamp|=(*buf)&0xFE;
  2625. skipbytes(1);
  2626. timestamp/=90;
  2627. *ptimestamp = timestamp;
  2628. bytesprocessed+=5;
  2629. header_len-=5;
  2630. /* Decoding timestamp */
  2631. if (PTS_DTS_flags==3)
  2632. {
  2633. timestamp=(*buf)&0x0E; timestamp<<=7;
  2634. skipbytes(1);
  2635. timestamp|=(*buf); timestamp<<=8;
  2636. skipbytes(1);
  2637. timestamp|=(*buf)&0xFE; timestamp<<=7;
  2638. skipbytes(1);
  2639. timestamp|=(*buf); timestamp<<=7;
  2640. skipbytes(1);
  2641. timestamp|=(*buf)&0xFE;
  2642. skipbytes(1);
  2643. timestamp/=90;
  2644. if (*packettype==Info->VideoMainStream ||
  2645. (Info->Type==SLIB_TYPE_MPEG_TRANSPORT &&
  2646. *packettype>=MPEG_VIDEO_STREAM_START &&
  2647. *packettype<=MPEG_VIDEO_STREAM_END))
  2648. {
  2649. _SlibDebug(_TIMECODE_,
  2650. ScDebugPrintf(Info->dbg,"Video DTimeCode=%d\n",timestamp));
  2651. Info->VideoDTimeCode=timestamp;
  2652. }
  2653. else if (*packettype==Info->AudioMainStream ||
  2654. (Info->Type==SLIB_TYPE_MPEG_TRANSPORT &&
  2655. *packettype>=MPEG_AUDIO_STREAM_START &&
  2656. *packettype<=MPEG_AUDIO_STREAM_END))
  2657. {
  2658. _SlibDebug(_TIMECODE_,
  2659. ScDebugPrintf(Info->dbg,"Audio DTimeCode=%d\n",timestamp));
  2660. Info->AudioDTimeCode=timestamp;
  2661. }
  2662. bytesprocessed+=5;
  2663. header_len-=5;
  2664. }
  2665. }
  2666. }
  2667. if (header_len>0)
  2668. {
  2669. _SlibDebug(_PARSE_,
  2670. ScDebugPrintf(Info->dbg,"slibParsePESHeader() skipping header: %d bytes\n",
  2671. header_len));
  2672. while ((int)size<=header_len)
  2673. {
  2674. _SlibDebug(_PARSE_,
  2675. ScDebugPrintf(Info->dbg,"slibParsePESHeader() size=%d <= header_len=%d\n",
  2676. size, header_len));
  2677. SlibFreeBuffer(bufstart);
  2678. header_len-=size;
  2679. bytesprocessed+=size;
  2680. buf=bufstart=slibGetBufferFromPin(Info, srcpin, &size, NULL);
  2681. if (!buf) return(FALSE);
  2682. }
  2683. buf+=header_len;
  2684. _SlibDebug(_VERIFY_ && size<(unsigned dword)header_len,
  2685. ScDebugPrintf(Info->dbg,"Insufficient bytes\n") );
  2686. size-=header_len;
  2687. bytesprocessed+=header_len;
  2688. }
  2689. }
  2690. /* If this is private data containing AC3, skip private header */
  2691. if (*packettype==MPEG_PRIVATE_STREAM1_BASE && (size<=0 || *buf==0x80))
  2692. {
  2693. /* header = 4 bytes = Hex: 80 0X XX XX */
  2694. skipbytes(4);
  2695. bytesprocessed+=4;
  2696. PES_packet_length-=4;
  2697. }
  2698. *buffer=buf;
  2699. *bufferstart=bufstart;
  2700. *buffersize=size;
  2701. if (headerlen)
  2702. *headerlen=bytesprocessed;
  2703. if (packetlen)
  2704. *packetlen=PES_packet_length;
  2705. _SlibDebug(_PARSE_,
  2706. ScDebugPrintf(Info->dbg,"slibParsePESHeader() bytesprocessed=%d packetlen=%d\n",
  2707. bytesprocessed, PES_packet_length));
  2708. return(TRUE);
  2709. }
  2710. #endif /* MPEG_SUPPORT */
  2711. #ifdef MPEG_SUPPORT
  2712. /*
  2713. ** Function: slibParseMpeg2Program()
  2714. ** Descript: Parse MPEG II Program stream and add Video data to Video Pin
  2715. ** and Audio to the Audio Pin.
  2716. ** Returns: TRUE if data was added to fillpin, otherwise FALSE.
  2717. */
  2718. SlibBoolean_t slibParseMpeg2Program(SlibInfo_t *Info, SlibPin_t *srcpin,
  2719. SlibPin_t *fillpin)
  2720. {
  2721. _SlibDebug(_DEBUG_||_PARSE_, ScDebugPrintf(Info->dbg,"slibParseMpeg2Program()\n"));
  2722. if (!srcpin)
  2723. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  2724. if (srcpin)
  2725. {
  2726. unsigned dword PacketLength;
  2727. unsigned char *buf, *bufstart=NULL;
  2728. unsigned dword size;
  2729. SlibTime_t ptimestamp = SLIB_TIME_NONE;
  2730. int header_len, packettype;
  2731. SlibPin_t *dstpin;
  2732. do {
  2733. buf=NULL;
  2734. if (!slibParsePESHeader(Info, srcpin, &bufstart, &buf, &size,
  2735. &header_len, &PacketLength, &packettype,
  2736. &ptimestamp))
  2737. {
  2738. _SlibDebug(_WARN_, ScDebugPrintf(Info->dbg,"slibParsePESHeader() failed\n") );
  2739. return(FALSE);
  2740. }
  2741. if (packettype)
  2742. {
  2743. if (packettype==Info->VideoMainStream)
  2744. {
  2745. _SlibDebug(_PARSE_,
  2746. ScDebugPrintf(Info->dbg,"slibParseMpeg2Program() VIDEO packet\n"));
  2747. dstpin = slibGetPin(Info, SLIB_DATA_VIDEO);
  2748. if (SlibTimeIsValid(ptimestamp) &&
  2749. (!SlibTimeIsValid(Info->VideoPTimeBase) ||
  2750. ptimestamp<Info->VideoPTimeBase))
  2751. {
  2752. Info->VideoPTimeBase=ptimestamp;
  2753. _SlibDebug(_PARSE_ || _TIMECODE_,
  2754. ScDebugPrintf(Info->dbg,"slibParseMpeg2Program() VideoPTimeBase=%ld\n",
  2755. Info->VideoPTimeBase));
  2756. }
  2757. }
  2758. else if (packettype==Info->AudioMainStream)
  2759. {
  2760. _SlibDebug(_PARSE_,
  2761. ScDebugPrintf(Info->dbg,"slibParseMpeg2Program() AUDIO packet\n"));
  2762. dstpin = slibGetPin(Info, SLIB_DATA_AUDIO);
  2763. if (SlibTimeIsValid(ptimestamp) &&
  2764. (!SlibTimeIsValid(Info->AudioPTimeBase) ||
  2765. ptimestamp<Info->AudioPTimeBase))
  2766. {
  2767. Info->AudioPTimeBase=ptimestamp;
  2768. _SlibDebug(_PARSE_ || _TIMECODE_,
  2769. ScDebugPrintf(Info->dbg,"slibParseMpeg2Program() AudioPTimeBase=%ld\n",
  2770. Info->AudioPTimeBase));
  2771. }
  2772. }
  2773. else if (packettype==MPEG_PRIVATE_STREAM1_BASE)
  2774. {
  2775. _SlibDebug(_PARSE_, printf("slibParseMpeg2Program() PRIVATE packet\n"));
  2776. dstpin = slibGetPin(Info, SLIB_DATA_PRIVATE);
  2777. }
  2778. else
  2779. {
  2780. _SlibDebug(_PARSE_,
  2781. ScDebugPrintf(Info->dbg,
  2782. "slibParseMpeg2Program() unknown packet 0x%02X, %d bytes\n",
  2783. packettype, PacketLength));
  2784. dstpin = NULL;
  2785. }
  2786. if (dstpin && slibPinOverflowing(Info, dstpin))
  2787. {
  2788. slibPinPrepareReposition(Info, dstpin->ID);
  2789. _SlibDebug(_WARN_,
  2790. ScDebugPrintf(Info->dbg,"Skipped data on Overflowing pin %s: time %d->",
  2791. dstpin->name, Info->VideoTimeStamp) );
  2792. if (dstpin->ID == SLIB_DATA_VIDEO)
  2793. {
  2794. dword frames=slibCountCodesOnPin(Info, dstpin,
  2795. MPEG_PICTURE_START, 4, Info->OverflowSize/2);
  2796. if (Info->FramesPerSec)
  2797. Info->VideoTimeStamp+=slibFrameToTime(Info, frames);
  2798. }
  2799. _SlibDebug(_WARN_, ScDebugPrintf(Info->dbg,"%d\n", Info->VideoTimeStamp) );
  2800. slibSkipDataOnPin(Info, dstpin, Info->OverflowSize/2);
  2801. slibPinFinishReposition(Info, dstpin->ID);
  2802. if (dstpin->ID == SLIB_DATA_VIDEO) /* move to key frame */
  2803. SlibSeek((SlibHandle_t *)Info, SLIB_STREAM_MAINVIDEO,
  2804. SLIB_SEEK_NEXT_KEY, 0);
  2805. }
  2806. if (dstpin && !slibPinOverflowing(Info, dstpin))
  2807. {
  2808. _SlibDebug(_DEBUG_, ScDebugPrintf(Info->dbg,"Adding Packet %X, %d bytes\n",
  2809. packettype, PacketLength) );
  2810. /* add the packet to the destination pin */
  2811. while (PacketLength>size)
  2812. {
  2813. _SlibDebug(_WARN_>1,
  2814. ScDebugPrintf(Info->dbg,"PacketLength=%d but buffer is %d bytes\n",
  2815. PacketLength, size) );
  2816. _SlibDebug(_VERIFY_ && Info->Fd>=0 && size>Info->FileBufSize,
  2817. printf("#1 size = %d\n", size));
  2818. if (size)
  2819. {
  2820. SlibAllocSubBuffer(buf, size);
  2821. /* ScDumpChar(buf, size, 0); */
  2822. slibAddBufferToPin(dstpin, buf, size, ptimestamp);
  2823. ptimestamp=SLIB_TIME_NONE;
  2824. PacketLength-=size;
  2825. }
  2826. SlibFreeBuffer(bufstart);
  2827. buf=bufstart=slibGetBufferFromPin(Info, srcpin, &size, NULL);
  2828. if (!buf)
  2829. return(fillpin==dstpin ? TRUE : FALSE);
  2830. }
  2831. if (PacketLength)
  2832. {
  2833. SlibAllocSubBuffer(buf, PacketLength);
  2834. /* ScDumpChar(buf, PacketLength, 0); */
  2835. slibAddBufferToPin(dstpin, buf, PacketLength, ptimestamp);
  2836. ptimestamp=SLIB_TIME_NONE;
  2837. size-=PacketLength;
  2838. buf+=PacketLength;
  2839. _SlibDebug(_VERIFY_ && Info->Fd>=0 && size>Info->FileBufSize,
  2840. ScDebugPrintf(Info->dbg,"#3 size = %d\n", size));
  2841. }
  2842. /* add remaining buffer data back to input pin */
  2843. if (size)
  2844. {
  2845. SlibAllocSubBuffer(buf, size);
  2846. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  2847. }
  2848. SlibFreeBuffer(bufstart);
  2849. if (fillpin==dstpin)
  2850. return(TRUE);
  2851. if (fillpin==NULL)
  2852. return(FALSE);
  2853. }
  2854. else /* dump the packet */
  2855. {
  2856. _SlibDebug(_WARN_ && dstpin,
  2857. ScDebugPrintf(Info->dbg,"Dumping packet %X (Overflow)\n", packettype) );
  2858. _SlibDebug((_WARN_>1 && !dstpin)||packettype==Info->VideoMainStream
  2859. ||packettype==Info->AudioMainStream,
  2860. ScDebugPrintf(Info->dbg,"Dumping packet %X (No pin)\n", packettype) );
  2861. while (PacketLength>size)
  2862. {
  2863. PacketLength-=size;
  2864. SlibFreeBuffer(bufstart);
  2865. buf=bufstart=slibGetBufferFromPin(Info, srcpin, &size, NULL);
  2866. _SlibDebug(_VERIFY_ && !buf,
  2867. ScDebugPrintf(Info->dbg,"Dumping Packet: no more buffers\n"));
  2868. if (buf==NULL)
  2869. return(FALSE);
  2870. }
  2871. buf+=PacketLength;
  2872. size-=PacketLength;
  2873. _SlibDebug(_VERIFY_ && Info->Fd>=0 && size>Info->FileBufSize,
  2874. ScDebugPrintf(Info->dbg,"#5 size = %d\n", size));
  2875. /* add remaining buffer data back to input pin */
  2876. if (size)
  2877. {
  2878. SlibAllocSubBuffer(buf, size);
  2879. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  2880. }
  2881. SlibFreeBuffer(bufstart);
  2882. }
  2883. } /* packet */
  2884. else /* put buffer back on the input pin */
  2885. {
  2886. _SlibDebug(_DEBUG_,
  2887. ScDebugPrintf(Info->dbg,"Not a packet %X - putting back buffer\n",
  2888. packettype) );
  2889. _SlibDebug(_VERIFY_ && Info->Fd>=0 && size>Info->FileBufSize,
  2890. ScDebugPrintf(Info->dbg,"#6 size = %d\n", size));
  2891. if (size)
  2892. {
  2893. SlibAllocSubBuffer(buf, size);
  2894. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  2895. }
  2896. SlibFreeBuffer(bufstart);
  2897. }
  2898. } while (1);
  2899. }
  2900. return(FALSE);
  2901. }
  2902. #endif /* MPEG_SUPPORT */
  2903. #ifdef MPEG_SUPPORT
  2904. /*
  2905. ** Function: slibParseMpeg2Transport()
  2906. ** Descript: Parse MPEG II Systems stream and add Video data to Video Pin.
  2907. ** Returns: TRUE if data was added to fillpin, otherwise FALSE.
  2908. */
  2909. SlibBoolean_t slibParseMpeg2Transport(SlibInfo_t *Info, SlibPin_t *srcpin,
  2910. SlibPin_t *fillpin)
  2911. {
  2912. _SlibDebug(_DEBUG_, ScDebugPrintf(Info->dbg,"slibParseMpeg2Transport()\n"));
  2913. if (!srcpin)
  2914. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  2915. if (srcpin)
  2916. {
  2917. int pid, adapt_field, payload_len, header_len, packettype;
  2918. unsigned char *buf, *bufstart=NULL;
  2919. unsigned dword size, oldsize;
  2920. SlibPin_t *dstpin;
  2921. /* SlibTime_t ptimestamp=SLIB_TIME_NONE; */
  2922. while ((buf = bufstart = slibSearchBuffersOnPin(Info, srcpin, NULL,
  2923. &size, MPEG_TSYNC_CODE, MPEG_TSYNC_CODE_LEN/8, TRUE))!=NULL)
  2924. {
  2925. _SlibDebug(_VERIFY_ && size<2, ScDebugPrintf(Info->dbg,"Insufficient bytes #2\n") );
  2926. pid=(int)(buf[0]&0x1F)<<8 | (int)buf[1]; /* 13 bits for PID */
  2927. skipbytes(2);
  2928. _SlibDebug(_VERIFY_ && size<1, ScDebugPrintf(Info->dbg,"Insufficient bytes #3\n") );
  2929. adapt_field=(buf[0]>>4)&0x03; /* 2 bits for adapt_field */
  2930. skipbytes(1);
  2931. payload_len=184; /* PES are 184 bytes */
  2932. if (adapt_field == 2 || adapt_field == 3)
  2933. {
  2934. _SlibDebug(_VERIFY_ && size<1, ScDebugPrintf(Info->dbg,"Insufficient bytes #4\n") );
  2935. header_len=*buf;
  2936. skipbytes(1);
  2937. payload_len--;
  2938. if (header_len) /* skip adaptation_field */
  2939. {
  2940. while ((int)size<=header_len)
  2941. {
  2942. SlibFreeBuffer(bufstart);
  2943. header_len-=size;
  2944. payload_len-=size;
  2945. buf=bufstart=slibGetBufferFromPin(Info, srcpin, &size, NULL);
  2946. if (!buf) return(FALSE);
  2947. }
  2948. _SlibDebug(_VERIFY_ && size<(unsigned dword)header_len,
  2949. ScDebugPrintf(Info->dbg,"Insufficient bytes\n") );
  2950. buf+=header_len;
  2951. size-=header_len;
  2952. payload_len-=header_len;
  2953. }
  2954. }
  2955. if ((adapt_field == 1 || adapt_field == 3)
  2956. && (Info->VideoPID<0 || Info->VideoPID==pid ||
  2957. Info->AudioPID<0 || Info->AudioPID==pid)) /* payload */
  2958. {
  2959. unsigned dword packet_len;
  2960. SlibTime_t ptimestamp = SLIB_TIME_NONE;
  2961. /* see if PES packet header */
  2962. if (slibParsePESHeader(Info, srcpin, &bufstart, &buf, &size,
  2963. &header_len, &packet_len, &packettype, &ptimestamp))
  2964. {
  2965. payload_len-=header_len;
  2966. _SlibDebug(_VERIFY_ && payload_len<0,
  2967. ScDebugPrintf(Info->dbg,"payload_len<header_len, header_len=%d\n",
  2968. header_len) );
  2969. if (pid!=MPEG_PID_NULL)
  2970. {
  2971. if (Info->VideoPID<0 && packettype>=MPEG_VIDEO_STREAM_START &&
  2972. packettype<=MPEG_VIDEO_STREAM_END)
  2973. {
  2974. _SlibDebug(_VERBOSE_,
  2975. ScDebugPrintf(Info->dbg,"Selecting Video PID %d\n", pid) );
  2976. Info->VideoPID=pid;
  2977. }
  2978. else if (Info->AudioPID<0 && packettype>=MPEG_AUDIO_STREAM_START &&
  2979. packettype<=MPEG_AUDIO_STREAM_END)
  2980. {
  2981. _SlibDebug(_VERBOSE_,
  2982. ScDebugPrintf(Info->dbg,"Selecting Audio PID %d\n", pid) );
  2983. Info->AudioPID=pid;
  2984. }
  2985. }
  2986. }
  2987. if (payload_len>0 && (Info->VideoPID==pid || Info->AudioPID==pid))
  2988. {
  2989. if (Info->VideoPID==pid)
  2990. dstpin = slibGetPin(Info, SLIB_DATA_VIDEO);
  2991. else
  2992. dstpin = slibGetPin(Info, SLIB_DATA_AUDIO);
  2993. if (dstpin && slibPinOverflowing(Info, dstpin))
  2994. {
  2995. slibPinPrepareReposition(Info, dstpin->ID);
  2996. _SlibDebug(_WARN_,
  2997. ScDebugPrintf(Info->dbg,"Skipped data on Overflowing pin %s: time %d->",
  2998. dstpin->name, Info->VideoTimeStamp) );
  2999. if (dstpin->ID == SLIB_DATA_VIDEO)
  3000. {
  3001. dword frames=slibCountCodesOnPin(Info, dstpin,
  3002. MPEG_PICTURE_START, 4, Info->OverflowSize/2);
  3003. if (Info->FramesPerSec)
  3004. Info->VideoTimeStamp+=slibFrameToTime(Info, frames);
  3005. }
  3006. _SlibDebug(_WARN_, ScDebugPrintf(Info->dbg,"%d\n", Info->VideoTimeStamp) );
  3007. slibSkipDataOnPin(Info, dstpin, Info->OverflowSize/2);
  3008. slibPinFinishReposition(Info, dstpin->ID);
  3009. if (dstpin->ID == SLIB_DATA_VIDEO) /* move to key frame */
  3010. SlibSeek((SlibHandle_t *)Info, SLIB_STREAM_MAINVIDEO,
  3011. SLIB_SEEK_NEXT_KEY, 0);
  3012. }
  3013. if (dstpin && !slibPinOverflowing(Info, dstpin))
  3014. {
  3015. _SlibDebug(_DEBUG_>1,
  3016. ScDebugPrintf(Info->dbg,"Adding Packet: Head=%02X %02X %02X %02X\n",
  3017. buf[0], buf[1], buf[2], buf[3]) );
  3018. /* add the packet to the destination pin */
  3019. while ((int)size<payload_len)
  3020. {
  3021. _SlibDebug(_DEBUG_,
  3022. printf("payload_len=%d but buffer is %d bytes\n",
  3023. payload_len, size) );
  3024. if (size)
  3025. {
  3026. SlibAllocSubBuffer(buf, size);
  3027. slibAddBufferToPin(dstpin, buf, size, ptimestamp);
  3028. ptimestamp=SLIB_TIME_NONE;
  3029. payload_len-=size;
  3030. }
  3031. SlibFreeBuffer(bufstart);
  3032. buf=bufstart=slibGetBufferFromPin(Info, srcpin, &size, NULL);
  3033. if (!buf) return(fillpin==dstpin?TRUE:FALSE);
  3034. }
  3035. if (payload_len)
  3036. {
  3037. SlibAllocSubBuffer(buf, payload_len);
  3038. slibAddBufferToPin(dstpin, buf, payload_len, ptimestamp);
  3039. ptimestamp=SLIB_TIME_NONE;
  3040. size-=payload_len;
  3041. buf+=payload_len;
  3042. }
  3043. /* add remaining buffer data back to input pin */
  3044. if (size)
  3045. {
  3046. SlibAllocSubBuffer(buf, size);
  3047. _SlibDebug(_WARN_ && buf[0]!=MPEG_TSYNC_CODE,
  3048. ScDebugPrintf(Info->dbg,
  3049. "Next code not Transport Sync: %02X %02X %02X %02X\n",
  3050. buf[0], buf[1], buf[2], buf[3]) );
  3051. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  3052. }
  3053. SlibFreeBuffer(bufstart);
  3054. payload_len=0;
  3055. size=0;
  3056. if (fillpin==dstpin)
  3057. return(TRUE);
  3058. else if (fillpin==NULL)
  3059. return(FALSE);
  3060. continue;
  3061. }
  3062. _SlibDebug(_WARN_, ScDebugPrintf(Info->dbg,
  3063. "ParseMpeg2Transport() Data not added: payload_len=%d PID=%d\n",
  3064. payload_len, pid) );
  3065. }
  3066. }
  3067. if (payload_len>0) /* dump the payload */
  3068. {
  3069. if (payload_len>(int)size)
  3070. {
  3071. payload_len-=size;
  3072. SlibFreeBuffer(bufstart);
  3073. bufstart=slibGetBufferFromPin(Info, srcpin, &size, NULL);
  3074. if (!bufstart)
  3075. return(FALSE);
  3076. buf=bufstart+payload_len;
  3077. size-=payload_len;
  3078. }
  3079. else
  3080. {
  3081. buf+=payload_len;
  3082. size-=payload_len;
  3083. }
  3084. }
  3085. /* add remaining buffer data back to input pin */
  3086. if (size)
  3087. {
  3088. SlibAllocSubBuffer(buf, size);
  3089. _SlibDebug(_WARN_ && buf[0]!=MPEG_TSYNC_CODE,
  3090. ScDebugPrintf(Info->dbg,
  3091. "Next code not Transport Sync: %02X %02X %02X %02X\n",
  3092. buf[0], buf[1], buf[2], buf[3]) );
  3093. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  3094. }
  3095. SlibFreeBuffer(bufstart);
  3096. } /* while */
  3097. }
  3098. return(FALSE);
  3099. }
  3100. #endif /* MPEG_SUPPORT */
  3101. #ifdef H261_SUPPORT
  3102. /*
  3103. ** Function: slibParseH261()
  3104. ** Descript: Parse H.261 Video stream and add Video data to Video Pin.
  3105. ** Returns: TRUE if data was added to dstpin, otherwise FALSE.
  3106. */
  3107. SlibBoolean_t slibParseH261(SlibInfo_t *Info, SlibPin_t *srcpin,
  3108. SlibPin_t *dstpin)
  3109. {
  3110. if (!srcpin)
  3111. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  3112. if (!dstpin)
  3113. dstpin = slibGetPin(Info, SLIB_DATA_VIDEO);
  3114. _SlibDebug(_DEBUG_, printf("slibParseH261()\n"));
  3115. if (srcpin && dstpin)
  3116. {
  3117. unsigned char *buf;
  3118. unsigned dword size;
  3119. SlibTime_t time;
  3120. if ((buf=slibGetBufferFromPin(Info, srcpin, &size, &time))!=NULL)
  3121. {
  3122. slibAddBufferToPin(dstpin, buf, size, time);
  3123. return(TRUE);
  3124. }
  3125. }
  3126. return(FALSE);
  3127. }
  3128. #endif /* H261_SUPPORT */
  3129. #ifdef H263_SUPPORT
  3130. /*
  3131. ** Function: slibParseH261()
  3132. ** Descript: Parse H.261 Video stream and add Video data to Video Pin.
  3133. ** Returns: TRUE if data was added to dstpin, otherwise FALSE.
  3134. */
  3135. SlibBoolean_t slibParseH263(SlibInfo_t *Info, SlibPin_t *srcpin,
  3136. SlibPin_t *dstpin)
  3137. {
  3138. if (!srcpin)
  3139. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  3140. if (!dstpin)
  3141. dstpin = slibGetPin(Info, SLIB_DATA_VIDEO);
  3142. _SlibDebug(_DEBUG_, printf("slibParseH263()\n"));
  3143. if (srcpin && dstpin)
  3144. {
  3145. unsigned char *buf;
  3146. unsigned dword size;
  3147. SlibTime_t time;
  3148. if (Info->Type==SLIB_TYPE_RTP_H263)
  3149. {
  3150. word rtp_start, sequence_no;
  3151. dword sync_src, pay_start;
  3152. /* RTP header */
  3153. rtp_start=slibGetWordFromPin(Info, srcpin);
  3154. sequence_no=slibGetWordFromPin(Info, srcpin);
  3155. time=slibGetDWordFromPin(Info, srcpin);
  3156. sync_src=slibGetDWordFromPin(Info, srcpin);
  3157. /* RTP payload header */
  3158. pay_start=slibGetDWordFromPin(Info, srcpin);
  3159. if ((pay_start&0x80000000) == 0) /* Mode A */
  3160. {
  3161. size=Info->PacketSize-16;
  3162. buf=SlibAllocBuffer(size);
  3163. }
  3164. else if ((pay_start&0x40000000) == 0) /* Mode B */
  3165. {
  3166. dword pay_start2=slibGetDWordFromPin(Info, srcpin);
  3167. size=Info->PacketSize-20;
  3168. }
  3169. else /* Mode C */
  3170. {
  3171. dword pay_start2=slibGetDWordFromPin(Info, srcpin);
  3172. size=Info->PacketSize-20;
  3173. }
  3174. buf=SlibAllocBuffer(size);
  3175. if (buf==NULL) return(FALSE);
  3176. size=slibFillBufferFromPin(Info, srcpin, buf, size, NULL);
  3177. if (size)
  3178. slibAddBufferToPin(dstpin, buf, size, time);
  3179. }
  3180. else
  3181. {
  3182. if ((buf=slibGetBufferFromPin(Info, srcpin, &size, &time))!=NULL)
  3183. {
  3184. slibAddBufferToPin(dstpin, buf, size, time);
  3185. return(TRUE);
  3186. }
  3187. }
  3188. }
  3189. return(FALSE);
  3190. }
  3191. #endif /* H263_SUPPORT */
  3192. #ifdef HUFF_SUPPORT
  3193. /*
  3194. ** Function: slibParseSlibHuff()
  3195. ** Descript: Parse SLIB Huffman Video stream and add Video data to Video Pin.
  3196. ** Returns: TRUE if data was added to dstpin, otherwise FALSE.
  3197. */
  3198. SlibBoolean_t slibParseSlibHuff(SlibInfo_t *Info, SlibPin_t *srcpin,
  3199. SlibPin_t *dstpin)
  3200. {
  3201. if (!srcpin)
  3202. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  3203. if (!dstpin)
  3204. dstpin = slibGetPin(Info, SLIB_DATA_VIDEO);
  3205. _SlibDebug(_DEBUG_, printf("slibParseSlibHuff()\n"));
  3206. if (srcpin && dstpin)
  3207. {
  3208. unsigned char *buf;
  3209. unsigned dword size;
  3210. SlibTime_t time;
  3211. _SlibDebug(_VERBOSE_, printf("slibParseSlibHuff(%s)\n", srcpin->name) );
  3212. if (!Info->HeaderProcessed)
  3213. {
  3214. _SlibDebug(_VERBOSE_, printf("slibParseSlibHuff() Header\n") );
  3215. slibGetDWordFromPin(Info, srcpin); /* SLIB */
  3216. slibGetDWordFromPin(Info, srcpin); /* HUFF */
  3217. Info->HeaderProcessed=TRUE;
  3218. }
  3219. if ((buf=slibGetBufferFromPin(Info, srcpin, &size, &time))!=NULL)
  3220. {
  3221. slibAddBufferToPin(dstpin, buf, size, time);
  3222. return(TRUE);
  3223. }
  3224. }
  3225. return(FALSE);
  3226. }
  3227. #endif /* HUFF_SUPPORT */
  3228. #ifdef G723_SUPPORT
  3229. /*
  3230. ** Function: slibParseG723Audio()
  3231. ** Descript: Parse G723 Audio stream and add Audio data to Audio Pin.
  3232. ** Returns: TRUE if data was added to dstpin, otherwise FALSE.
  3233. */
  3234. SlibBoolean_t slibParseG723Audio(SlibInfo_t *Info, SlibPin_t *srcpin,
  3235. SlibPin_t *dstpin)
  3236. {
  3237. _SlibDebug(_DEBUG_, printf("slibParseG723Audio()\n"));
  3238. if (!srcpin)
  3239. srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED);
  3240. if (!dstpin)
  3241. dstpin = slibGetPin(Info, SLIB_DATA_AUDIO);
  3242. if (srcpin && dstpin)
  3243. {
  3244. unsigned char *buf;
  3245. unsigned dword size;
  3246. SlibTime_t time;
  3247. if ((buf=slibGetBufferFromPin(Info, srcpin, &size, &time))!=NULL)
  3248. {
  3249. slibAddBufferToPin(dstpin, buf, size, time);
  3250. _SlibDebug(_DEBUG_, printf("slibParseG723Audio() added %d bytes\n",
  3251. size));
  3252. return(TRUE);
  3253. }
  3254. }
  3255. return(FALSE);
  3256. }
  3257. #endif /* G723_SUPPORT */
  3258. /*
  3259. ** Function: slibParseAVI()
  3260. ** Descript: Parse AVI data and add Video data to Video Pin.
  3261. ** Returns: TRUE if data was added to fillpin, otherwise FALSE.
  3262. */
  3263. SlibBoolean_t slibParseAVI(SlibInfo_t *Info, SlibPin_t *srcpin,
  3264. SlibPin_t *fillpin)
  3265. {
  3266. unsigned char *buf, *bufstart=NULL;
  3267. unsigned dword size;
  3268. SlibTime_t time=SLIB_TIME_NONE;
  3269. SlibPin_t *dstpin;
  3270. _SlibDebug(_DEBUG_, printf("slibParseAVI()\n") );
  3271. if (!srcpin && (srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED))==NULL)
  3272. return(FALSE);
  3273. /* only searching for video, for now */
  3274. dstpin = slibGetPin(Info, SLIB_DATA_VIDEO);
  3275. do {
  3276. buf = bufstart = slibSearchBuffersOnPin(Info, srcpin, NULL, &size,
  3277. (('0'<<16) | ('0'<<8) | 'd'), 3, TRUE);
  3278. /* AVI_DIBcompressed or AVI_DIBbits */
  3279. if (buf==NULL || *buf=='c' || *buf=='b')
  3280. break;
  3281. /* put buffer back on input to be search again */
  3282. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  3283. } while (buf);
  3284. if (buf && dstpin)
  3285. {
  3286. unsigned dword framesize;
  3287. buf++; /* skip 'c' or 'b' */
  3288. size--;
  3289. framesize=((int)buf[3]<<24)|((int)buf[2]<<16)|
  3290. ((int)buf[1]<<8)|buf[0];
  3291. buf+=4;
  3292. size-=4;
  3293. if (framesize==0)
  3294. return(FALSE);
  3295. else if (size>=framesize)
  3296. {
  3297. SlibAllocSubBuffer(buf, framesize);
  3298. slibAddBufferToPin(dstpin, buf, framesize, time);
  3299. }
  3300. else
  3301. {
  3302. /* frame data crosses over into next buffer */
  3303. unsigned char *newbuf=SlibAllocBuffer(framesize);
  3304. slibAddBufferToPin(dstpin, newbuf, framesize, time);
  3305. _SlibDebug(_DEBUG_, printf("Copying in sections\n") );
  3306. do {
  3307. _SlibDebug(_DEBUG_,
  3308. printf("Copying %d bytes (framesize=%d)\n", size, framesize) );
  3309. memcpy(newbuf, buf, size);
  3310. newbuf+=size;
  3311. framesize-=size;
  3312. SlibFreeBuffer(bufstart);
  3313. buf=bufstart=slibGetBufferFromPin(Info, srcpin, &size, &time);
  3314. if (buf==NULL)
  3315. return(FALSE);
  3316. } while (size<framesize);
  3317. if (framesize>0)
  3318. memcpy(newbuf, buf, framesize);
  3319. }
  3320. buf+=framesize;
  3321. size-=framesize;
  3322. if (size>0) /* add remaining data back onto src pin */
  3323. {
  3324. SlibAllocSubBuffer(buf, size);
  3325. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  3326. }
  3327. SlibFreeBuffer(bufstart);
  3328. if (fillpin==dstpin)
  3329. return(TRUE);
  3330. }
  3331. else
  3332. _SlibDebug(_DEBUG_, printf("Failed to find JPEG frame\n") );
  3333. return(FALSE);
  3334. }
  3335. /*
  3336. ** Function: slibParseRaster()
  3337. ** Descript: Parse Sun Raster data and add Video data to Video Pin.
  3338. ** Returns: TRUE if data was added to fillpin, otherwise FALSE.
  3339. */
  3340. SlibBoolean_t slibParseRaster(SlibInfo_t *Info, SlibPin_t *srcpin,
  3341. SlibPin_t *fillpin)
  3342. {
  3343. unsigned char *buf, *bufstart=NULL;
  3344. unsigned dword size;
  3345. SlibTime_t time=SLIB_TIME_NONE;
  3346. SlibPin_t *dstpin;
  3347. _SlibDebug(_DEBUG_, printf("slibParseRaster()\n") );
  3348. if (!srcpin && (srcpin = slibLoadPin(Info, SLIB_DATA_COMPRESSED))==NULL)
  3349. return(FALSE);
  3350. /* only searching for video, for now */
  3351. dstpin = slibGetPin(Info, SLIB_DATA_VIDEO);
  3352. buf = bufstart = slibSearchBuffersOnPin(Info, srcpin, NULL, &size,
  3353. 0x59a66a95, 4, TRUE);
  3354. if (buf && dstpin)
  3355. {
  3356. unsigned dword framesize;
  3357. buf+=28; /* skip header */
  3358. size-=28;
  3359. if (Info->CompVideoFormat)
  3360. framesize=Info->CompVideoFormat->biWidth*Info->CompVideoFormat->biHeight*3;
  3361. else
  3362. framesize=Info->Width*Info->Height*3;
  3363. if (size>=framesize)
  3364. {
  3365. SlibAllocSubBuffer(buf, framesize);
  3366. slibAddBufferToPin(dstpin, buf, framesize, time);
  3367. }
  3368. else
  3369. {
  3370. /* frame data crosses over into next buffer */
  3371. unsigned char *newbuf=SlibAllocBuffer(framesize);
  3372. slibAddBufferToPin(dstpin, newbuf, framesize, time);
  3373. _SlibDebug(_DEBUG_, printf("Copying in sections\n") );
  3374. do {
  3375. _SlibDebug(_DEBUG_,
  3376. printf("Copying %d bytes (framesize=%d)\n", size, framesize) );
  3377. memcpy(newbuf, buf, size);
  3378. newbuf+=size;
  3379. framesize-=size;
  3380. SlibFreeBuffer(bufstart);
  3381. buf=bufstart=slibGetBufferFromPin(Info, srcpin, &size, &time);
  3382. if (buf==NULL)
  3383. return(FALSE);
  3384. } while (size<framesize);
  3385. if (framesize>0)
  3386. memcpy(newbuf, buf, framesize);
  3387. }
  3388. buf+=framesize;
  3389. size-=framesize;
  3390. if (size>0) /* add remaining data back onto src pin */
  3391. {
  3392. SlibAllocSubBuffer(buf, size);
  3393. slibInsertBufferOnPin(srcpin, buf, size, SLIB_TIME_NONE);
  3394. }
  3395. SlibFreeBuffer(bufstart);
  3396. if (fillpin==dstpin)
  3397. return(TRUE);
  3398. }
  3399. else
  3400. _SlibDebug(_DEBUG_, printf("Failed to find Raster frame\n") );
  3401. return(FALSE);
  3402. }
  3403. /*
  3404. ** Name: slibSetMaxInput
  3405. ** Desc: Set the maximum number of bytes allowed to be input.
  3406. ** Use maxbytes=0 for no limit.
  3407. */
  3408. void slibSetMaxInput(SlibInfo_t *Info, unsigned dword maxbytes)
  3409. {
  3410. Info->MaxBytesInput=maxbytes;
  3411. if (maxbytes)
  3412. {
  3413. SlibPin_t *pin = slibGetPin(Info, SLIB_DATA_COMPRESSED);
  3414. if (pin)
  3415. Info->InputMarker=pin->Offset;
  3416. else
  3417. Info->MaxBytesInput=0;
  3418. }
  3419. }
  3420. /*
  3421. ** Name: slibGetPinPosition
  3422. ** Desc: Get the current byte position counter for a pin.
  3423. ** Return: -1 if pin doesn't exist
  3424. */
  3425. SlibPosition_t slibGetPinPosition(SlibInfo_t *Info, int pinid)
  3426. {
  3427. SlibPin_t *pin;
  3428. _SlibDebug(_DEBUG_>1, printf("slibGetPinPosition(pinid=%d)\n", pinid) );
  3429. if ((pin=slibGetPin(Info, pinid))!=NULL)
  3430. return(pin->Offset);
  3431. else
  3432. return((SlibPosition_t)-1);
  3433. }
  3434. /*
  3435. ** Name: slibSetPinPosition
  3436. ** Desc: Set the byte position counter for a pin.
  3437. ** Called when seeking to a new offset.
  3438. ** Return: old position
  3439. ** -1 if pin doesn't exist
  3440. */
  3441. SlibPosition_t slibSetPinPosition(SlibInfo_t *Info, int pinid,
  3442. SlibPosition_t pos)
  3443. {
  3444. SlibPin_t *pin;
  3445. SlibPosition_t oldpos;
  3446. _SlibDebug(_DEBUG_, printf("slibSetPinPosition(pinid=%d, pos=%ld)\n",
  3447. pinid, pos) );
  3448. if ((pin=slibGetPin(Info, pinid))!=NULL)
  3449. {
  3450. oldpos=pin->Offset;
  3451. pin->Offset=pos;
  3452. return(oldpos);
  3453. }
  3454. else
  3455. return((SlibPosition_t)-1);
  3456. }
  3457. /*
  3458. ** Name: slibPreLoadPin
  3459. ** Desc: Load a buffer onto a particular pin (try to get it from the
  3460. ** appropriate source).
  3461. */
  3462. SlibPin_t *slibPreLoadPin(SlibInfo_t *Info, SlibPin_t *pin)
  3463. {
  3464. unsigned char *buf, *bufstart=NULL;
  3465. unsigned dword size;
  3466. _SlibDebug(_DEBUG_, printf("slibPreLoadPin(%s)\n",pin->name) );
  3467. if (!pin || Info->Mode!=SLIB_MODE_DECOMPRESS)
  3468. return(NULL);
  3469. switch (pin->ID)
  3470. {
  3471. case SLIB_DATA_COMPRESSED:
  3472. _SlibDebug(_DEBUG_ && Info->MaxBytesInput,
  3473. printf("Offset=%d InputMarker=%d\n",
  3474. pin->Offset, Info->InputMarker) );
  3475. if (Info->MaxBytesInput &&
  3476. (pin->Offset-Info->InputMarker)>=Info->MaxBytesInput)
  3477. return(NULL);
  3478. if (Info->SlibCB) /* data source is an application callback */
  3479. {
  3480. SlibMessage_t result;
  3481. _SlibDebug(_VERBOSE_,
  3482. printf("slibPreLoadPin(%s) SlibCB(SLIB_MSG_ENDOFDATA)\n",
  3483. pin->name) );
  3484. result=(*(Info->SlibCB))((SlibHandle_t)Info,
  3485. SLIB_MSG_ENDOFDATA, (SlibCBParam1_t)0,
  3486. (SlibCBParam2_t)0, (void *)Info->SlibCBUserData);
  3487. switch (result)
  3488. {
  3489. case SLIB_MSG_CONTINUE:
  3490. return(pin);
  3491. case SLIB_MSG_ENDOFSTREAM:
  3492. case SLIB_MSG_ENDOFDATA:
  3493. case SLIB_MSG_BADPOSITION:
  3494. Info->IOError=TRUE;
  3495. break;
  3496. default:
  3497. return(NULL);
  3498. }
  3499. }
  3500. else if (Info->Fd>=0) /* data source is a file */
  3501. {
  3502. if ((buf=SlibAllocBuffer(Info->FileBufSize))==NULL)
  3503. return(NULL);
  3504. _SlibDebug(_VERBOSE_,
  3505. printf("slibPreLoadPin(%s) ScFileRead(%d, %d bytes)\n",
  3506. pin->name, Info->Fd, Info->FileBufSize) );
  3507. size = ScFileRead(Info->Fd, buf, Info->FileBufSize);
  3508. if (size<Info->FileBufSize)
  3509. Info->IOError=TRUE;
  3510. if (size <= 0)
  3511. {
  3512. SlibFreeBuffer(buf);
  3513. return(NULL);
  3514. }
  3515. else
  3516. {
  3517. slibAddBufferToPin(pin, buf, size, SLIB_TIME_NONE);
  3518. return(pin);
  3519. }
  3520. }
  3521. break;
  3522. case SLIB_DATA_AUDIO:
  3523. switch (Info->Type)
  3524. {
  3525. case SLIB_TYPE_PCM_WAVE:
  3526. if (slibParseWave(Info, NULL, pin))
  3527. return(pin);
  3528. break;
  3529. #ifdef MPEG_SUPPORT
  3530. case SLIB_TYPE_MPEG1_AUDIO:
  3531. if (slibParseMpegAudio(Info, NULL, pin))
  3532. return(pin);
  3533. break;
  3534. case SLIB_TYPE_MPEG_SYSTEMS:
  3535. case SLIB_TYPE_MPEG_SYSTEMS_MPEG2:
  3536. if (slibParseMpeg1Systems(Info, NULL, pin))
  3537. return(pin);
  3538. break;
  3539. case SLIB_TYPE_MPEG_PROGRAM:
  3540. if (slibParseMpeg2Program(Info, NULL, pin))
  3541. return(pin);
  3542. break;
  3543. case SLIB_TYPE_MPEG_TRANSPORT:
  3544. if (slibParseMpeg2Transport(Info, NULL, pin))
  3545. return(pin);
  3546. break;
  3547. #endif /* MPEG_SUPPORT */
  3548. #ifdef AC3_SUPPORT
  3549. case SLIB_TYPE_AC3_AUDIO:
  3550. if (slibParseAC3Audio(Info, NULL, pin))
  3551. return(pin);
  3552. break;
  3553. #endif /* AC3_SUPPORT */
  3554. #ifdef G723_SUPPORT
  3555. case SLIB_TYPE_G723:
  3556. if (slibParseG723Audio(Info, NULL, pin))
  3557. return(pin);
  3558. break;
  3559. #endif /* G723_SUPPORT */
  3560. }
  3561. break;
  3562. case SLIB_DATA_VIDEO:
  3563. switch (Info->Type)
  3564. {
  3565. case SLIB_TYPE_AVI:
  3566. case SLIB_TYPE_YUV_AVI:
  3567. if (slibParseAVI(Info, NULL, pin))
  3568. return(pin);
  3569. break;
  3570. case SLIB_TYPE_RASTER:
  3571. if (slibParseRaster(Info, NULL, pin))
  3572. return(pin);
  3573. break;
  3574. #ifdef MPEG_SUPPORT
  3575. case SLIB_TYPE_MPEG1_VIDEO:
  3576. case SLIB_TYPE_MPEG2_VIDEO:
  3577. if (slibParseMpegVideo(Info, NULL, pin))
  3578. return(pin);
  3579. break;
  3580. case SLIB_TYPE_MPEG_SYSTEMS:
  3581. case SLIB_TYPE_MPEG_SYSTEMS_MPEG2:
  3582. if (slibParseMpeg1Systems(Info, NULL, pin))
  3583. return(pin);
  3584. break;
  3585. case SLIB_TYPE_MPEG_PROGRAM:
  3586. if (slibParseMpeg2Program(Info, NULL, pin))
  3587. return(pin);
  3588. break;
  3589. case SLIB_TYPE_MPEG_TRANSPORT:
  3590. if (slibParseMpeg2Transport(Info, NULL, pin))
  3591. return(pin);
  3592. break;
  3593. #endif /* MPEG_SUPPORT */
  3594. #ifdef H261_SUPPORT
  3595. case SLIB_TYPE_H261:
  3596. case SLIB_TYPE_RTP_H261:
  3597. if (slibParseH261(Info, NULL, pin))
  3598. return(pin);
  3599. break;
  3600. #endif /* H261_SUPPORT */
  3601. #ifdef H263_SUPPORT
  3602. case SLIB_TYPE_H263:
  3603. case SLIB_TYPE_RTP_H263:
  3604. if (slibParseH263(Info, NULL, pin))
  3605. return(pin);
  3606. break;
  3607. #endif /* H263_SUPPORT */
  3608. #ifdef JPEG_SUPPORT
  3609. case SLIB_TYPE_JPEG_AVI:
  3610. case SLIB_TYPE_MJPG_AVI:
  3611. if (slibParseAVI(Info, NULL, pin))
  3612. return(pin);
  3613. break;
  3614. #endif /* JPEG_SUPPORT */
  3615. #ifdef HUFF_SUPPORT
  3616. case SLIB_TYPE_SHUFF:
  3617. if (slibParseSlibHuff(Info, NULL, pin))
  3618. return(pin);
  3619. break;
  3620. #endif /* HUFF_SUPPORT */
  3621. }
  3622. break;
  3623. case SLIB_DATA_PRIVATE:
  3624. switch (Info->Type)
  3625. {
  3626. #ifdef MPEG_SUPPORT
  3627. case SLIB_TYPE_MPEG_SYSTEMS:
  3628. case SLIB_TYPE_MPEG_SYSTEMS_MPEG2:
  3629. if (slibParseMpeg1Systems(Info, NULL, pin))
  3630. return(pin);
  3631. break;
  3632. case SLIB_TYPE_MPEG_PROGRAM:
  3633. if (slibParseMpeg2Program(Info, NULL, pin))
  3634. return(pin);
  3635. break;
  3636. case SLIB_TYPE_MPEG_TRANSPORT:
  3637. if (slibParseMpeg2Transport(Info, NULL, pin))
  3638. return(pin);
  3639. break;
  3640. #endif /* MPEG_SUPPORT */
  3641. }
  3642. break;
  3643. }
  3644. return(NULL);
  3645. }
  3646. /*
  3647. ** Name: slibPutBuffer
  3648. ** Purpose: Send a buffer to the appropriate output.
  3649. */
  3650. SlibStatus_t slibPutBuffer(SlibInfo_t *Info, unsigned char *buffer,
  3651. unsigned dword bufsize)
  3652. {
  3653. _SlibDebug(_VERBOSE_ || _WRITE_,
  3654. printf("slibPutBuffer(%d) %d bytes\n", Info->Fd, bufsize) );
  3655. if (bufsize==0)
  3656. return(SlibErrorNone);
  3657. if (Info->IOError || buffer==NULL)
  3658. return(SlibErrorWriting);
  3659. if (Info->Fd>=0) /* writing to a file */
  3660. {
  3661. if ((unsigned dword)ScFileWrite(Info->Fd, buffer, bufsize)<bufsize)
  3662. Info->IOError=TRUE;
  3663. if (SlibValidBuffer(buffer))
  3664. SlibFreeBuffer(buffer);
  3665. }
  3666. else if (Info->SlibCB) /* sending data back to app through a callback */
  3667. {
  3668. _SlibDebug(_WARN_,
  3669. printf("slibPutBuffer(%d) callbacks not yet supported\n") );
  3670. if (SlibValidBuffer(buffer))
  3671. SlibFreeBuffer(buffer);
  3672. }
  3673. else /* adding buffer to compress data pin */
  3674. {
  3675. unsigned char *bufptr=buffer;
  3676. SlibPin_t *pin=slibGetPin(Info, SLIB_DATA_COMPRESSED);
  3677. if (!SlibValidBuffer(bufptr))
  3678. {
  3679. /* we need to create a SLIB allocated buffer to copy the
  3680. * output to and then add to the compressed data pin
  3681. */
  3682. bufptr=SlibAllocBuffer(bufsize);
  3683. if (!bufptr)
  3684. return(SlibErrorMemory);
  3685. memcpy(bufptr, buffer, bufsize);
  3686. }
  3687. if (slibAddBufferToPin(pin, bufptr, bufsize, SLIB_TIME_NONE)!=SlibErrorNone)
  3688. return(SlibErrorWriting);
  3689. }
  3690. return(SlibErrorNone);
  3691. }
  3692. /*
  3693. ** Name: slibGetBufferFromPin
  3694. ** Purpose: Read the next buffer from the data source.
  3695. */
  3696. unsigned char *slibGetBufferFromPin(SlibInfo_t *Info, SlibPin_t *pin,
  3697. unsigned dword *size, SlibTime_t *time)
  3698. {
  3699. unsigned char *address=NULL;
  3700. _SlibDebug(_DEBUG_>1, printf("slibGetBufferFromPin(%s)\n", pin->name) );
  3701. if (slibLoadPin(Info, pin->ID) != NULL)
  3702. {
  3703. SlibBuffer_t *tmpbuf = pin->Buffers;
  3704. pin->Offset=tmpbuf->offset+tmpbuf->size;
  3705. if (tmpbuf->next == NULL)
  3706. pin->BuffersTail = NULL;
  3707. pin->Buffers = tmpbuf->next;
  3708. address=tmpbuf->address;
  3709. if (size)
  3710. *size = tmpbuf->size;
  3711. if (time)
  3712. *time = tmpbuf->time;
  3713. pin->BufferCount--;
  3714. pin->DataSize-=tmpbuf->size;
  3715. ScFree(tmpbuf);
  3716. }
  3717. else
  3718. {
  3719. _SlibDebug(_WARN_ && pin->DataSize,
  3720. printf("slibGetBufferFromPin() No more buffers on pin, yet DataSize=%d\n",
  3721. pin->DataSize) );
  3722. if (size)
  3723. *size = 0;
  3724. address=NULL;
  3725. }
  3726. return(address);
  3727. }
  3728. /*
  3729. ** Name: slibGetBufferFromPin
  3730. ** Purpose: Get a pointer to the next buffer on a pin, but don't
  3731. ** remove it.
  3732. */
  3733. unsigned char *slibPeekBufferOnPin(SlibInfo_t *Info, SlibPin_t *pin,
  3734. unsigned dword *psize, SlibTime_t *ptime)
  3735. {
  3736. _SlibDebug(_DEBUG_, printf("slibPeekBufferOnPin(%s)\n",pin->name) );
  3737. if (slibLoadPin(Info, pin->ID) != NULL)
  3738. {
  3739. if (psize)
  3740. *psize = pin->Buffers->size;
  3741. if (ptime)
  3742. *ptime = pin->Buffers->time;
  3743. return(pin->Buffers->address);
  3744. }
  3745. else
  3746. return(NULL);
  3747. }
  3748. /*
  3749. ** Name: slibGetNextTimeOnPin
  3750. ** Purpose: Get the next time on a pin.
  3751. */
  3752. SlibTime_t slibGetNextTimeOnPin(SlibInfo_t *Info, SlibPin_t *pin,
  3753. unsigned dword maxbytes)
  3754. {
  3755. unsigned dword bytesread=0, size;
  3756. unsigned char *buf;
  3757. SlibTime_t timefound=SLIB_TIME_NONE;
  3758. _SlibDebug(_DEBUG_,
  3759. printf("slibGetNextTimeOnPin(%s)\n",pin?"NULL":pin->name) );
  3760. if (!pin)
  3761. return(SLIB_TIME_NONE);
  3762. buf=slibPeekBufferOnPin(Info, pin, &size, &timefound);
  3763. bytesread+=size;
  3764. while (buf && timefound==SLIB_TIME_NONE && bytesread<maxbytes)
  3765. {
  3766. buf=slibPeekNextBufferOnPin(Info, pin, buf, &size, &timefound);
  3767. bytesread+=size;
  3768. }
  3769. return(timefound);
  3770. }
  3771. /*
  3772. ** Name: slibPeekNextBufferOnPin
  3773. ** Purpose: Get a pointer to the next buffer on a pin after the buffer
  3774. ** specified by "lastbuffer"; don't remove it.
  3775. */
  3776. unsigned char *slibPeekNextBufferOnPin(SlibInfo_t *Info, SlibPin_t *pin,
  3777. unsigned char *lastbuffer,
  3778. unsigned dword *size, SlibTime_t *time)
  3779. {
  3780. unsigned char *address=NULL;
  3781. SlibBuffer_t *tmpbuf;
  3782. _SlibDebug(_DEBUG_, printf("slibPeekNextBufferOnPin(lastbuffer=%p,pin=%s)\n",
  3783. lastbuffer, pin->name) );
  3784. /* check the last loaded buffer first */
  3785. tmpbuf=pin->BuffersTail;
  3786. if (tmpbuf &&
  3787. lastbuffer>=tmpbuf->address && lastbuffer<tmpbuf->address+tmpbuf->size)
  3788. {
  3789. /* load a new buffer onto the pin */
  3790. slibPreLoadPin(Info, pin);
  3791. if (tmpbuf != pin->BuffersTail)
  3792. {
  3793. address=pin->BuffersTail->address;
  3794. if (size)
  3795. *size=pin->BuffersTail->size;
  3796. if (time)
  3797. *time=pin->BuffersTail->time;
  3798. return(address);
  3799. }
  3800. _SlibDebug(_WARN_, printf("slibPeekNextBufferOnPin() End of data\n") );
  3801. return(NULL);
  3802. }
  3803. /* search through all the buffers on the pin */
  3804. if (pin->Buffers==NULL)
  3805. slibPreLoadPin(Info, pin);
  3806. tmpbuf = pin->Buffers;
  3807. while (tmpbuf)
  3808. {
  3809. if (lastbuffer>=tmpbuf->address && lastbuffer<tmpbuf->address+tmpbuf->size)
  3810. {
  3811. tmpbuf=tmpbuf->next;
  3812. if (tmpbuf)
  3813. {
  3814. _SlibDebug(_WARN_ &&
  3815. lastbuffer>=tmpbuf->address && lastbuffer<tmpbuf->address+tmpbuf->size,
  3816. printf("slibPeekNextBufferOnPin() same addresses\n") );
  3817. if (size)
  3818. *size=tmpbuf->size;
  3819. if (time)
  3820. *time=tmpbuf->time;
  3821. return(tmpbuf->address);
  3822. }
  3823. else
  3824. {
  3825. _SlibDebug(_WARN_, printf("slibPeekNextBufferOnPin() End of bufs\n") );
  3826. return(NULL);
  3827. }
  3828. }
  3829. tmpbuf=tmpbuf->next;
  3830. }
  3831. _SlibDebug(_WARN_, printf("slibPeekNextBufferOnPin() address no found\n") );
  3832. return(NULL);
  3833. }