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

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: format_base.c 611 2006-01-25 22:01:51Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "common.h"
  24. #define DROP_SHOW 8
  25. #define ENDCHUNKS (128*1024/BLOCKSIZE)
  26. #define SKIPDISTANCE 64*1024
  27. #define SYNCREAD 6
  28. #define SEEKTRIES 4
  29. #define SEEKMAXREAD 256*1024
  30. #define PROCESSMINAUDIO BLOCKSIZE
  31. #define PROCESSMINVIDEO 128*1024
  32. #define READER_BONUS 256*1024
  33. int FormatBaseEnum(format_base* p,int* No,datadef* Param)
  34. {
  35. if (FormatEnum(p,No,Param) == ERR_NONE)
  36. return ERR_NONE;
  37. if (*No < p->TotalCount)
  38. {
  39. memset(Param,0,sizeof(datadef));
  40. Param->Class = FORMAT_CLASS;
  41. Param->Size = sizeof(pin);
  42. Param->No = FORMAT_STREAM + *No;
  43. Param->Type = TYPE_PACKET;
  44. Param->Flags = DF_OUTPUT;
  45. *No = 0;
  46. return ERR_NONE;
  47. }
  48. *No -= p->TotalCount;
  49. if (*No < p->TotalCount)
  50. {
  51. memset(Param,0,sizeof(datadef));
  52. Param->Class = FORMAT_CLASS;
  53. Param->Size = sizeof(pin);
  54. Param->No = FORMAT_COMMENT + *No;
  55. Param->Type = TYPE_COMMENT;
  56. Param->Flags = DF_OUTPUT;
  57. *No = 0;
  58. return ERR_NONE;
  59. }
  60. *No -= p->TotalCount;
  61. return ERR_INVALID_PARAM;
  62. }
  63. static INLINE void Format_BufferInsert(format_reader* p,format_buffer* Buffer)
  64. {
  65. Buffer->Next = NULL;
  66. if (p->BufferLast)
  67. p->BufferLast->Next = Buffer;
  68. else
  69. p->BufferFirst = Buffer;
  70. p->BufferLast = Buffer;
  71. p->BufferAvailable += Buffer->Length;
  72. }
  73. format_buffer* Format_BufferAlloc(format_base*,int Mode); //0:optional 1:drop 2:new alloc
  74. format_packet* Format_PacketAlloc(format_base*);
  75. void Format_PacketRelease(format_base*, format_packet*);
  76. bool_t Format_ReadBuffer(format_reader*, bool_t ToRead);
  77. int Format_Seek(format_base* p,filepos_t Pos,int Origin)
  78. {
  79. int Result = p->Reader->Seek(p->Reader,Pos,Origin);
  80. if (Result == ERR_NONE)
  81. Format_AfterSeek(p);
  82. return Result;
  83. }
  84. int Format_SeekForce(format_base* p,filepos_t Pos,int Origin)
  85. {
  86. int Result;
  87. filepos_t Save = p->Reader[0].FilePos;
  88. p->Reader[0].FilePos = -1;
  89. Result = Format_Seek(p,Pos,Origin);
  90. if (Result != ERR_NONE)
  91. p->Reader[0].FilePos = Save;
  92. return Result;
  93. }
  94. int Format_SeekByPacket(format_base* p,tick_t Time,filepos_t FilePos,bool_t PrevKey)
  95. {
  96. int Try;
  97. int LastTime;
  98. int LastPos;
  99. format_stream* Stream = NULL;
  100. if (FilePos < 0)
  101. {
  102. Time -= SHOWAHEAD; // we should go a little earlier
  103. if (Time > 0)
  104. {
  105. if (p->FileSize<0 || p->Duration<0)
  106. return ERR_NOT_SUPPORTED;
  107. FilePos = Scale(p->FileSize,Time,p->Duration);
  108. }
  109. else
  110. FilePos = 0;
  111. }
  112. if (Time>0)
  113. Stream = Format_DefSyncStream(p,p->Reader);
  114. p->GlobalOffset = 0;
  115. p->InSeek = 1;
  116. LastPos = -1;
  117. LastTime = -1;
  118. for (Try=0;Try<SEEKTRIES;++Try) // maximum iterations
  119. {
  120. if (FilePos < p->SeekByPacket_DataStart)
  121. FilePos = p->SeekByPacket_DataStart;
  122. if (p->SeekByPacket_BlockAlign > 1)
  123. FilePos -= (FilePos - p->SeekByPacket_DataStart) % p->SeekByPacket_BlockAlign;
  124. if (Format_Seek(p,FilePos,SEEK_SET) != ERR_NONE)
  125. {
  126. p->InSeek = 0;
  127. return ERR_NOT_SUPPORTED;
  128. }
  129. if (Stream)
  130. {
  131. // check if really seeked to the right time (and adjust if needed)
  132. format_reader* Reader = p->Reader;
  133. int SeekRead = FilePos + SEEKMAXREAD;
  134. while (Reader->FilePos<SeekRead)
  135. {
  136. Format_ReadBuffer(Reader,0); // simulate input thread
  137. if (p->FillQueue(p,Reader) == ERR_END_OF_FILE)
  138. break;
  139. if (Stream->LastTime >= 0)
  140. {
  141. DEBUG_MSG3(DEBUG_FORMAT,T("SeekByPacket to:%d current:%d filepos:%d"),Time,Stream->LastTime,FilePos);
  142. if (!p->TimeStamps)
  143. {
  144. // adjust GlobalOffset
  145. p->GlobalOffset = Time - Stream->LastTime;
  146. if (p->GlobalOffset>0)
  147. {
  148. // need to adjust all stream packets
  149. int No;
  150. for (No=0;No<p->StreamCount;++No)
  151. {
  152. format_packet* i;
  153. format_stream* s = p->Streams[No];
  154. if (s->LastTime >= 0)
  155. s->LastTime += p->GlobalOffset;
  156. for (i=s->PacketFirst;i;i=i->Next)
  157. if (i->RefTime >= 0)
  158. i->RefTime += p->GlobalOffset;
  159. }
  160. }
  161. else
  162. p->GlobalOffset=0; // can't be negative
  163. SeekRead = -1; // accept
  164. break;
  165. }
  166. if (Time>=Stream->LastTime && (Time-Stream->LastTime) <= (TICKSPERSEC/2))
  167. FilePos = -1; // accept
  168. else
  169. {
  170. int Move;
  171. if (LastPos >= 0)
  172.   Move = Scale(FilePos-LastPos,Time-Stream->LastTime,Stream->LastTime-LastTime);
  173. else
  174.   Move = Scale(p->FileSize,Time-Stream->LastTime,p->Duration);
  175. if (Move < 0)
  176. Move = (Move*9)/8;
  177. else
  178. Move = (Move*15)/16;
  179. if (Move > 64*1024 || Move < -64*1024)
  180. {
  181. LastTime = Stream->LastTime;
  182. LastPos = FilePos;
  183. }
  184. else
  185. LastPos = -1;
  186. FilePos += Move;
  187. }
  188. if (FilePos < 0 || FilePos >= p->FileSize)
  189. SeekRead = -1; // accept
  190. break;
  191. }
  192. if (!Reader->BufferAvailable && !Reader->ReadBuffer && Reader->NoMoreInput)
  193. break; // end of file
  194. }
  195. if (Reader->FilePos<SeekRead)
  196. continue; // try again
  197. }
  198. break;
  199. }
  200. p->InSeek = 0;
  201. return ERR_NONE;
  202. }
  203. format_buffer* Format_BufferRemoveLast(format_reader* Reader)
  204. {
  205. format_buffer *Buffer,*Tail;
  206. LockEnter(Reader->Format->BufferLock);
  207. Buffer = Reader->BufferLast;
  208. if (Buffer)
  209. {
  210. Tail = Reader->BufferFirst;
  211. if (Tail == Buffer)
  212. Reader->BufferFirst = Tail = NULL;
  213. else
  214. {
  215. while (Tail && Tail->Next != Buffer)
  216. Tail = Tail->Next;
  217. if (Tail)
  218. Tail->Next = NULL;
  219. }
  220. Reader->BufferLast = Tail;
  221. Reader->BufferAvailable -= Buffer->Length;
  222. assert(Reader->BufferAvailable >= 0);
  223. }
  224. LockLeave(Reader->Format->BufferLock);
  225. return Buffer;
  226. }
  227. int Format_Hibernate(format_base* p, int Mode)
  228. {
  229. bool_t Changed = 0;
  230. if (p->InputLock)
  231. {
  232. int No;
  233. format_buffer *Buffer;
  234. LockEnter(p->InputLock);
  235. LockEnter(p->BufferLock);
  236. #ifndef TARGET_PALMOS
  237. if (Mode == HIBERNATE_HARD)
  238. {
  239. format_reader *Reader = p->Reader;
  240. filepos_t Seek = 0;
  241. if (Reader->InputBuffer)
  242. Seek += Reader->InputBuffer->Length;
  243. for (Buffer = Reader->BufferFirst;Buffer;Buffer = Buffer->Next)
  244. Seek += Buffer->Length;
  245. if (Seek && Reader->Input && Reader->Input->Seek(Reader->Input,-Seek,SEEK_CUR)>=0)
  246. {
  247. Reader->NoMoreInput = 0;
  248. if (Reader->InputBuffer)
  249. {
  250. Format_BufferRelease(p,Reader->InputBuffer);
  251. Reader->InputBuffer = NULL;
  252. }
  253. while ((Buffer = Format_BufferRemoveLast(Reader)) != NULL)
  254. Format_BufferRelease(p,Buffer);
  255. }
  256. }
  257. #endif
  258. while (p->FreeBuffers)
  259. {
  260. Buffer = p->FreeBuffers;
  261. p->FreeBuffers = Buffer->Next;
  262. FreeBlock(&Buffer->Block);
  263. free(Buffer);
  264. Changed = 1;
  265. }
  266. if (!Changed)
  267. for (No=0;No<MAXREADER;++No)
  268. for (Buffer = p->Reader[No].BufferFirst;Buffer;Buffer = Buffer->Next)
  269. if (SetHeapBlock(BLOCKSIZE,&Buffer->Block,HEAP_STORAGE))
  270. Changed = 1;
  271. LockLeave(p->BufferLock);
  272. LockLeave(p->InputLock);
  273. }
  274. return Changed ? ERR_NONE : ERR_OUT_OF_MEMORY;
  275. }
  276. static bool_t DropBuffer(format_base* p)
  277. {
  278. bool_t Dropped = 0;
  279. int No=0;
  280. for (No=0;No<p->StreamCount;++No)
  281. {
  282. format_stream* Stream = p->Streams[No];
  283. if (Stream->PacketFirst)
  284. {
  285. format_packet* Packet = Stream->PacketFirst;
  286. Stream->PacketFirst = Packet->Next;
  287. if (Stream->PacketLast == Packet)
  288. Stream->PacketLast = NULL;
  289. Format_PacketRelease(p,Packet);
  290. Stream->Pending = 0;
  291. Stream->State.DropLevel = 2;
  292. Stream->DropCount = DROP_SHOW;
  293. Dropped = 1;
  294. }
  295. }
  296. return Dropped;
  297. }
  298. format_buffer* Format_BufferAlloc(format_base* p,int Mode)
  299. {
  300. format_buffer* Buffer;
  301. retry:
  302. Buffer = p->FreeBuffers;
  303. if (!Buffer)
  304. {
  305. if (p->BufferUsed < p->BufferSize || Mode==2)
  306. {
  307. block Block;
  308. if (AllocBlock(BLOCKSIZE,&Block,Mode!=2,HEAP_ANY))
  309. {
  310. Buffer = (format_buffer*) malloc(sizeof(format_buffer));
  311. if (Buffer)
  312. Buffer->Block = Block;
  313. else
  314. FreeBlock(&Block);
  315. }
  316. }
  317. else
  318. if (Mode==0)
  319. return NULL;
  320. if (!Buffer)
  321. {
  322. if (Mode==1 && DropBuffer(p))
  323. goto retry;
  324. return NULL;
  325. }
  326. }
  327. else
  328. {
  329. assert(Buffer->RefCount==0);
  330. p->FreeBuffers = Buffer->Next;
  331. }
  332. Buffer->Length = 0;
  333. Buffer->Id = p->BufferId++;
  334. Buffer->RefCount = 1;
  335. Buffer->Next = NULL;
  336. ++p->BufferUsed;
  337. return Buffer;
  338. }
  339. static int SumByteRate(format_base* p)
  340. {
  341. // try to sum stream byterates
  342. int No;
  343. int ByteRate = 0;
  344. for (No=0;No<p->StreamCount;++No)
  345. {
  346. packetformat Format;
  347. p->Format.Get(p,(FORMAT_STREAM|PIN_FORMAT)+No,&Format,sizeof(Format));
  348. if (Format.ByteRate<=0)
  349. {
  350. if (p->Streams[No]->Pin.Node && p->ProcessTime == TIME_SYNC)
  351. {
  352. p->ProcessTime = 0;
  353. p->Process(p,p->Streams[No]); // try processing
  354. p->ProcessTime = TIME_SYNC;
  355. }
  356. p->Format.Get(p,(FORMAT_STREAM|PIN_FORMAT)+No,&Format,sizeof(Format));
  357. if (Format.ByteRate<=0)
  358. return p->SumByteRate; // failed
  359. }
  360. ByteRate += Format.ByteRate;
  361. }
  362. return ByteRate;
  363. }
  364. static bool_t IsVideo(format_base* p)
  365. {
  366. int No;
  367. for (No=0;No<p->StreamCount;++No)
  368. if (p->Streams[No]->Format.Type == PACKET_VIDEO)
  369. return 1;
  370. return 0;
  371. }
  372. static void FindCoverArt(format_base* p);
  373. static void CalcDuration(format_base* p)
  374. {
  375. if (p->Duration<0 && p->FileSize>=0)
  376. {
  377. if (p->TimeStamps)
  378. {
  379. // try to read the last packets and figure out Duration
  380. filepos_t SavePos;
  381. format_reader* Reader = p->Reader;
  382. LockEnter(p->InputLock);
  383. LockEnter(p->BufferLock);
  384. SavePos = Reader->Input->Seek(Reader->Input,0,SEEK_CUR);
  385. if (SavePos >= 0)
  386. {
  387. format_buffer* Buffer[ENDCHUNKS];
  388. int No,i;
  389. int Total = 0;
  390. tick_t Max=-1;
  391. format_reader Backup = *Reader;
  392. memset(Buffer,0,sizeof(Buffer));
  393. Reader->NoMoreInput = 1; //disable reading during ReadPacket
  394. for (No=0;No<ENDCHUNKS;++No)
  395. {
  396. filepos_t Pos = p->FileSize - (No+1)*BLOCKSIZE;
  397. if (Pos<0)
  398. {
  399. if (No)
  400. break;
  401. Pos = 0;
  402. }
  403. Buffer[No] = Format_BufferAlloc(p,2);
  404. if (!Buffer[No])
  405. break;
  406. if (Reader->Input->Seek(Reader->Input,Pos,SEEK_SET)<0)
  407. break;
  408. Buffer[No]->Length = Reader->Input->ReadBlock(Reader->Input,&Buffer[No]->Block,0,BLOCKSIZE);
  409. if (Buffer[No]->Length < 0)
  410. break;
  411. Total += Buffer[No]->Length;
  412. if (No)
  413. Buffer[No]->Next = Buffer[No-1];
  414. // setup temporary buffer
  415. Reader->InputBuffer = NULL;
  416. Reader->BufferAvailable = Total;
  417. Reader->BufferLast = Buffer[0];
  418. Reader->BufferFirst = Buffer[No];
  419. Reader->ReadPos = 0;
  420. Reader->ReadBuffer = NULL;
  421. Reader->FilePos = Pos;
  422. for (i=0;i<=No;++i)
  423. Buffer[i]->RefCount++;
  424. if (p->SeekByPacket_BlockAlign > 1)
  425. {
  426. int Rem = (Pos - p->SeekByPacket_DataStart) % p->SeekByPacket_BlockAlign;
  427. if (Rem)
  428. Reader->Skip(Reader,p->SeekByPacket_BlockAlign - Rem);
  429. }
  430. if (p->BackupPacketState)
  431. p->BackupPacketState(p,1);
  432. while (Reader->BufferLast || Reader->ReadBuffer)
  433. {
  434. int Result;
  435. format_packet* Packet = Format_PacketAlloc(p);
  436. if (!Packet)
  437. break;
  438. Result = p->ReadPacket(p,Reader,Packet);
  439. if (Result != ERR_NONE && Result != ERR_DATA_NOT_FOUND)
  440. {
  441. Reader->BufferLast = NULL;
  442. Reader->ReadBuffer = NULL;
  443. }
  444. else
  445. if (Result == ERR_NONE && Packet->Stream && Packet->RefTime>Max)
  446. Max = Packet->RefTime;
  447. Format_PacketRelease(p,Packet);
  448. }
  449. if (p->BackupPacketState)
  450. p->BackupPacketState(p,0);
  451. for (i=0;i<=No;++i)
  452. Buffer[i]->RefCount=1; // ugly
  453. if (Max >= 0)
  454. {
  455. p->Duration = Max;
  456. break;
  457. }
  458. }
  459. for (No=0;No<ENDCHUNKS;++No)
  460. if (Buffer[No])
  461. Format_BufferRelease(p,Buffer[No]);
  462. Reader->Input->Seek(Reader->Input,SavePos,SEEK_SET);
  463. *Reader = Backup;
  464. }
  465. LockLeave(p->BufferLock);
  466. LockLeave(p->InputLock);
  467. }
  468. if (p->StreamCount)
  469. {
  470. int ByteRate = SumByteRate(p);
  471. if (ByteRate>0)
  472. {
  473. tick_t Duration = Scale(p->FileSize,TICKSPERSEC,ByteRate);
  474. if (p->Duration<0 || p->Duration+3*TICKSPERSEC<Duration)
  475. {
  476. p->Duration = Duration;
  477. p->TimeStamps = 0;
  478. }
  479. }
  480. }
  481. }
  482. #if !defined(MULTITHREAD)
  483. if (IsVideo(p))
  484. p->AutoReadSize = 1; // force auto readsize
  485. #endif
  486. if (p->StreamCount && p->ProcessMinBuffer)
  487. {
  488. int ByteRate = SumByteRate(p);
  489. if (ByteRate<=0 && p->Duration>0)
  490. {
  491. int FileSize = p->FileSize;
  492. if (FileSize < 0 && p->Reader->Input)
  493. {
  494. LockEnter(p->InputLock);
  495. p->Reader->Input->Get(p->Reader->Input,STREAM_LENGTH,&FileSize,sizeof(FileSize));
  496. LockLeave(p->InputLock);
  497. }
  498. ByteRate = Scale(FileSize,TICKSPERSEC,p->Duration);
  499. }
  500. if (ByteRate>0)
  501. {
  502. while (ByteRate>p->ProcessMinBuffer*2 && p->ProcessMinBuffer < p->BufferSize*BLOCKSIZE/4)
  503. p->ProcessMinBuffer += BLOCKSIZE;
  504. if (p->AutoReadSize)
  505. {
  506. int No;
  507. int Rate = ByteRate / 16;
  508. // find video framerate
  509. for (No=0;No<p->StreamCount;++No)
  510. {
  511. packetformat Format;
  512. p->Format.Get(p,(FORMAT_STREAM|PIN_FORMAT)+No,&Format,sizeof(Format));
  513. if (Format.Type == PACKET_VIDEO && Format.PacketRate.Num>0)
  514. {
  515. Rate = Scale(ByteRate,Format.PacketRate.Den,Format.PacketRate.Num);
  516. break;
  517. }
  518. }
  519. p->ReadSize = 16384;
  520. while (p->ReadSize>1024 && Rate<5000)
  521. {
  522. Rate <<= 1;
  523. p->ReadSize >>= 1;
  524. }
  525. }
  526. }
  527. }
  528. #if defined(TARGET_SYMBIAN)
  529. if (p->ReadSize > 4096) // large reads interfere with audio (until multithreaded is not added...)
  530. p->ReadSize = 4096;
  531. #endif
  532. FindCoverArt(p);
  533. }
  534. void Format_BufferRelease(format_base* p, format_buffer* Buffer)
  535. {
  536. //DEBUG_MSG4(DEBUG_FORMAT,"Buffer:%d release %d->%d (%d)",Buffer->Id,Buffer->RefCount,Buffer->RefCount-1,p->BufferUsed);
  537. LockEnter(p->BufferLock);
  538. assert(Buffer->RefCount>0 && Buffer->RefCount<1000);
  539. if (--Buffer->RefCount <= 0)
  540. {
  541. assert(Buffer->RefCount==0);
  542. --p->BufferUsed;
  543. if (p->BufferUsed <= p->BufferSize)
  544. {
  545. Buffer->Next = p->FreeBuffers;
  546. p->FreeBuffers = Buffer;
  547. }
  548. else
  549. {
  550. FreeBlock(&Buffer->Block);
  551. free(Buffer);
  552. }
  553. }
  554. LockLeave(p->BufferLock);
  555. }
  556. format_buffer* Format_BufferRemove(format_reader* Reader)
  557. {
  558. format_buffer* Buffer;
  559. LockEnter(Reader->Format->BufferLock);
  560. Buffer = Reader->BufferFirst;
  561. if (Buffer)
  562. {
  563. Reader->BufferFirst = Buffer->Next;
  564. if (Reader->BufferLast == Buffer)
  565. Reader->BufferLast = NULL;
  566. Reader->BufferAvailable -= Buffer->Length;
  567. assert(Reader->BufferAvailable >= 0);
  568. }
  569. LockLeave(Reader->Format->BufferLock);
  570. return Buffer;
  571. }
  572. void Format_SingleRefRelease(format_base* p, format_ref* Ref)
  573. {
  574. if (Ref->Buffer)
  575. Format_BufferRelease(p,Ref->Buffer);
  576. Ref->Next = p->FreeRefs;
  577. p->FreeRefs = Ref;
  578. }
  579. void Format_ReleaseRef(format_base* p, format_ref* Ref)
  580. {
  581. while (Ref)
  582. {
  583. format_ref* Next = Ref->Next;
  584. Format_SingleRefRelease(p,Ref);
  585. Ref = Next;
  586. }
  587. }
  588. void Format_PacketRelease(format_base* p, format_packet* Packet)
  589. {
  590. Format_ReleaseRef(p,Packet->Data);
  591. Packet->Data = NULL;
  592. Packet->Next = p->FreePackets;
  593. p->FreePackets = Packet;
  594. }
  595. static NOINLINE void ReleaseStream(format_base* p,format_stream* Stream)
  596. {
  597. format_packet* Packet;
  598. Stream->State.DropLevel = 0;
  599. Stream->DropCount = 0;
  600. Stream->Pending = 0;
  601. Stream->LastTime = TIME_SYNC;
  602. while (Stream->PacketFirst)
  603. {
  604. Packet = Stream->PacketFirst;
  605. Stream->PacketFirst = Packet->Next;
  606. if (Stream->PacketLast == Packet)
  607. Stream->PacketLast = NULL;
  608. Format_PacketRelease(p,Packet);
  609. }
  610. if (p->ReleaseStream && Stream != p->SubTitle && Stream != p->CoverArt)
  611. p->ReleaseStream(p,Stream);
  612. }
  613. static int UpdateStreamPin(format_base* p,format_stream* Stream)
  614. {
  615. if (!Stream->Pin.Node)
  616. ReleaseStream(p,Stream);
  617. return ERR_NONE;
  618. }
  619. void Format_AfterSeek(format_base* p)
  620. {
  621. int No;
  622. // release stream packets
  623. for (No=0;No<p->StreamCount;++No)
  624. ReleaseStream(p,p->Streams[No]);
  625. if (p->SubTitle)
  626. ReleaseStream(p,p->SubTitle);
  627. p->LastRead = NULL;
  628. if (p->AfterSeek)
  629. p->AfterSeek(p);
  630. }
  631. void Format_ReleaseBuffers(format_reader* Reader)
  632. {
  633. format_buffer* Buffer;
  634. // release read buffers
  635. Reader->NoMoreInput = 0;
  636. Reader->ReadPos = 0;
  637. if (Reader->ReadBuffer)
  638. {
  639. Format_BufferRelease(Reader->Format,Reader->ReadBuffer);
  640. Reader->ReadBuffer = NULL;
  641. }
  642. if (Reader->InputBuffer)
  643. {
  644. Format_BufferRelease(Reader->Format,Reader->InputBuffer);
  645. Reader->InputBuffer = NULL;
  646. }
  647. while ((Buffer = Format_BufferRemove(Reader))!=NULL)
  648. Format_BufferRelease(Reader->Format,Buffer);
  649. }
  650. format_reader* Format_FindReader(format_base* p,filepos_t Min,filepos_t Max)
  651. {
  652. int No;
  653. filepos_t LimitMax;
  654. if (Max < Min+16)
  655. Max = Min+16;
  656. LimitMax = p->BufferSize*BLOCKSIZE/2;
  657. if (p->Duration>0)
  658. {
  659. // example a 55Mb/sec mjpeg with pcm audio can have large differences at end of file
  660. LimitMax = Scale(Max-Min,3*TICKSPERSEC,p->Duration);
  661. if (LimitMax < 512*1024)
  662. LimitMax = 512*1024;
  663. }
  664. for (No=0;No<MAXREADER;++No)
  665. {
  666. format_reader* Reader = p->Reader+No;
  667. filepos_t Limit = (Reader->OffsetMax - Reader->OffsetMin)/4;
  668. if (Limit<128*1024)
  669. Limit=128*1024;
  670. if (Limit>LimitMax)
  671. Limit=LimitMax;
  672. if (!Reader->OffsetMax ||
  673. (Reader->OffsetMin < Max && Reader->OffsetMax > Min && 
  674.  abs(Reader->OffsetMin-Min)<Limit && abs(Reader->OffsetMax-Max)<Limit))
  675. {
  676. stream* Orig = p->Reader[0].Input;
  677. if (Reader->OffsetMin > Min)
  678. Reader->OffsetMin = Min;
  679. if (Reader->OffsetMax < Max)
  680. Reader->OffsetMax = Max;
  681. Reader->Ratio = Scale(MAX_INT,1,Reader->OffsetMax - Reader->OffsetMin);
  682. if (!Reader->Input && Orig)
  683. {
  684. bool_t Silent = 1;
  685. tchar_t URL[MAXPATH];
  686. stream* Input;
  687. if (Orig->Get(Orig,STREAM_URL,URL,sizeof(URL)) != ERR_NONE)
  688. break;
  689. Input = (stream*)NodeCreate(Orig->Class);
  690. if (!Input)
  691. break;
  692. Input->Set(Input,STREAM_SILENT,&Silent,sizeof(bool_t));
  693. if (Input->Set(Input,STREAM_URL,URL,sizeof(URL))!=ERR_NONE)
  694. {
  695. NodeDelete((node*)Input);
  696. break;
  697. }
  698. Reader->ReadPos = 0;
  699. Reader->FilePos = 0;
  700. Reader->Input = Input;
  701. }
  702. return Reader;
  703. }
  704. }
  705. return NULL;
  706. }
  707. static NOINLINE void Format_FreeStream(format_base* p,format_stream* Stream)
  708. {
  709. PacketFormatClear(&Stream->Format);
  710. BufferClear(&Stream->BufferMem);
  711. FreeBlock(&Stream->BufferBlock);
  712. free(Stream);
  713. }
  714. int Format_Reset(format_base* p)
  715. {
  716. int Result = ERR_NONE;
  717. format_packet* Packet;
  718. format_buffer* Buffer;
  719. format_reader* Reader;
  720. format_ref* Ref;
  721. int No;
  722. if (p->BufferLock) // only if it was inited
  723. {
  724. Format_AfterSeek(p);
  725. for (No=0;No<MAXREADER;++No)
  726. Format_ReleaseBuffers(p->Reader+No);
  727. }
  728. if (p->ReleaseStreams.Func)
  729. p->ReleaseStreams.Func(p->ReleaseStreams.This,0,0);
  730. if (p->Done)
  731. p->Done(p);
  732. while (p->StreamCount)
  733. Format_RemoveStream(p);
  734. while (p->FreePackets)
  735. {
  736. Packet = p->FreePackets;
  737. p->FreePackets = Packet->Next;
  738. free(Packet);
  739. }
  740. while (p->FreeBuffers)
  741. {
  742. Buffer = p->FreeBuffers;
  743. p->FreeBuffers = Buffer->Next;
  744. FreeBlock(&Buffer->Block);
  745. free(Buffer);
  746. }
  747. while (p->FreeRefs)
  748. {
  749. Ref = p->FreeRefs;
  750. p->FreeRefs = Ref->Next;
  751. free(Ref);
  752. }
  753. if (p->SubTitle)
  754. {
  755. Format_FreeSubTitle(p,p->SubTitle);
  756. p->SubTitle = NULL;
  757. }
  758. if (p->CoverArt)
  759. {
  760. Format_FreeStream(p,p->CoverArt);
  761. p->CoverArt = NULL;
  762. }
  763. p->TotalCount = 0;
  764. p->StreamCount = 0;
  765. p->ActiveStreams = 0;
  766. LockDelete(p->BufferLock);
  767. LockDelete(p->InputLock);
  768. p->BufferLock = NULL;
  769. p->InputLock = NULL;
  770. p->LastRead = NULL;
  771. for (No=0;No<MAXREADER;++No)
  772. {
  773. Reader = p->Reader+No;
  774. if (No>0 && Reader->Input)
  775. {
  776. Reader->Input->Set(Reader->Input,STREAM_URL,NULL,0);
  777. NodeDelete((node*)Reader->Input);
  778. Reader->Input = NULL;
  779. }
  780. Reader->Ratio = -1;
  781. Reader->OffsetMin = MAX_INT;
  782. Reader->OffsetMax = 0;
  783. Reader->Current = NULL;
  784. Reader->OutOfSync = 0;
  785. }
  786. Reader = p->Reader;
  787. if (Reader->Input)
  788. {
  789. if (!NodeIsClass(Reader->Input->Class,STREAM_CLASS) &&
  790. !NodeIsClass(Reader->Input->Class,STREAMPROCESS_CLASS))
  791. return ERR_INVALID_PARAM;
  792. if (Reader->Input->Get(Reader->Input,STREAM_LENGTH,&p->FileSize,sizeof(p->FileSize)) != ERR_NONE)
  793. p->FileSize = -1;
  794. p->InputLock = LockCreate();
  795. p->BufferLock = LockCreate();
  796. p->Duration = TIME_UNKNOWN;
  797. p->FirstSync = 1;
  798. p->SyncMode = 1; // start with syncmode
  799. p->SyncTime = TIME_SYNC;
  800. p->SyncStream = NULL;
  801. p->HeaderLoaded = 0;
  802. p->ProcessMinBuffer = PROCESSMINVIDEO;
  803. p->ReadSize = 16384;
  804. p->GlobalOffset = 0;
  805. p->SumByteRate = 0;
  806. Reader->FilePos = 0;
  807. Reader->NoMoreInput = 0;
  808. p->SeekByPacket_DataStart = 0;
  809. p->SeekByPacket_BlockAlign = 1;
  810. if (p->Init)
  811. {
  812. Result = p->Init(p);
  813. if (Result != ERR_NONE)
  814. {
  815. Reader->Input = NULL;
  816. Format_Reset(p);
  817. }
  818. else
  819. p->SyncRead = SYNCREAD;
  820. }
  821. }
  822. return Result;
  823. }
  824. int FormatBaseGet(format_base* p,int No,void* Data,int Size)
  825. {
  826. int Result = ERR_INVALID_PARAM;
  827. if (No >= FORMAT_COMMENT && No < FORMAT_COMMENT+p->TotalCount)  
  828. GETVALUE(p->Streams[No-FORMAT_COMMENT]->Comment,pin)
  829. else
  830. if (No >= FORMAT_STREAM && No < FORMAT_STREAM+p->TotalCount)
  831. GETVALUE(p->Streams[No-FORMAT_STREAM]->Pin,pin)
  832. else
  833. if (No >= FORMAT_STREAM_PRIORITY && No < FORMAT_STREAM_PRIORITY+p->TotalCount)
  834. GETVALUE(p->Streams[No-FORMAT_STREAM_PRIORITY]->Priority,int)
  835. else
  836. if (No >= (FORMAT_STREAM|PIN_PROCESS) && No < (FORMAT_STREAM|PIN_PROCESS)+p->TotalCount)
  837. GETVALUE(p->Streams[No-(FORMAT_STREAM|PIN_PROCESS)]->Process,packetprocess)
  838. else
  839. if (No >= (FORMAT_STREAM|PIN_FORMAT) && No < (FORMAT_STREAM|PIN_FORMAT)+p->TotalCount)
  840. {
  841. packetformat CodecFormat;
  842. format_stream* s = p->Streams[No-(FORMAT_STREAM|PIN_FORMAT)];
  843. assert(Size == sizeof(packetformat));
  844. if (s->Pin.Node && s->Pin.Node->Get(s->Pin.Node,s->Pin.No|PIN_FORMAT,&CodecFormat,sizeof(CodecFormat))==ERR_NONE)
  845. PacketFormatCombine(&s->Format,&CodecFormat);
  846. *(packetformat*)Data = s->Format;
  847. Result = ERR_NONE;
  848. }
  849. else
  850. switch (No)
  851. {
  852. case FORMAT_BUFFERSIZE: GETVALUE(p->BufferSize,int); break;
  853. case FORMAT_INPUT: GETVALUE(p->Reader[0].Input,stream*); break;
  854. case FORMAT_DURATION: GETVALUECOND(p->Duration,tick_t,p->Duration>=0); break;
  855. case FORMAT_FILEPOS: GETVALUECOND(p->Reader[0].FilePos,int,p->Timing && p->Reader[0].FilePos>=0); break;
  856. case FORMAT_FILEALIGN: GETVALUE(p->FileAlign,int); break;
  857. case FORMAT_STREAM_COUNT: GETVALUE(p->TotalCount,int); break;
  858. case FORMAT_FILESIZE: GETVALUECOND(p->FileSize/1024,int,p->FileSize>=0); break;
  859. case FORMAT_FIND_SUBTITLES: GETVALUE(p->NeedSubtitles,bool_t); break;
  860. case FORMAT_GLOBAL_COMMENT: GETVALUE(p->Comment,pin); break;
  861. case FORMAT_AUTO_READSIZE: GETVALUE(p->AutoReadSize,bool_t); break;
  862. case FORMAT_TIMING: GETVALUE(p->Timing,bool_t); break;
  863. case FORMAT_COVERART: GETVALUECOND(p->StreamCount+(p->SubTitle!=NULL),int,p->CoverArt!=NULL); break;
  864. case FORMAT_MIN_BUFFER: GETVALUE(p->ProcessMinBuffer/BLOCKSIZE,int); break;
  865. }
  866. return Result;
  867. }
  868. int FormatBaseSet(format_base* p,int No,const void* Data,int Size)
  869. {
  870. node* Advanced;
  871. uint8_t* Ptr;
  872. int Result = ERR_INVALID_PARAM;
  873. if (No >= FORMAT_COMMENT && No < FORMAT_COMMENT+p->TotalCount)
  874. SETVALUE(p->Streams[No-FORMAT_COMMENT]->Comment,pin,ERR_NONE)
  875. else
  876. if (No >= FORMAT_STREAM && No < FORMAT_STREAM+p->TotalCount)
  877. {
  878. format_stream* s = p->Streams[No-FORMAT_STREAM];
  879. if (s->Pin.Node && No-FORMAT_STREAM<p->StreamCount) p->ActiveStreams--;
  880. SETVALUE(s->Pin,pin,UpdateStreamPin(p,s));
  881. if (s->Pin.Node && No-FORMAT_STREAM<p->StreamCount) p->ActiveStreams++;
  882. }
  883. else
  884. if (No >= (FORMAT_STREAM|PIN_PROCESS) && No < (FORMAT_STREAM|PIN_PROCESS)+p->TotalCount)
  885. SETVALUE(p->Streams[No-(FORMAT_STREAM|PIN_PROCESS)]->Process,packetprocess,ERR_NONE)
  886. else
  887. switch (No)
  888. {
  889. case FORMAT_INPUT: SETVALUENULL(p->Reader[0].Input,stream*,Format_Reset(p),p->Reader[0].Input=NULL); break;
  890. case FORMAT_UPDATESTREAMS: SETVALUE(p->UpdateStreams,notify,ERR_NONE); break;
  891. case FORMAT_RELEASESTREAMS: SETVALUE(p->ReleaseStreams,notify,ERR_NONE); break;
  892. case FORMAT_FIND_SUBTITLES: SETVALUE(p->NeedSubtitles,bool_t,ERR_NONE); break;
  893. case FORMAT_GLOBAL_COMMENT: SETVALUE(p->Comment,pin,ERR_NONE); break;
  894. case FORMAT_FILEALIGN: SETVALUE(p->FileAlign,int,ERR_NONE); break;
  895. case FORMAT_AUTO_READSIZE: SETVALUE(p->AutoReadSize,bool_t,ERR_NONE); break;
  896. case NODE_HIBERNATE:
  897. assert(Size == sizeof(int));
  898. Result = Format_Hibernate(p,*(int*)Data);
  899. break;
  900. case NODE_SETTINGSCHANGED:
  901. Advanced = Context()->Advanced;
  902. if (Advanced)
  903. {
  904. Advanced->Get(Advanced,ADVANCED_DROPTOL,&p->DropTolerance,sizeof(tick_t));
  905. Advanced->Get(Advanced,ADVANCED_SKIPTOL,&p->SkipTolerance,sizeof(tick_t));
  906. Advanced->Get(Advanced,ADVANCED_AVOFFSET,&p->AVOffset,sizeof(tick_t));
  907. }
  908. break;
  909. case FORMAT_DATAFEED:
  910. Ptr = (uint8_t*) Data;
  911. while (Size)
  912. {
  913. format_buffer* Buffer;
  914. Buffer = Format_BufferAlloc(p,2);
  915. if (Buffer)
  916. {
  917. Buffer->Length = Size;
  918. if (Buffer->Length > BLOCKSIZE)
  919. Buffer->Length = BLOCKSIZE;
  920. WriteBlock(&Buffer->Block,0,Ptr,Buffer->Length);
  921. Ptr += Buffer->Length;
  922. Size -= Buffer->Length;
  923. Format_BufferInsert(p->Reader,Buffer);
  924. }
  925. }
  926. break;
  927. case FORMAT_BUFFERSIZE: SETVALUE(p->BufferSize,int,ERR_NONE); break;
  928. }
  929. return Result;
  930. }
  931. format_packet* Format_PacketAlloc(format_base* p)
  932. {
  933. format_packet* Packet = p->FreePackets;
  934. if (!Packet)
  935. {
  936. Packet = (format_packet*) malloc(sizeof(format_packet));
  937. if (!Packet)
  938. return NULL;
  939. }
  940. else
  941. p->FreePackets = Packet->Next;
  942. Packet->Data = NULL;
  943. Packet->RefTime = TIME_UNKNOWN;
  944. Packet->EndRefTime = TIME_UNKNOWN;
  945. Packet->Stream = NULL;
  946. Packet->Next = NULL;
  947. Packet->Key = 1;
  948. return Packet;
  949. }
  950. static int Format_Sync(format_base* p,tick_t Time,int FilePos,bool_t PrevKey)
  951. {
  952. if (!p->Seek || !p->Reader[0].Input)
  953. return ERR_NOT_SUPPORTED;
  954. if (!p->HeaderLoaded)
  955. return ERR_LOADING_HEADER;
  956. p->SyncMode = 1;
  957. p->SyncRead = SYNCREAD;
  958. p->SyncTime = TIME_SYNC; // set before p->Seek
  959. p->SyncStream = NULL;
  960. if (Time>=0 || FilePos>=0)
  961. {
  962. int Result = p->Seek(p,Time,FilePos,PrevKey);
  963. if (Result != ERR_NONE)
  964. {
  965. p->SyncMode = 0;
  966. return Result;
  967. }
  968. }
  969. return ERR_NONE;
  970. }
  971. int Format_CheckEof(format_base* p,format_stream* Stream)
  972. {
  973. int Result;
  974. if (!p->Timing && p->ProcessTime>=0 && p->ProcessTime<5*TICKSPERSEC)
  975. return ERR_BUFFER_FULL;
  976. Stream->State.CurrTime = p->ProcessTime;
  977. Stream->State.DropLevel = 0;
  978. Result = Stream->Process(Stream->Pin.Node,NULL,&Stream->State);
  979. if (Result != ERR_BUFFER_FULL)
  980. Result = ERR_END_OF_FILE;
  981. return Result;
  982. }
  983. static NOINLINE int Synced(format_base* p,format_stream* Stream)
  984. {
  985. p->SyncMode = 0;
  986. if (p->SyncTime == TIME_SYNC)
  987. {
  988. p->SyncTime = Stream->Packet.RefTime;
  989. if (p->SyncTime < 0)
  990. p->SyncTime = Stream->LastTime;
  991. }
  992. if (p->FirstSync)
  993. {
  994. // some codecs may need the first few packets as headers
  995. int No;
  996. p->ProcessTime = 0;
  997. for (No=0;No<p->StreamCount;++No)
  998. if (p->Streams[No]->Pin.Node && p->Streams[No]->PacketFirst)
  999. p->Process(p,p->Streams[No]); // try processing
  1000. p->ProcessTime = TIME_SYNC;
  1001. }
  1002. return ERR_SYNCED;
  1003. }
  1004. int Format_Send(format_base* p,format_stream* Stream)
  1005. {
  1006. int Result;
  1007. tick_t CurrTime = p->ProcessTime;
  1008. Stream->State.CurrTime = CurrTime;
  1009. if (Stream->Packet.RefTime >= 0 && !Stream->DisableDrop)
  1010. {
  1011. Stream->State.DropLevel = 0;
  1012. if (CurrTime >= 0)
  1013. {
  1014. tick_t Diff = CurrTime - Stream->Packet.RefTime;
  1015. if (Diff < -TICKSPERSEC/2 && Stream->Format.Type == PACKET_VIDEO)
  1016. {
  1017. // make sure buffers and pending packets are processed
  1018. Stream->Process(Stream->Pin.Node,NULL,&Stream->State);
  1019. return ERR_BUFFER_FULL;
  1020. }
  1021. if (Diff > p->DropTolerance)
  1022. {
  1023. if (Diff > p->SkipTolerance + p->DropTolerance)
  1024. {
  1025. Stream->State.DropLevel = 2;
  1026. Stream->DropCount = DROP_SHOW;
  1027. }
  1028. else
  1029. {
  1030. if (!Stream->State.DropLevel)
  1031. Stream->DropCount = 0;
  1032. if (Stream->DropCount >= DROP_SHOW)
  1033. {
  1034. Stream->State.DropLevel = 0; // show one packet
  1035. Stream->DropCount = 0;
  1036. }
  1037. else
  1038. {
  1039. Stream->State.DropLevel = 1;
  1040. ++Stream->DropCount;
  1041. }
  1042. }
  1043. }
  1044. }
  1045. }
  1046. DEBUG_MSG5(DEBUG_FORMAT,T("Send stream:%d size:%d time:%d curr:%d drop:%d"),Stream->No,Stream->Packet.Length,Stream->Packet.RefTime,CurrTime,Stream->State.DropLevel);
  1047. Result = Stream->Process(Stream->Pin.Node,&Stream->Packet,&Stream->State);
  1048. // packet not processed?
  1049. if (Result == ERR_BUFFER_FULL)
  1050. {
  1051. DEBUG_MSG1(DEBUG_FORMAT,T("Send stream:%d BufferFull"),Stream->No);
  1052. return Result;
  1053. }
  1054. if (p->Sended)
  1055. p->Sended(p,Stream);
  1056. Stream->Pending = 0;
  1057. // sync: found a valid frame?
  1058. if (p->SyncMode && (Result == ERR_NONE || Result == ERR_NOT_SUPPORTED))
  1059. Result = Synced(p,Stream);
  1060. return Result;
  1061. }
  1062. void Format_TimeStampRestarted(format_base* p,format_stream* Stream,tick_t* RefTime)
  1063. {
  1064. if (!p->InSeek)
  1065. {
  1066. format_packet* i;
  1067. *RefTime -= p->GlobalOffset;
  1068. p->GlobalOffset = Stream->LastTime; // last processed time
  1069. for (i=Stream->PacketFirst;i;i=i->Next)
  1070. if (i->RefTime>=0)
  1071. p->GlobalOffset = i->RefTime; // last packet time
  1072. *RefTime += p->GlobalOffset;
  1073. p->TimeStamps = 0;
  1074. }
  1075. }
  1076. int Format_FillQueue(format_base* p,format_reader* Reader)
  1077. {
  1078. int Result;
  1079. format_packet* Packet;
  1080. if (!Reader->BufferAvailable && !Reader->ReadBuffer && p->ProcessMinBuffer!=0 &&
  1081. (!p->SyncMode || p->SyncRead<=0 || Reader->NoMoreInput))
  1082. return ERR_NEED_MORE_DATA;
  1083. Packet = Format_PacketAlloc(p);
  1084. if (!Packet)
  1085. return ERR_OUT_OF_MEMORY;
  1086. Result = p->ReadPacket(p,Reader,Packet);
  1087. if (Result == ERR_NONE && Packet->Stream && Packet->Stream->Pin.Node)
  1088. {
  1089. format_stream* s = Packet->Stream;
  1090. if (Packet->RefTime>=0)
  1091. {
  1092. Packet->RefTime += p->GlobalOffset;
  1093. if (s->Format.Type == PACKET_AUDIO)
  1094. {
  1095. Packet->RefTime += p->AVOffset;
  1096. if (Packet->RefTime < 0)
  1097. Packet->RefTime = 0;
  1098. }
  1099. if (s->LastTime<0)
  1100. s->LastTime = Packet->RefTime; // found reftime
  1101. else
  1102. if (s->LastTime > Packet->RefTime+TICKSPERSEC  && Packet->RefTime-p->GlobalOffset<TICKSPERSEC)
  1103. Format_TimeStampRestarted(p,s,&Packet->RefTime);
  1104. }
  1105. if (s->LastTime >= TIME_UNKNOWN)
  1106. {
  1107. // add packet to stream
  1108. if (!s->PacketFirst)
  1109. s->PacketFirst = Packet;
  1110. else
  1111. s->PacketLast->Next = Packet;
  1112. s->PacketLast = Packet;
  1113. if (Packet->EndRefTime>=0 && s->Format.Type == PACKET_SUBTITLE)
  1114. {
  1115. // add empty packet
  1116. format_packet* Tail = Format_PacketAlloc(p);
  1117. if (Tail)
  1118. {
  1119. Tail->Stream = Packet->Stream;
  1120. Tail->RefTime = Packet->EndRefTime;
  1121. if (!s->PacketFirst)
  1122. s->PacketFirst = Tail;
  1123. else
  1124. s->PacketLast->Next = Tail;
  1125. s->PacketLast = Tail;
  1126. }
  1127. }
  1128. }
  1129. else
  1130. Format_PacketRelease(p,Packet);
  1131. }
  1132. else
  1133. Format_PacketRelease(p,Packet);
  1134. return Result;
  1135. }
  1136. NOINLINE bool_t Format_AllocBufferBlock(format_base* p,format_stream* Stream,int Size)
  1137. {
  1138. FreeBlock(&Stream->BufferBlock);
  1139. if (Size>0)
  1140. {
  1141. Size = (Size + SAFETAIL + 0x7FFF) & ~0x7FFF;
  1142. if (AllocBlock(Size,&Stream->BufferBlock,0,HEAP_STORAGE))
  1143. Size -= SAFETAIL;
  1144. else
  1145. Size = 0;
  1146. }
  1147. Stream->BufferBlockLength = Size;
  1148. return Size>0;
  1149. }
  1150. /*
  1151. static bool_t ReleasePacket(format_base* p)
  1152. {
  1153. int No;
  1154. format_stream* Min = NULL;
  1155. tick_t MinTime = MAX_TICK;
  1156. for (No=0;No<p->StreamCount;++No)
  1157. {
  1158. format_stream* Stream = p->Streams[No];
  1159. if (Stream->PacketFirst && Stream->PacketFirst->RefTime < MinTime)
  1160. {
  1161. Min = Stream;
  1162. MinTime = Stream->PacketFirst->RefTime;
  1163. }
  1164. }
  1165. if (Min)
  1166. {
  1167. format_packet* Packet = Min->PacketFirst;
  1168. Min->PacketFirst = Packet->Next;
  1169. if (Min->PacketLast == Packet)
  1170. Min->PacketLast = NULL;
  1171. Format_PacketRelease(p,Packet);
  1172. return 1;
  1173. }
  1174. return 0;
  1175. }
  1176. */
  1177. static int Format_ProcessStream(format_base* p,format_stream* Stream)
  1178. {
  1179. format_packet* Packet;
  1180. format_ref* Ref;
  1181. int Result = ERR_NONE;
  1182. int No;
  1183. int Burst;
  1184. if (Stream->Pending)
  1185. {
  1186. Result = Format_Send(p,Stream);
  1187. if (Result == ERR_BUFFER_FULL || Result == ERR_SYNCED)
  1188. {
  1189. if (p->SyncMode && Stream == p->SyncStream) // can happen when sync without seek 
  1190. Result = Synced(p,Stream);
  1191. return Result;
  1192. }
  1193. }
  1194. // process a limited number of packets at once (other streams need cpu time too)
  1195. Burst = Stream->PacketBurst;
  1196. for (No=0;No<Burst;++No)
  1197. {
  1198. while (!Stream->PacketFirst)
  1199. {
  1200. format_reader* Reader = Stream->Reader;
  1201. /*
  1202. if (p->BufferUsed >= p->BufferSize && p->SyncMode && Stream == p->SyncStream)
  1203. {
  1204. // try dropping other stream packets to make buffer for sync stream
  1205. while (p->BufferUsed >= p->BufferSize)
  1206. if (!ReleasePacket(p))
  1207. break;
  1208. }
  1209. */
  1210. // prevent audio from going too much ahead
  1211. if (Reader->BufferAvailable < p->ProcessMinBuffer && !Reader->NoMoreInput && 
  1212. (!p->SyncMode || p->SyncRead<=0 || Stream != p->SyncStream))
  1213. return ERR_NEED_MORE_DATA;
  1214. Result = Format_FillQueue(p,Reader);
  1215. if (Reader->NoMoreInput && (Result == ERR_END_OF_FILE || Result == ERR_NEED_MORE_DATA))
  1216. Result = Format_CheckEof(p,Stream);
  1217. if (Result != ERR_NONE || (p->Bench && (No || !Stream->PacketFirst)))
  1218. return Result;
  1219. }
  1220. Packet = Stream->PacketFirst;
  1221. // sync: all non SyncStream packets are stored (or dropped)
  1222. if (p->SyncMode && Stream != p->SyncStream && p->SyncStream)
  1223. {
  1224. // catch up to syncstream (drop packets)
  1225. tick_t LastTime = p->SyncStream->LastTime;
  1226. if (p->SyncStream->Fragmented)
  1227. LastTime -= TICKSPERSEC/2; // LastTime may not be the correct sync time
  1228. while (Packet && Packet->RefTime < LastTime)
  1229. {
  1230. Stream->PacketFirst = Packet->Next;
  1231. if (Stream->PacketLast == Packet)
  1232. Stream->PacketLast = NULL;
  1233. Format_PacketRelease(p,Packet);
  1234. Packet = Stream->PacketFirst;
  1235. }
  1236. return ERR_NEED_MORE_DATA; // allow SyncStream to need more data
  1237. }
  1238. //DEBUG_MSG3(DEBUG_FORMAT,T("Packet stream:%d time:%d pos:%d"),Stream->No,Packet->RefTime,Packet->FilePos);
  1239. // build output packet
  1240. if (Packet->RefTime >= 0)
  1241. Stream->LastTime = Packet->RefTime;
  1242. Stream->Packet.RefTime = Packet->RefTime;
  1243. Stream->Packet.Key = Packet->Key;
  1244. Ref = Packet->Data;
  1245. if (!Ref)
  1246. {
  1247. Stream->Packet.Data[0] = NULL;
  1248. Stream->Packet.Length = 0;
  1249. Stream->Pending = 1;
  1250. }
  1251. else
  1252. if (!Stream->Fragmented)
  1253. {
  1254. if (Ref->Next || (Ref->Length + Ref->Begin + SAFETAIL > BLOCKSIZE) || Stream->ForceMerge)
  1255. {
  1256. // merge references
  1257. if (p->UseBufferBlock)
  1258. {
  1259. int Total = 0;
  1260. format_ref* i;
  1261. for (Total=0,i=Ref;i;i=i->Next)
  1262. Total += i->Length;
  1263. if (Stream->BufferBlockLength < Total && !Format_AllocBufferBlock(p,Stream,Total))
  1264. Ref = NULL;
  1265. for (Total=0,i=Ref;i;i=i->Next)
  1266. {
  1267. WriteBlock(&Stream->BufferBlock,Total,i->Buffer->Block.Ptr + i->Begin,i->Length);
  1268. Total += i->Length;
  1269. }
  1270. Stream->Packet.Data[0] = Stream->BufferBlock.Ptr;
  1271. Stream->Packet.Length = Total;
  1272. }
  1273. else
  1274. {
  1275. BufferDrop(&Stream->BufferMem);
  1276. for (;Ref;Ref=Ref->Next)
  1277. BufferWrite(&Stream->BufferMem,Ref->Buffer->Block.Ptr + Ref->Begin, Ref->Length,16384);
  1278. Stream->Packet.Data[0] = Stream->BufferMem.Data;
  1279. Stream->Packet.Length = Stream->BufferMem.WritePos;
  1280. }
  1281. }
  1282. else
  1283. {
  1284. // single reference
  1285. Stream->Packet.Data[0] = Ref->Buffer->Block.Ptr + Ref->Begin;
  1286. Stream->Packet.Length = Ref->Length;
  1287. }
  1288. Stream->Pending = 1;
  1289. }
  1290. else
  1291. {
  1292. // send first reference (doesn't matter how long)
  1293. Stream->Packet.Data[0] = Ref->Buffer->Block.Ptr + Ref->Begin;
  1294. Stream->Packet.Length = Ref->Length;
  1295. Stream->Pending = 2; // indicate parital sending
  1296. }
  1297. Result = Format_Send(p,Stream);
  1298. if (Result == ERR_BUFFER_FULL || Result == ERR_SYNCED)
  1299. break;
  1300. if (Stream->State.DropLevel==2 && Stream->PacketFirst && Burst<10 && No==Burst-1)
  1301. ++Burst; // try to catch up
  1302. }
  1303. // buffer full: there was possibly some processing so don't allow sleeping
  1304. // need data: burst count exceeded, but it doesn't mean there is no data left in buffers
  1305. if (Result == ERR_BUFFER_FULL || Result == ERR_NEED_MORE_DATA)
  1306. Result = ERR_NONE;
  1307. return Result;
  1308. }
  1309. static void Format_Sended(format_base* p, format_stream* Stream)
  1310. {
  1311. format_packet* Packet = Stream->PacketFirst;
  1312. if (Packet)
  1313. {
  1314. if (Stream->Pending == 2 && Packet->Data)
  1315. {
  1316. // release sended references
  1317. format_ref* Ref = Packet->Data;
  1318. Packet->Data = Ref->Next;
  1319. Format_SingleRefRelease(p,Ref);
  1320. if (Packet->Data)
  1321. {
  1322. // packet still not finished
  1323. Packet->RefTime = TIME_UNKNOWN;
  1324. return;
  1325. }
  1326. }
  1327. // full packet is released
  1328. Stream->PacketFirst = Packet->Next;
  1329. if (Stream->PacketLast == Packet)
  1330. Stream->PacketLast = NULL;
  1331. Format_PacketRelease(p,Packet);
  1332. }
  1333. }
  1334. NOINLINE format_stream* Format_DefSyncStream(format_base* p, format_reader* Reader)
  1335. {
  1336. format_stream* Found = NULL;
  1337. format_stream* Stream;
  1338. int No;
  1339. // prefer video streams
  1340. for (No=0;No<p->StreamCount;++No)
  1341. {
  1342. Stream = p->Streams[No];
  1343. if (Stream->Pin.Node && (!Reader || Stream->Reader==Reader))
  1344. {
  1345. if (Stream->Format.Type == PACKET_VIDEO)
  1346. return Stream;
  1347. if (!Found)
  1348. Found = Stream;
  1349. }
  1350. }
  1351. return Found;
  1352. }
  1353. static bool_t TryReSend(node* p)
  1354. {
  1355. if (p)
  1356. {
  1357. bool_t Buffered;
  1358. if (p->Get(p,FLOW_BUFFERED,&Buffered,sizeof(Buffered))==ERR_NONE && Buffered)
  1359. return p->Set(p,FLOW_RESEND,NULL,0) == ERR_NONE;
  1360. if (!NodeIsClass(p->Class,OUT_CLASS))
  1361. {
  1362. pin Pin;
  1363. node* Node;
  1364. datadef DataDef;
  1365. int No;
  1366. for (No=0;NodeEnum(p,No,&DataDef)==ERR_NONE;++No)
  1367. if (DataDef.Flags & DF_OUTPUT)
  1368. {
  1369. switch (DataDef.Type)
  1370. {
  1371. case TYPE_NODE:
  1372. if (p->Get(p,DataDef.No,&Node,sizeof(Node))==ERR_NONE && TryReSend(Node))
  1373. return 1;
  1374. break;
  1375. case TYPE_PACKET:
  1376. if (p->Get(p,DataDef.No,&Pin,sizeof(Pin))==ERR_NONE && TryReSend(Pin.Node))
  1377. return 1;
  1378. break;
  1379. }
  1380. }
  1381. }
  1382. }
  1383. return 0;
  1384. }
  1385. static int DummyError(void* This,int Param,int Param2)
  1386. {
  1387. return ERR_NONE;
  1388. }
  1389. static NOINLINE int ProcessCoverArt(format_base* p,format_stream* Stream)
  1390. {
  1391. int Result;
  1392. notify Error;
  1393. context* c = Context();
  1394. node* Node = Stream->Pin.Node;
  1395. if (!Node)
  1396. return ERR_NONE;
  1397. if (TryReSend(Node))
  1398. return ERR_NONE;
  1399. // suppress covert art decoding error messages
  1400. Error = c->Error;
  1401. c->Error.Func = DummyError;
  1402. Stream->State.CurrTime = TIME_SYNC;
  1403. Stream->State.DropLevel = 0;
  1404. Result = Stream->Process(Node,&Stream->Packet,&Stream->State);
  1405. c->Error = Error;
  1406. return Result;
  1407. }
  1408. static int Format_Process(format_base* p,processstate* State)
  1409. {
  1410. int No;
  1411. int Result;
  1412. int AllNeedMoreData = 1;
  1413. int AllEndOfFile = 1;
  1414. assert(State->Time>=0 || State->Time == TIME_BENCH);
  1415. State->BufferUsedBefore = p->BufferUsed;
  1416. p->ProcessTime = State->Time;
  1417. p->Bench = p->ProcessTime < 0;
  1418. if (!p->HeaderLoaded)
  1419. {
  1420. // load format begining to find streams
  1421. format_reader* Reader = p->Reader;
  1422. Result = p->FillQueue(p,Reader);
  1423. if (Reader->FilePos > HEADERLOAD || (p->StreamCount && Reader->FilePos > p->MinHeaderLoad) || Reader->Eof(Reader))
  1424. p->HeaderLoaded = 1;
  1425. State->BufferUsedAfter = p->BufferUsed;
  1426. return Result;
  1427. }
  1428. if (p->SyncMode)
  1429. {
  1430. p->ProcessTime = TIME_SYNC;
  1431. // we need to choose one stream (to find a non dropped frame)
  1432. if (!p->SyncStream)
  1433. {
  1434. p->SyncStream = Format_DefSyncStream(p,NULL);
  1435. if (!p->SyncStream)
  1436. {
  1437. // no sync needed
  1438. p->SyncMode = 0;
  1439. // try to calc duration once (after first sync)
  1440. if (p->FirstSync)
  1441. {
  1442. p->FirstSync = 0;
  1443. CalcDuration(p);
  1444. }
  1445. if (p->CoverArt)
  1446. ProcessCoverArt(p,p->CoverArt);
  1447. // leave time as it is
  1448. State->BufferUsedAfter = p->BufferUsed;
  1449. return ERR_SYNCED;
  1450. }
  1451. }
  1452. }
  1453. // if all streams are full: caller can go to sleep
  1454. Result = ERR_BUFFER_FULL;
  1455. if (p->SubTitle)
  1456. Format_ProcessSubTitle(p,p->SubTitle);
  1457. for (No=0;No<p->StreamCount;++No)
  1458. {
  1459. format_stream* Stream = p->Streams[No];
  1460. if (Stream->Pin.Node)
  1461. {
  1462. int i = p->Process(p,Stream);
  1463. if (!p->SyncMode || p->SyncStream == Stream)
  1464. {
  1465. if (i == ERR_NEED_MORE_DATA)
  1466. {
  1467. if (!Stream->Reader->NoMoreInput && Stream->Format.Type != PACKET_SUBTITLE)
  1468. {
  1469. // if less then 1/8 sec is left and stream needs data -> force need more data mode
  1470. tick_t LastTime = Stream->LastTime;
  1471. if (State->Fill || (LastTime >= 0 && p->ProcessTime >= 0 && LastTime < p->ProcessTime + TICKSPERSEC/8))
  1472. Result = ERR_NEED_MORE_DATA;
  1473. }
  1474. }
  1475. else
  1476. AllNeedMoreData = 0;
  1477. if (i != ERR_END_OF_FILE)
  1478. AllEndOfFile = 0;
  1479. }
  1480. if (i == ERR_SYNCED)
  1481. {
  1482. // try to calc duration once (after first sync)
  1483. if (p->FirstSync)
  1484. {
  1485. p->FirstSync = 0;
  1486. CalcDuration(p);
  1487. }
  1488. if (p->CoverArt)
  1489. ProcessCoverArt(p,p->CoverArt);
  1490. State->Time = p->SyncTime;
  1491. State->BufferUsedAfter = p->BufferUsed;
  1492. return i;
  1493. }
  1494. if (Result == ERR_BUFFER_FULL &&
  1495. i != ERR_BUFFER_FULL && 
  1496. i != ERR_END_OF_FILE && 
  1497. i != ERR_NEED_MORE_DATA)
  1498. Result = ERR_NONE; // no sleep
  1499. if (Result == ERR_NONE && Stream->State.DropLevel)
  1500. Result = ERR_DROPPING;
  1501. }
  1502. }
  1503. if (!p->ActiveStreams)
  1504. {
  1505. // release buffers
  1506. Result = ERR_END_OF_FILE;
  1507. for (No=0;No<MAXREADER;++No)
  1508. {
  1509. format_buffer* Buffer;
  1510. format_reader* Reader = p->Reader+No;
  1511. if (!Reader->Input)
  1512. break;
  1513. while ((Buffer = Format_BufferRemove(Reader))!=NULL)
  1514. {
  1515. Reader->FilePos += Buffer->Length;
  1516. Format_BufferRelease(p,Buffer);
  1517. }
  1518. if (!Reader->NoMoreInput)
  1519. Result = ERR_BUFFER_FULL; // return buffer full so fill mode doesn't go though file
  1520. }
  1521. State->Time = TIME_UNKNOWN; // player should use file position
  1522. }
  1523. else
  1524. {
  1525. if (AllEndOfFile) // all end of file?
  1526. Result = ERR_END_OF_FILE;
  1527. else
  1528. if (AllNeedMoreData) // all need data?
  1529. {
  1530. Result = ERR_END_OF_FILE;
  1531. for (No=0;No<MAXREADER;++No)
  1532. {
  1533. if (!p->Reader[No].Input)
  1534. break;
  1535. if (!p->Reader[No].NoMoreInput)
  1536. {
  1537. Result = ERR_NEED_MORE_DATA;
  1538. break;
  1539. }
  1540. }
  1541. }
  1542. else
  1543. if (Result == ERR_BUFFER_FULL && State->Fill)
  1544. {
  1545. // don't allow exiting fill mode if buffer is less than ProcessMinBuffer+BLOCKSIZE
  1546. // we might fallback to loadmode right after starting playback
  1547. if (p->Reader->BufferAvailable < p->ProcessMinBuffer+BLOCKSIZE && !p->Reader->NoMoreInput)
  1548. Result = ERR_NEED_MORE_DATA; 
  1549. }
  1550. }
  1551. if (p->SyncMode && Result == ERR_END_OF_FILE)
  1552. {
  1553. p->SyncMode = 0;
  1554. if (p->Duration<0 && p->SyncStream)
  1555. State->Time = p->SyncStream->LastTime;
  1556. else
  1557. State->Time = p->Duration;
  1558. Result = ERR_SYNCED;
  1559. }
  1560. State->BufferUsedAfter = p->BufferUsed;
  1561. return Result;
  1562. }
  1563. format_ref* Format_RefAlloc(format_base* p, format_buffer* To, int Begin, int Length)
  1564. {
  1565. format_ref* Ref = p->FreeRefs;
  1566. if (!Ref)
  1567. {
  1568. Ref = (format_ref*) malloc(sizeof(format_ref));
  1569. if (!Ref)
  1570. return NULL;
  1571. }
  1572. else
  1573. p->FreeRefs = Ref->Next;
  1574. LockEnter(p->BufferLock);
  1575. //DEBUG_MSG3(DEBUG_FORMAT,"Buffer:%d addref %d->%d",To->Id,To->RefCount,To->RefCount+1);
  1576. ++To->RefCount;
  1577. LockLeave(p->BufferLock);
  1578. Ref->Length = Length;
  1579. Ref->Begin = Begin;
  1580. Ref->Buffer = To;
  1581. Ref->Next = NULL;
  1582. return Ref;
  1583. }
  1584. bool_t Format_ReadBuffer(format_reader* Reader, bool_t ToRead)
  1585. {
  1586. bool_t Result;
  1587. LockEnter(Reader->Format->InputLock);
  1588. LockEnter(Reader->Format->BufferLock);
  1589. if (!Reader->BufferFirst && !Reader->NoMoreInput)
  1590. {
  1591. format_buffer* Buffer = Reader->InputBuffer;
  1592. if (!Buffer)
  1593. Buffer = Format_BufferAlloc(Reader->Format,1);
  1594. if (Buffer)
  1595. {
  1596. // use partial buffer loading after sync for a few times (SYNCREAD)
  1597. // but later have to use full buffer (matroska seeking example can run out of buffer...)
  1598. int TargetLength = (ToRead && Reader->Format->SyncRead>0)? Reader->Format->ReadSize:BLOCKSIZE;
  1599. if (Buffer->Length >= TargetLength)
  1600. {
  1601. Format_BufferInsert(Reader,Buffer);
  1602. Reader->InputBuffer = NULL;
  1603. }
  1604. else
  1605. {
  1606. int Length = Reader->Input->ReadBlock(Reader->Input,&Buffer->Block,Buffer->Length,TargetLength - Buffer->Length);
  1607. if (Length < 0)
  1608. {
  1609. // failed
  1610. if (!Reader->InputBuffer)
  1611. Format_BufferRelease(Reader->Format,Buffer);
  1612. }
  1613. else
  1614. {
  1615. Buffer->Length += Length;
  1616. Reader->NoMoreInput = Length == 0;
  1617. if (!Length && !Reader->InputBuffer)
  1618. Format_BufferRelease(Reader->Format,Buffer);
  1619. else
  1620. {
  1621. Format_BufferInsert(Reader,Buffer);
  1622. Reader->InputBuffer = NULL;
  1623. }
  1624. }
  1625. }
  1626. }
  1627. if (Reader->Format->SyncRead>0)
  1628. Reader->Format->SyncRead--;
  1629. }
  1630. Result = Reader->BufferFirst != NULL;
  1631. if (Result && ToRead)
  1632. {
  1633. Reader->ReadBuffer = Format_BufferRemove(Reader);
  1634. if (Reader->ReadBuffer)
  1635. Reader->ReadLen = Reader->ReadBuffer->Length;
  1636. }
  1637. LockLeave(Reader->Format->BufferLock);
  1638. LockLeave(Reader->Format->InputLock);
  1639. return Result;
  1640. }
  1641. format_ref* Format_DupRef(format_base* p, format_ref* Chain, int Offset, int Length)
  1642. {
  1643. format_ref* Head = NULL;
  1644. format_ref** Ptr = &Head;
  1645. while (Chain && Offset >= Chain->Length)
  1646. {
  1647. Chain = Chain->Next;
  1648. Offset -= Chain->Length;
  1649. }
  1650. while (Chain && Length > 0)
  1651. {
  1652. int Len = Chain->Length - Offset;
  1653. if (Len > Length)
  1654. Len = Length;
  1655. *Ptr = Format_RefAlloc(p,Chain->Buffer,Chain->Begin+Offset,Len);
  1656. if (!*Ptr)
  1657. break;
  1658. Chain = Chain->Next;
  1659. Length -= Len;
  1660. Offset = 0;
  1661. Ptr = &(*Ptr)->Next;
  1662. }
  1663. return Head;
  1664. }
  1665. //---------------------------------------------------------------------------------------------
  1666. static bool_t Reader_GetReadBuffer(format_reader* Reader)
  1667. {
  1668. if (!Reader->Input) // external reader
  1669. {
  1670. Reader->ReadBuffer = NULL;
  1671. return 0;
  1672. }
  1673. // release old buffer
  1674. if (Reader->ReadBuffer)
  1675. {
  1676. Reader->ReadPos -= Reader->ReadBuffer->Length;
  1677. Format_BufferRelease(Reader->Format,Reader->ReadBuffer);
  1678. }
  1679. // get new buffer from BufferFirst..BufferLast chain
  1680. Reader->ReadBuffer = Format_BufferRemove(Reader);
  1681. if (Reader->ReadBuffer)
  1682. {
  1683. Reader->ReadLen = Reader->ReadBuffer->Length;
  1684. return 1;
  1685. }
  1686. // load input now (can't wait for input thread)
  1687. return Format_ReadBuffer(Reader,1);
  1688. }
  1689. format_ref* Reader_ReadAsRef(format_reader* p, int Length)
  1690. {
  1691. int n;
  1692. format_ref* Ref;
  1693. format_ref** RefPtr;
  1694. Ref = NULL;
  1695. RefPtr = &Ref;
  1696. if (Length < 0) // read as much as possible from one buffer
  1697. {
  1698. while (!p->ReadBuffer || p->ReadPos >= p->ReadLen)
  1699. if (!p->GetReadBuffer(p))
  1700. return NULL;
  1701. n = p->ReadLen - p->ReadPos;
  1702. if (n > -Length)
  1703. n = -Length;
  1704. Length = n;
  1705. }
  1706. while (Length > 0)
  1707. {
  1708. while (!p->ReadBuffer || p->ReadPos >= p->ReadLen)
  1709. if (!p->GetReadBuffer(p))
  1710. return Ref;
  1711. n = p->ReadLen - p->ReadPos;
  1712. if (n > Length)
  1713. n = Length;
  1714. *RefPtr = Format_RefAlloc(p->Format,p->ReadBuffer,p->ReadPos,n);
  1715. if (!*RefPtr)
  1716. break;
  1717. RefPtr = &(*RefPtr)->Next;
  1718. Length -= n;
  1719. p->FilePos += n;
  1720. p->ReadPos += n;
  1721. }
  1722. return Ref;
  1723. }
  1724. static void Reader_Skip(format_reader* p,int n)
  1725. {
  1726. if (n > 0)
  1727. {
  1728. assert(n < 0x10000000);
  1729. p->FilePos += n;
  1730. p->ReadPos += n;
  1731. }
  1732. }
  1733. static int Reader_Seek(format_reader* Reader,filepos_t Pos,int Origin)
  1734. {
  1735. int Adjust = 0;
  1736. if (Reader->FilePos >= 0 && !Reader->Format->DisableReader)
  1737. {
  1738. filepos_t RelPos = Pos;
  1739. if (Origin == SEEK_SET)
  1740. RelPos -= Reader->FilePos;
  1741. if (Origin != SEEK_END)
  1742. {
  1743. // check if we can use Format_Skip
  1744. if (RelPos >= 0 && RelPos < Reader->BufferAvailable + SKIPDISTANCE)
  1745. {
  1746. Reader_Skip(Reader,RelPos);
  1747. return ERR_NONE;
  1748. }
  1749. // check if we are in the same ReadBuffer
  1750. if (RelPos < 0 && Reader->ReadBuffer && Reader->ReadPos + RelPos >= 0)
  1751. {
  1752. Reader->FilePos += RelPos;
  1753. Reader->ReadPos += RelPos;
  1754. return ERR_NONE;
  1755. }
  1756. }
  1757. }
  1758. if (!Reader->Input)
  1759. return ERR_NOT_SUPPORTED;
  1760. if (Origin == SEEK_CUR)
  1761. {
  1762. // input is at a different position already, using SEEK_SET
  1763. Origin = SEEK_SET;
  1764. Pos += Reader->FilePos;
  1765. }
  1766. if (Origin == SEEK_SET)
  1767. {
  1768. // align reading for local files
  1769. Adjust = Pos & (Reader->Format->FileAlign-1);
  1770. Pos &= ~(Reader->Format->FileAlign-1);
  1771. }
  1772. LockEnter(Reader->Format->InputLock);
  1773. Pos = Reader->Input->Seek(Reader->Input,Pos,Origin);
  1774. if (Pos < 0)
  1775. {
  1776. LockLeave(Reader->Format->InputLock);
  1777. return ERR_NOT_SUPPORTED;
  1778. }
  1779. // query again file size, because http could have reopened connection
  1780. if (Reader->Input->Get(Reader->Input,STREAM_LENGTH,&Reader->Format->FileSize,sizeof(Reader->Format->FileSize)) != ERR_NONE)
  1781. Reader->Format->FileSize = -1;
  1782. Format_ReleaseBuffers(Reader);
  1783. Reader->FilePos = Pos + Adjust;
  1784. Reader->ReadPos += Adjust;
  1785. LockLeave(Reader->Format->InputLock);
  1786. return ERR_NONE;
  1787. }
  1788. static bool_t Reader_Eof(format_reader* p)
  1789. {
  1790. return !p->BufferAvailable && !p->ReadBuffer && p->NoMoreInput;
  1791. }
  1792. static int Reader_Read(format_reader* p, void* Data, int Length0)
  1793. {
  1794. uint8_t* Ptr = (uint8_t*)Data;
  1795. int Length = Length0;
  1796. int n;
  1797. while (Length > 0)
  1798. {
  1799. while (!p->ReadBuffer || p->ReadPos >= p->ReadLen)
  1800. if (!p->GetReadBuffer(p))
  1801. return Length0 - Length;
  1802. n = p->ReadLen - p->ReadPos;
  1803. if (n > Length)
  1804. n = Length;
  1805. memcpy(Ptr,p->ReadBuffer->Block.Ptr+p->ReadPos,n);
  1806. Ptr += n;
  1807. Length -= n;
  1808. p->FilePos += n;
  1809. p->ReadPos += n;
  1810. }
  1811. return Length0;
  1812. }
  1813. static int Reader_Read8(format_reader* p)
  1814. {
  1815. while (!p->ReadBuffer || p->ReadPos >= p->ReadLen)
  1816. if (!p->GetReadBuffer(p))
  1817. return -1;
  1818. p->FilePos++;
  1819. return p->ReadBuffer->Block.Ptr[p->ReadPos++];
  1820. }
  1821. static int Reader_ReadBE16(format_reader* p)
  1822. {
  1823. int v = Reader_Read8(p) << 8;
  1824. v |= Reader_Read8(p);
  1825. return v;
  1826. }
  1827. static int Reader_ReadLE16(format_reader* p)
  1828. {
  1829. int v = Reader_Read8(p);
  1830. v |= Reader_Read8(p) << 8;
  1831. return v;
  1832. }
  1833. static int Reader_ReadBE32(format_reader* p)
  1834. {
  1835. int v = Reader_Read8(p) << 24;
  1836. v |= Reader_Read8(p) << 16;
  1837. v |= Reader_Read8(p) << 8;
  1838. v |= Reader_Read8(p);
  1839. return v;
  1840. }
  1841. static int Reader_ReadLE32(format_reader* p)
  1842. {
  1843. int v = Reader_Read8(p);
  1844. v |= Reader_Read8(p) << 8;
  1845. v |= Reader_Read8(p) << 16;
  1846. v |= Reader_Read8(p) << 24;
  1847. return v;
  1848. }
  1849. static int64_t Reader_ReadBE64(format_reader* p)
  1850. {
  1851. int64_t v = (int64_t)Reader_ReadBE32(p) << 32;
  1852. v |= (uint32_t)Reader_ReadBE32(p);
  1853. return v;
  1854. }
  1855. static int64_t Reader_ReadLE64(format_reader* p)
  1856. {
  1857. int64_t v = (uint32_t)Reader_ReadLE32(p);
  1858. v |= (int64_t)Reader_ReadLE32(p) << 32;
  1859. return v;
  1860. }
  1861. static NOINLINE int GetRate(format_reader* p,format_reader* Last)
  1862. {
  1863. int64_t Rate;
  1864. if (p->NoMoreInput)
  1865. return MAX_INT;
  1866. if (p->BufferAvailable <= PROCESSMINVIDEO)
  1867. return -MAX_INT;
  1868. Rate = (int64_t)p->Ratio * (p->BufferAvailable - (p==Last?READER_BONUS:0));
  1869. if (Rate > MAX_INT)
  1870. return MAX_INT;
  1871. return (int)Rate;
  1872. }
  1873. static int Format_ReadInput(format_base* p,int BufferMax,int* BufferUsed)
  1874. {
  1875. int No;
  1876. int Left,Length;
  1877. int Result = ERR_NONE;
  1878. format_buffer* Buffer;
  1879. format_reader* Reader;
  1880. int Used = p->BufferUsed;
  1881. // simple estimate test without locking BufferUsed
  1882. if (Used >= BufferMax)
  1883. {
  1884. *BufferUsed = Used;
  1885. return ERR_BUFFER_FULL;
  1886. }
  1887. LockEnter(p->InputLock);
  1888. LockEnter(p->BufferLock);
  1889. // select which reader to use
  1890. Reader = p->Reader;
  1891. if (p->Reader[1].Input)
  1892. {
  1893. int Lowest = GetRate(Reader,p->LastRead);
  1894. for (No=1;No<MAXREADER;++No)
  1895. {
  1896. format_reader* r = p->Reader+No;
  1897. if (r->Ratio > 0)
  1898. {
  1899. int Rate = GetRate(r,p->LastRead);
  1900. if (Lowest > Rate)
  1901. {
  1902. Lowest = Rate;
  1903. Reader = r;
  1904. }
  1905. }
  1906. }
  1907. p->LastRead = Reader;
  1908. }
  1909. Buffer = Reader->InputBuffer;
  1910. if (!Buffer)
  1911. {
  1912. // allocate input buffer
  1913. if (p->BufferUsed < BufferMax) // check again (BufferUsed is locked)
  1914. {
  1915. Buffer = Format_BufferAlloc(p,0);
  1916. if (p->BufferUsed >= BufferMax)
  1917. Result = ERR_BUFFER_FULL;
  1918. }
  1919. if (!Buffer)
  1920. {
  1921. *BufferUsed = p->BufferUsed;
  1922. LockLeave(p->BufferLock);
  1923. LockLeave(p->InputLock);
  1924. return ERR_BUFFER_FULL;
  1925. }
  1926. #ifndef NDEBUG
  1927. Buffer->FilePos = Reader->Input->Seek(Reader->Input,0,SEEK_CUR);
  1928. #endif
  1929. }
  1930. *BufferUsed = p->BufferUsed;
  1931. LockLeave(p->BufferLock);
  1932. Left = BLOCKSIZE - Buffer->Length;
  1933. if (Left > p->ReadSize)
  1934. Left = p->ReadSize;
  1935. if (Reader->Input->DataAvailable)
  1936. {
  1937. int Available = Reader->Input->DataAvailable(Reader->Input);
  1938. if (Available>=0)
  1939. {
  1940. if (!Available)
  1941. {
  1942. if (!Reader->InputBuffer)
  1943. Format_BufferRelease(Reader->Format,Buffer);
  1944. LockLeave(p->InputLock);
  1945. return ERR_NEED_MORE_DATA;
  1946. }
  1947. if (Left > Available)
  1948. Left = Available;
  1949. }
  1950. }
  1951. Length = Reader->Input->ReadBlock(Reader->Input,&Buffer->Block,Buffer->Length,Left);
  1952. if (Length < 0)
  1953. {
  1954. // failed
  1955. if (!Reader->InputBuffer)
  1956. Format_BufferRelease(Reader->Format,Buffer);
  1957. Result = ERR_DEVICE_ERROR;
  1958. }
  1959. else
  1960. {
  1961. Buffer->Length += Length;
  1962. Reader->NoMoreInput = Length == 0;
  1963. if (!Length)
  1964. {
  1965. // only return end of file if all readers are at the end
  1966. Result = ERR_END_OF_FILE;
  1967. for (No=0;No<MAXREADER;++No)
  1968. {
  1969. if (!p->Reader[No].Input)
  1970. break;
  1971. if (!p->Reader[No].NoMoreInput)
  1972. {
  1973. Result = ERR_NONE;
  1974. break;
  1975. }
  1976. }
  1977. }
  1978. if (!Length && !Reader->InputBuffer)
  1979. Format_BufferRelease(Reader->Format,Buffer);
  1980. else
  1981. {
  1982. if (!Length || Buffer->Length == BLOCKSIZE || p->ProcessMinBuffer==0)
  1983. {
  1984. LockEnter(p->BufferLock);
  1985. Format_BufferInsert(Reader,Buffer);
  1986. LockLeave(p->BufferLock);
  1987. Buffer = NULL;
  1988. }
  1989. Reader->InputBuffer = Buffer;
  1990. }
  1991. }
  1992. LockLeave(p->InputLock);
  1993. return Result;
  1994. }
  1995. static NOINLINE void UpdateTotalCount(format_base* p)
  1996. {
  1997. p->TotalCount = p->StreamCount;
  1998. if (p->SubTitle)
  1999. p->Streams[p->TotalCount++] = p->SubTitle;
  2000. if (p->CoverArt)
  2001. p->Streams[p->TotalCount++] = p->CoverArt;
  2002. }
  2003. static NOINLINE void ReadCoverArt(format_base* p,stream* Input,filepos_t Pos,int Len,const tchar_t* ContentType,const tchar_t* URL)
  2004. {
  2005. uint8_t Probe[512];
  2006. int ProbeLen;
  2007. Input->Seek(Input,Pos,SEEK_SET);
  2008. ProbeLen = Input->Read(Input,Probe,min(Len,sizeof(Probe)));
  2009. if (ProbeLen>0)
  2010. {
  2011. int *i;
  2012. array List;
  2013. NodeEnumClassEx(&List,RAWIMAGE_CLASS,ContentType,URL,Probe,ProbeLen);
  2014. for (i=ARRAYBEGIN(List,int);i!=ARRAYEND(List,int);++i)
  2015. {
  2016. const tchar_t* Format = LangStr(*i,RAWIMAGE_FORMAT);
  2017. if (tcsnicmp(Format,T("vcodec/"),7)==0)
  2018. {
  2019. format_stream* s = (format_stream*) malloc(sizeof(format_stream));
  2020. if (!s)
  2021. return;
  2022. memset(s,0,sizeof(format_stream));
  2023. s->Format.Type = PACKET_VIDEO;
  2024. s->Format.Format.Video.Pixel.Flags = PF_FOURCC|PF_NOPREROTATE;
  2025. s->Format.Format.Video.Pixel.FourCC = StringToFourCC(Format+7,1);
  2026. if (Format_AllocBufferBlock(p,s,Len))
  2027. {
  2028. WriteBlock(&s->BufferBlock,0,Probe,ProbeLen);
  2029. s->Packet.Length = ProbeLen;
  2030. if (Len>ProbeLen)
  2031. s->Packet.Length += Input->ReadBlock(Input,&s->BufferBlock,ProbeLen,Len-ProbeLen);
  2032. }
  2033. if (s->Packet.Length>0)
  2034. {
  2035. s->Packet.Data[0] = s->BufferBlock.Ptr;
  2036. s->Packet.Key = 1;
  2037. s->Packet.RefTime = 0;
  2038. p->CoverArt = s;
  2039. UpdateTotalCount(p);
  2040. Format_PrepairStream(p,s);
  2041. }
  2042. else
  2043. Format_FreeStream(p,s);
  2044. break;
  2045. }
  2046. }
  2047. ArrayClear(&List);
  2048. }
  2049. }
  2050. static NOINLINE bool_t GetNonStreamingURL(format_base* p,tchar_t* URL,int URLLen,bool_t Local)
  2051. {
  2052. bool_t HasHost;
  2053. int Length;
  2054. stream* Input = p->Reader->Input;
  2055. if (!Input)
  2056. return 0;
  2057. LockEnter(p->InputLock);
  2058. if (Input->Get(Input,STREAM_URL,URL,URLLen*sizeof(tchar_t)) != ERR_NONE)
  2059. URL[0] = 0;
  2060. if (Input->Get(Input,STREAM_LENGTH,&Length,sizeof(Length)) != ERR_NONE)
  2061. Length = -1;
  2062. LockLeave(p->InputLock);
  2063. if (!URL[0])
  2064. return 0; //no URL?
  2065. GetMime(URL,NULL,0,&HasHost);
  2066. if (HasHost && (Local || Length<0))
  2067. return 0; //non local or streaming
  2068. return 1;
  2069. }
  2070. static NOINLINE bool_t OpenCoverAtr(format_base* p, const tchar_t* Base, const tchar_t* Name)
  2071. {
  2072. tchar_t Path[MAXPATH];
  2073. int Length;
  2074. stream* Input;
  2075. AbsPath(Path,TSIZEOF(Path),Name,Base);
  2076. if (FileExits(Path) && (Input = GetStream(Path,1))!=NULL)
  2077. {
  2078. //todo: cache global cover art...
  2079. if (Input->Set(Input,STREAM_URL,Path,sizeof(tchar_t)*(tcslen(Path)+1)) == ERR_NONE &&
  2080. Input->Get(Input,STREAM_LENGTH,&Length,sizeof(Length)) == ERR_NONE)
  2081. ReadCoverArt(p,Input,0,Length,NULL,Path);
  2082. Input->Set(Input,STREAM_URL,NULL,0);
  2083. NodeDelete((node*)Input);
  2084. }
  2085. return p->CoverArt != NULL;
  2086. }
  2087. static NOINLINE void FindCoverArt(format_base* p)
  2088. {
  2089. tchar_t Value[MAXPATH];
  2090. if (p->Comment.Node && NodeIsClass(p->Comment.Node->Class,PLAYER_ID) &&
  2091. ((player*)p->Comment.Node)->CommentByName(p->Comment.Node,-1,PlayerComment(COMMENT_COVER),Value,TSIZEOF(Value)))
  2092. {
  2093. tchar_t* SPos = tcschr(Value,':');
  2094. tchar_t* SLen = SPos?tcschr(SPos+1,':'):NULL;
  2095. tchar_t* ContentType = SLen?tcschr(SLen+1,':'):NULL;
  2096. int Pos = SPos ? StringToInt(SPos+1,0):0;
  2097. int Len = SLen ? StringToInt(SLen+1,0):0;
  2098. if (ContentType && Len>0)
  2099. {
  2100. stream* Input = p->Reader->Input;
  2101. filepos_t SavePos;
  2102. LockEnter(p->InputLock);
  2103. SavePos = Input->Seek(Input,0,SEEK_CUR);
  2104. if (SavePos >= 0)
  2105. {
  2106. if (*(++ContentType)==0)
  2107. ContentType = NULL;
  2108. ReadCoverArt(p,Input,Pos,Len,ContentType,NULL);
  2109. Input->Seek(Input,SavePos,SEEK_SET);
  2110. }
  2111. LockLeave(p->InputLock);
  2112. }
  2113. }
  2114. else if (NodeIsClass(p->Format.Class,RAWAUDIO_CLASS) && GetNonStreamingURL(p,Value,TSIZEOF(Value),1))
  2115. {
  2116. tchar_t Base[MAXPATH];
  2117. SplitURL(Value,Base,TSIZEOF(Base),Base,TSIZEOF(Base),NULL,0,NULL,0);
  2118. if (!OpenCoverAtr(p,Base,T("cover.jpg")) &&
  2119. !OpenCoverAtr(p,Base,T("folder.jpg")) &&
  2120. !OpenCoverAtr(p,Base,T("front.jpg")) &&
  2121. !OpenCoverAtr(p,Base,T("coverart.jpg")));
  2122. }
  2123. }
  2124. static void FindSubtitles(format_base* p)
  2125. {
  2126. /*
  2127. //!SUBTITLE
  2128. tchar_t* SubExt[] = { T("sub"),T("str"),T("smi"), NULL };
  2129. tchar_t** s;
  2130. tchar_t URL[MAXPATH];
  2131. if (!GetNonStreamingURL(p,URL,TSIZEOF(URL),0))
  2132. return;
  2133. for (s=SubExt;*s && !p->SubTitle;++s)
  2134. if (SetFileExt(URL,TSIZEOF(URL),*s))
  2135. {
  2136. stream* Input = GetStream(URL,1);
  2137. if (Input)
  2138. {
  2139. bool_t Silent = 1;
  2140. Input->Set(Input,STREAM_SILENT,&Silent,sizeof(Silent));
  2141. if (Input->Set(Input,STREAM_URL,URL,sizeof(tchar_t)*(tcslen(URL)+1)) == ERR_NONE)
  2142. {
  2143. p->SubTitle = Format_LoadSubTitle(p,Input);
  2144. if (p->SubTitle)
  2145. {
  2146. UpdateTotalCount(p);
  2147. Format_PrepairStream(p,(format_stream*)p->SubTitle);
  2148. }
  2149. }
  2150. Input->Delete(Input);
  2151. }
  2152. }
  2153. */
  2154. }
  2155. void Format_PrepairStream(format_base* p,format_stream* Stream)
  2156. {
  2157. switch (Stream->Format.Type)
  2158. {
  2159. case PACKET_VIDEO: Stream->PacketBurst = VIDEO_BURST; break;
  2160. case PACKET_AUDIO: Stream->PacketBurst = AUDIO_BURST; break;
  2161. case PACKET_SUBTITLE: Stream->PacketBurst = 1; break;
  2162. }
  2163. if (p->ProcessMinBuffer)
  2164. p->ProcessMinBuffer = IsVideo(p) ? PROCESSMINVIDEO:PROCESSMINAUDIO;
  2165. if (Stream->Format.Type == PACKET_AUDIO && Stream->Format.Format.Audio.Format == AUDIOFMT_PCM)
  2166. {
  2167. // there could be alignement problems (with memory and with audio.BlockSize)
  2168. Stream->Fragmented = 0;
  2169. Stream->ForceMerge = 1;
  2170. }
  2171. if (p->UpdateStreams.Func)
  2172. p->UpdateStreams.Func(p->UpdateStreams.This,0,0);
  2173. if (Stream->Format.Type == PACKET_VIDEO && p->NeedSubtitles)
  2174. {
  2175. p->NeedSubtitles = 0;
  2176. FindSubtitles(p);
  2177. }
  2178. }
  2179. static NOINLINE void DefaultPalette(packetformat* p)
  2180. {
  2181. if (p->Format.Video.Pixel.BitCount >= 1 &&
  2182. p->Format.Video.Pixel.BitCount <= 8 &&
  2183. p->ExtraLength >= (4 << p->Format.Video.Pixel.BitCount))
  2184. p->Format.Video.Pixel.Palette = p->Extra;
  2185. }
  2186. int Format_BitmapInfoMem(format_stream* s,void* Data,int Length)
  2187. {
  2188. if (Length>=4)
  2189. {
  2190. char* p = (char*)Data;
  2191. int Size = INT32LE(*(int32_t*)p);
  2192. if (Length >= Size)
  2193. {
  2194. PacketFormatClear(&s->Format);
  2195. s->Format.Type = PACKET_VIDEO;
  2196. s->Format.Format.Video.Width = INT32LE(*(int32_t*)(p+4));
  2197. s->Format.Format.Video.Height = INT32LE(*(int32_t*)(p+8));
  2198. s->Format.Format.Video.Pixel.BitCount = INT16LE(*(int16_t*)(p+14));
  2199. s->Format.Format.Video.Pixel.FourCC = INT32LE(*(int32_t*)(p+16));
  2200. s->Format.Format.Video.Aspect = ASPECT_ONE; //todo
  2201. if (PacketFormatExtra(&s->Format,Size-40))
  2202. {
  2203. memcpy(s->Format.Extra,p+40,s->Format.ExtraLength);
  2204. DefaultPalette(&s->Format);
  2205. }
  2206. PacketFormatDefault(&s->Format);
  2207. }
  2208. else
  2209. Size = 4;
  2210. Length -= Size;
  2211. }
  2212. return Length;
  2213. }
  2214. void Format_BitmapInfo(format_reader* p,format_stream* s,int Length)
  2215. {
  2216. if (Length>=4)
  2217. {
  2218. int Size = p->ReadLE32(p); //size
  2219. if (Length >= Size)
  2220. {
  2221. PacketFormatClear(&s->Format);
  2222. s->Format.Type = PACKET_VIDEO;
  2223. s->Format.Format.Video.Width = p->ReadLE32(p); 
  2224. s->Format.Format.Video.Height = p->ReadLE32(p); 
  2225. p->ReadLE16(p); //planes
  2226. s->Format.Format.Video.Pixel.BitCount = p->ReadLE16(p);
  2227. s->Format.Format.Video.Pixel.FourCC = p->ReadLE32(p);
  2228. s->Format.Format.Video.Aspect = ASPECT_ONE; //todo
  2229. p->Skip(p,20); //SizeImage,XPelsPerMeter,YPelsPerMeter,ClrUsed,ClrImportant
  2230. if (PacketFormatExtra(&s->Format,Size-40))
  2231. {
  2232. p->Read(p,s->Format.Extra,s->Format.ExtraLength);
  2233. DefaultPalette(&s->Format);
  2234. }
  2235. PacketFormatDefault(&s->Format);
  2236. }
  2237. else
  2238. Size = 4;
  2239. Length -= Size;
  2240. }
  2241. p->Skip(p,Length);
  2242. }
  2243. int Format_WaveFormatMem(format_stream* s,void* Data,int Length)
  2244. {
  2245. if (Length >= 16)
  2246. {
  2247. char* p = (char*)Data;
  2248. PacketFormatClear(&s->Format);
  2249. s->Format.Type = PACKET_AUDIO;
  2250. s->Format.Format.Audio.Format = INT16LE(*(int16_t*)(p+0));
  2251. s->Format.Format.Audio.Channels =INT16LE(*(int16_t*)(p+2));
  2252. s->Format.Format.Audio.SampleRate = INT32LE(*(int32_t*)(p+4));
  2253. s->Format.ByteRate = INT32LE(*(int32_t*)(p+8));
  2254. s->Format.Format.Audio.BlockAlign = INT16LE(*(int16_t*)(p+12));
  2255. s->Format.Format.Audio.Bits = INT16LE(*(int16_t*)(p+14));
  2256. Length -= 16;
  2257. if (Length >= 2)
  2258. {
  2259. int Extra = INT16LE(*(int16_t*)(p+16));
  2260. Length -= 2;
  2261. if (Extra > 0 && Length >= Extra)
  2262. {
  2263. if (PacketFormatExtra(&s->Format,Extra))
  2264. memcpy(s->Format.Extra,p+18,s->Format.ExtraLength);
  2265. Length -= Extra;
  2266. }
  2267. }
  2268. PacketFormatDefault(&s->Format);
  2269. }
  2270. return Length;
  2271. }
  2272. void Format_WaveFormat(format_reader* p,format_stream* s,int Length)
  2273. {
  2274. if (Length >= 16)
  2275. {
  2276. PacketFormatClear(&s->Format);
  2277. s->Format.Type = PACKET_AUDIO;
  2278. s->Format.Format.Audio.Format = p->ReadLE16(p);
  2279. s->Format.Format.Audio.Channels = p->ReadLE16(p);
  2280. s->Format.Format.Audio.SampleRate = p->ReadLE32(p);
  2281. s->Format.ByteRate = p->ReadLE32(p);
  2282. s->Format.Format.Audio.BlockAlign = p->ReadLE16(p);
  2283. s->Format.Format.Audio.Bits = p->ReadLE16(p);
  2284. Length -= 16;
  2285. if (Length >= 2)
  2286. {
  2287. int Extra = p->ReadLE16(p);
  2288. Length -= 2;
  2289. if (Extra > 0 && Length >= Extra)
  2290. {
  2291. if (PacketFormatExtra(&s->Format,Extra))
  2292. p->Read(p,s->Format.Extra,s->Format.ExtraLength);
  2293. Length -= Extra;
  2294. }
  2295. }
  2296. PacketFormatDefault(&s->Format);
  2297. }
  2298. p->Skip(p,Length);
  2299. }
  2300. void Format_RemoveStream(format_base* p)
  2301. {
  2302. if (p->StreamCount)
  2303. {
  2304. format_stream* Stream = p->Streams[--p->StreamCount];
  2305. UpdateTotalCount(p);
  2306. if (p->FreeStream)
  2307. p->FreeStream(p,Stream);
  2308. Format_FreeStream(p,Stream);
  2309. }
  2310. }
  2311. format_stream* Format_AddStream(format_base* p, int Length)
  2312. {
  2313. format_stream* s;
  2314. if (p->StreamCount >= MAXSTREAM-1-1) //subtitle,coverart
  2315. return NULL;
  2316. s = (format_stream*) malloc(Length);
  2317. if (!s)
  2318. return NULL;
  2319. memset(s,0,Length);
  2320. s->Reader = p->Reader; // default
  2321. s->No = p->StreamCount;
  2322. s->LastTime = TIME_SYNC;
  2323. p->Streams[p->StreamCount++] = s;
  2324. UpdateTotalCount(p);
  2325. return s;
  2326. }
  2327. static int Create(format_base* p)
  2328. {
  2329. int No;
  2330. format_reader* Reader = p->Reader;
  2331. for (No=0;No<MAXREADER;++No,++Reader)
  2332. {
  2333. Reader->Format = p;
  2334. Reader->Seek = Reader_Seek;
  2335. Reader->Eof = Reader_Eof;
  2336. Reader->Skip = Reader_Skip;
  2337. Reader->Read = Reader_Read;
  2338. Reader->Read8 = Reader_Read8;
  2339. Reader->ReadLE16 = Reader_ReadLE16;
  2340. Reader->ReadBE16 = Reader_ReadBE16;
  2341. Reader->ReadLE32 = Reader_ReadLE32;
  2342. Reader->ReadBE32 = Reader_ReadBE32;
  2343. Reader->ReadLE64 = Reader_ReadLE64;
  2344. Reader->ReadBE64 = Reader_ReadBE64;
  2345. Reader->ReadAsRef = Reader_ReadAsRef;
  2346. Reader->GetReadBuffer = Reader_GetReadBuffer;
  2347. }
  2348. p->Format.Enum = (nodeenum)FormatBaseEnum;
  2349. p->Format.Get = (nodeget)FormatBaseGet;
  2350. p->Format.Set = (nodeset)FormatBaseSet;
  2351. p->Format.Sync = (fmtsync)Format_Sync;
  2352. p->Format.Read = (fmtread)Format_ReadInput;
  2353. p->Format.Process = (fmtprocess)Format_Process;
  2354. p->FillQueue = (fmtfill)Format_FillQueue;
  2355. p->Process = (fmtstreamprocess)Format_ProcessStream;
  2356. p->Sended = (fmtstream)Format_Sended;
  2357. p->FileAlign = 1;
  2358. p->Timing = 1;
  2359. p->MinHeaderLoad = BLOCKSIZE;
  2360. #ifdef TARGET_PALMOS
  2361. p->UseBufferBlock = Context()->LowMemory;
  2362. #endif
  2363. return ERR_NONE;
  2364. }
  2365. static const nodedef FormatBase =
  2366. {
  2367. sizeof(format_base)|CF_ABSTRACT,
  2368. FORMATBASE_CLASS,
  2369. FORMAT_CLASS,
  2370. PRI_DEFAULT,
  2371. (nodecreate)Create,
  2372. };
  2373. void FormatBase_Init()
  2374. {
  2375. NodeRegisterClass(&FormatBase);
  2376. }
  2377. void FormatBase_Done()
  2378. {
  2379. NodeUnRegisterClass(FORMATBASE_CLASS);
  2380. }