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

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: mjpeg.c 603 2006-01-19 13:00:33Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23.  
  24. #include "../common/common.h"
  25. #include "mjpeg.h"
  26. #define WEBMJEG_READSIZE 2048
  27. #define VLC_BITS 9
  28. typedef struct blockindex
  29. {
  30. uint8_t quant;
  31. uint8_t comp;
  32. uint8_t ac;
  33. uint8_t dc;
  34. } blockindex;
  35. typedef struct mjpeg 
  36. {
  37. codecidct Codec;
  38. bool_t error;
  39. int sos_no;
  40. int restart_interval;
  41. int restart_count;
  42. idct_block_t* blockptr;
  43. // bitstream
  44. bitstream s;
  45. vlc* v[2][4];
  46. int vsize[2][4];
  47.     uint8_t quant[4][64];
  48. int hblock[4];
  49. int vblock[4];
  50. int compid[4];
  51. int quantidx[4];
  52. int Ss;
  53. int Se;
  54. int Al;
  55. int Ah;
  56. int blocks;
  57. int mb_width;
  58. int mb_height;
  59. int last_dc[4];
  60. int comp;
  61. bool_t progressive;
  62. int startstate;
  63. blockindex *indexend;
  64. blockindex index[4*2*2];
  65. uint8_t zigzag[64];
  66. IDCT_BLOCK_DECLARE
  67. } mjpeg;
  68. static const uint8_t zigzag[64] = 
  69. {
  70.  0,  1,  8, 16,  9,  2,  3, 10, 
  71. 17, 24, 32, 25, 18, 11,  4,  5,
  72. 12, 19, 26, 33, 40, 48, 41, 34, 
  73. 27, 20, 13,  6,  7, 14, 21, 28, 
  74. 35, 42, 49, 56, 57, 50, 43, 36, 
  75. 29, 22, 15, 23, 30, 37, 44, 51, 
  76. 58, 59, 52, 45, 38, 31, 39, 46, 
  77. 53, 60, 61, 54, 47, 55, 62, 63
  78. };
  79. static const uint8_t dc_luminance[] =
  80. 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
  81. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
  82. };
  83. static const uint8_t dc_chrominance[] =
  84. 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 
  85. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 
  86. };
  87. static const uint8_t ac_luminance[] =
  88. 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125, 
  89. 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
  90. 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
  91. 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
  92. 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
  93. 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
  94. 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
  95. 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
  96. 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
  97. 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
  98. 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
  99. 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
  100. 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
  101. 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
  102. 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  103. 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
  104. 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
  105. 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
  106. 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
  107. 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
  108. 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
  109. 0xf9, 0xfa 
  110. };
  111. static const uint8_t ac_chrominance[] =
  112. 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119,
  113. 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
  114. 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
  115. 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
  116. 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
  117. 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
  118. 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
  119. 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
  120. 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
  121. 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
  122. 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
  123. 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  124. 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  125. 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
  126. 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
  127. 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
  128. 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
  129. 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
  130. 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
  131. 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
  132. 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
  133. 0xf9, 0xfa 
  134. };
  135. static const uint8_t* const default_dht[4] =
  136. {
  137. dc_luminance,
  138. dc_chrominance,
  139. ac_luminance,
  140. ac_chrominance
  141. };
  142. DECLARE_BITINIT
  143. DECLARE_BITLOAD
  144. #undef bitload_pos
  145. #define bitload_pos(p, bitpos)
  146. bitpos -= 8;
  147. if (bitpos >= 0) {
  148. int bits = (p)->bits;
  149. const uint8_t* bitptr = (p)->bitptr;
  150. do {
  151. bits = (bits << 8) | *bitptr;
  152. if (*bitptr++ == 0xFF)
  153. {
  154. while (*bitptr==0xFF && bitptr<(p)->bitend) 
  155. bitptr++;
  156. if (*bitptr==0)
  157. ++bitptr;
  158. }
  159. bitpos -= 8;
  160. } while (bitpos>=0);
  161. (p)->bits = bits;
  162. (p)->bitptr = bitptr;
  163. }
  164. bitpos += 8;
  165. static NOINLINE int NotSupported(mjpeg* p)
  166. {
  167. if (!p->error)
  168. {
  169. p->error = 1;
  170. ShowError(p->Codec.Node.Class,MJPEG_ID,MJPEG_NOT_SUPPORTED);
  171. }
  172. return ERR_NOT_SUPPORTED;
  173. }
  174. static NOINLINE bool_t VLC(vlc** tab, int* size, const uint8_t *data) 
  175. {
  176. uint32_t huffcode[256];
  177. uint16_t huffdata[256];
  178. int i,j,k,n,code;
  179. code = 0;
  180. k = 0;
  181. for (i=1;i<=16;i++) 
  182. {
  183. n = data[i];
  184. for (j=0;j<n;j++) 
  185. {
  186. huffcode[k] = ((code++)<<5)|i;
  187. huffdata[k] = data[k+17];
  188. ++k;
  189. }
  190. code <<= 1;
  191. }
  192.     return vlcinit(tab,size,huffcode,4,huffdata,k,0,VLC_BITS);
  193. }
  194. static int DQT(mjpeg* p)
  195. {
  196.     int len = bitget(&p->s,16) - 2;
  197.     while (len >= 65 && !biteof(&p->s)) 
  198. {
  199. int comp,i;
  200. bitload(&p->s);
  201.         if (bitget(&p->s,4) != 0)
  202. return NotSupported(p); // 16bit prec
  203.         comp = bitget(&p->s, 4);
  204.         if (comp >= 4)
  205.             return ERR_INVALID_DATA;
  206.         for (i=0;i<64;i++) 
  207. {
  208. bitload(&p->s);
  209. p->quant[comp][i] = (uint8_t)bitget(&p->s,8);
  210. }
  211.         len -= 65;
  212.     }
  213.     
  214.     return ERR_NONE;
  215. }
  216. static int DHT(mjpeg* p)
  217. {
  218.     uint8_t data[17+256];
  219.     int len = bitget(&p->s,16)-2;
  220.     while (len>=17 && !biteof(&p->s)) 
  221. {
  222. int n,i;
  223. int comp,idx;
  224. bitload(&p->s);
  225.         comp = bitget(&p->s,4);
  226.         if (comp >= 2)
  227. break;
  228.         idx = bitget(&p->s,4);
  229.         if (idx >= 4)
  230. break;
  231.         n = 0;
  232.         for (i=1;i<=16;i++) 
  233. {
  234. bitload(&p->s);
  235.             data[i] = (uint8_t) bitget(&p->s,8);
  236.             n += data[i];
  237.         }
  238.         len -= 17+n;
  239.         if (len<0 || n>256)
  240. break;
  241.         for (i=0;i<n;i++) 
  242. {
  243. bitload(&p->s);
  244.             data[17+i] = (uint8_t) bitget(&p->s,8);
  245. }
  246. if (!VLC(&p->v[comp][idx],&p->vsize[comp][idx],data))
  247. return ERR_NONE;
  248.     }
  249. return ERR_NONE;
  250. }
  251. static int DRI(mjpeg* p)
  252. {
  253.     if (bitget(&p->s,16) == 4)
  254. {
  255. bitload(&p->s);
  256.     p->restart_interval = bitget(&p->s,16);
  257. }
  258. return ERR_NONE;
  259. }
  260. static int SOF(mjpeg* p,bool_t progressive)
  261. {
  262.     int len,i,width,height,mode;
  263. p->progressive = progressive;
  264.     len = bitget(&p->s,16);
  265. bitload(&p->s);
  266.     if (bitget(&p->s,8) != 8) // 8bit/component
  267. return NotSupported(p);
  268.     
  269.     height = bitget(&p->s,16);
  270. bitload(&p->s);
  271.     width = bitget(&p->s,16);
  272.     p->comp = bitget(&p->s,8);
  273.     if (p->comp != 3 && p->comp != 1) // 3 or 1 components
  274. return NotSupported(p);
  275. if (len != 8+3*p->comp)
  276. return ERR_INVALID_DATA;
  277. p->blocks = 0;
  278.     for (i=0;i<p->comp;i++) 
  279. {
  280. bitload(&p->s);
  281.         p->compid[i] = bitget(&p->s,8);
  282.         p->hblock[i] = bitget(&p->s,4);
  283.         p->vblock[i] = bitget(&p->s,4);
  284.         p->quantidx[i] = bitget(&p->s,8);
  285.         if (p->quantidx[i] >= 4)
  286.             return ERR_INVALID_DATA;
  287. if (i>0 && (p->hblock[i]!=1 || p->vblock[i]!=1))
  288. return NotSupported(p);
  289. p->blocks += p->hblock[i] * p->vblock[i];
  290.     }
  291. p->indexend = p->index + p->blocks;
  292. switch (16*p->vblock[0]+p->hblock[0])
  293. {
  294. case 0x11:
  295. mode = PF_YUV444;
  296. p->mb_width  = (width + 7) >> 3;
  297. p->mb_height = (height + 7) >> 3;
  298. break;
  299. case 0x12:
  300. mode = PF_YUV422;
  301. p->mb_width  = (width + 15) >> 4;
  302. p->mb_height = (height + 7) >> 3;
  303. break;
  304. case 0x22:
  305. mode = PF_YUV420;
  306. p->mb_width  = (width + 15) >> 4;
  307. p->mb_height = (height + 15) >> 4;
  308. break;
  309. default:
  310. return NotSupported(p);
  311. }
  312. return CodecIDCTSetFormat(&p->Codec,mode|PF_YUV_PC,width,height,width,height,p->Codec.In.Format.Format.Video.Aspect);
  313. }
  314. static NOINLINE void scan(mjpeg* p)
  315. {
  316. idct* IDCT = p->Codec.IDCT.Ptr;
  317.     int x,y,bitpos;
  318. blockindex* i; 
  319. p->restart_count = p->restart_interval;
  320. bitpos = p->s.bitpos;
  321.     for (y=0;y<p->mb_height;++y)
  322.         for (x=0;x<p->mb_width;++x)
  323. {
  324. IDCT->Process(IDCT,x,y);
  325.             for (i=p->index;i!=p->indexend;i++)
  326. {
  327. int len,val,n;
  328. idct_block_t* block = p->blockptr; 
  329. uint8_t* quant = p->quant[i->quant];
  330. vlc* tab = p->v[0][i->dc]; 
  331. if (biteof(&p->s))
  332. break;
  333. ClearBlock(block);
  334. vlcget2_pos(val,tab,&p->s,bitpos,n,255,VLC_BITS);
  335. if (val)
  336. {
  337. bitload_pos(&p->s,bitpos);
  338. bitgetx_pos(&p->s,bitpos,val,n);
  339. }
  340. val = val * quant[0] + p->last_dc[i->comp];
  341. p->last_dc[i->comp] = val;
  342. block[0] = (idct_block_t)val;
  343. tab = p->v[1][i->ac];
  344. len = 1;
  345. for (;;)
  346. {
  347. vlcget2_pos(val,tab,&p->s,bitpos,n,255,VLC_BITS);
  348. if (!val)
  349. break;
  350. if (val == 0xF0) 
  351. {
  352. len += 16;
  353. if (len>=64)
  354. break;
  355. }
  356. else
  357. {
  358. n = val >> 4;
  359. val &= 15;
  360. len += n;
  361. bitload_pos(&p->s,bitpos);
  362. bitgetx_pos(&p->s,bitpos,val,n);
  363. n = len & 63;
  364. val *= quant[n];
  365. n = p->zigzag[n];
  366. block[n] = (idct_block_t)val;
  367. if (++len>=64)
  368. break;
  369. }
  370. }
  371. IDCT->Intra8x8(IDCT,block,len,IDCTSCAN_ZIGZAG);
  372.             }
  373. if (p->comp == 1)
  374. {
  375. idct_block_t* block = p->blockptr; 
  376. ClearBlock(block);
  377. block[0] = 1024;
  378. IDCT->Intra8x8(IDCT,block,1,IDCTSCAN_ZIGZAG);
  379. ClearBlock(block);
  380. block[0] = 1024;
  381. IDCT->Intra8x8(IDCT,block,1,IDCTSCAN_ZIGZAG);
  382. }
  383.             if (p->restart_interval && !--p->restart_count) 
  384. {
  385.                 p->restart_count = p->restart_interval;
  386. p->last_dc[0] = p->last_dc[1] = p->last_dc[2] = 1024;
  387.                 bitbytealign_pos(&p->s,bitpos);
  388. bitflush_pos(&p->s,bitpos,16);
  389. bitload_pos(&p->s,bitpos);
  390.             }
  391.         }
  392. p->s.bitpos = bitpos;
  393. }
  394. static int SOS(mjpeg* p)
  395. {
  396. const uint8_t *pos;
  397. int i,j,comp,len,result;
  398.     len = bitget(&p->s,16);
  399.     comp = bitget(&p->s,8);
  400.     if (len != 6+2*comp)
  401. return ERR_INVALID_DATA;
  402. if (p->comp != comp)
  403. return NotSupported(p);
  404. j=0;
  405.     for (i=0;i<comp;i++) 
  406. {
  407. int n,dc,ac;
  408. bitload(&p->s);
  409.         if (p->compid[i] != bitget(&p->s,8))
  410. return NotSupported(p);
  411.         dc = bitget(&p->s,4);
  412.         ac = bitget(&p->s,4);
  413. if (dc >= 4 || ac >= 4)
  414. return ERR_INVALID_DATA;
  415. for (n=p->hblock[i]*p->vblock[i];n;--n,++j)
  416. {
  417. p->index[j].quant=(uint8_t)p->quantidx[i];
  418. p->index[j].comp=(uint8_t)i;
  419. p->index[j].ac=(uint8_t)ac;
  420. p->index[j].dc=(uint8_t)dc;
  421. }
  422.     }
  423. bitload(&p->s);
  424.     p->Ss = bitget(&p->s,8); // Ss
  425.     p->Se = bitget(&p->s,8); // Se
  426. bitload(&p->s);
  427.     p->Ah = bitget(&p->s,4); // Ah
  428.     p->Al = bitget(&p->s,4); // Al
  429. p->last_dc[0] = p->last_dc[1] = p->last_dc[2] = 1024;
  430. if (!p->sos_no)
  431. {
  432. result = p->Codec.IDCT.Ptr->FrameStart(p->Codec.IDCT.Ptr,0,NULL,0,-1,-1,0,0);
  433. if (result != ERR_NONE)
  434. return result;
  435. p->Codec.Show = 0;
  436. }
  437. pos = bitbytepos(&p->s);
  438. bitinit(&p->s,pos,bitendptr(&p->s)-pos);
  439. ++p->sos_no;
  440.     scan(p);
  441. return ERR_NONE;
  442. }
  443. static int APP(mjpeg* p)
  444. {
  445.     int n = bitget(&p->s,16);
  446.     if (n>6)
  447.     bitflush(&p->s,n*8-16);
  448. return ERR_NONE;
  449. }
  450. static int Frame(mjpeg* p, const uint8_t* ptr, int num)
  451. {
  452. int Result = ERR_NONE;
  453. int code,v;
  454. if (p->Codec.State.DropLevel)
  455. return p->Codec.IDCT.Ptr->Null(p->Codec.IDCT.Ptr,NULL,0);
  456. p->sos_no = 0;
  457. p->progressive = 0;
  458. do
  459. {
  460. for (;;)
  461. {
  462. if (num < 2) 
  463. {
  464. code = 0xD9;
  465. break;
  466. }
  467. v = *ptr++;
  468. --num;
  469. if ((v == 0xFF) && (*ptr >= 0xC0) && (*ptr <= 0xFE)) 
  470. {
  471. code = *ptr++;
  472. --num;
  473. break;
  474. }
  475. }
  476. if (code == 0xD9)  // end of image
  477. break;
  478. bitinit(&p->s,ptr,num);
  479. bitload(&p->s);
  480.         switch(code) 
  481. {
  482.         case 0xD8: // start of image
  483.     p->restart_interval = 0;
  484. break;
  485. case 0xDD: // define restart interval
  486.     Result = DRI(p);
  487.     break;
  488.         case 0xDB: // define quantization tables
  489. Result = DQT(p);
  490. break;
  491. case 0xC4: // define huffman tables
  492. Result = DHT(p);
  493. break;
  494. case 0xC0: // baseline, huffman
  495.             Result = SOF(p,0);
  496. break;
  497. case 0xC2: // progressive, huffman
  498. if (!p->error)
  499. {
  500. p->error = 1;
  501. ShowError(p->Codec.Node.Class,MJPEG_ID,MJPEG_PROGRESSIVE);
  502. }
  503. Result = ERR_NOT_SUPPORTED;
  504. //todo... Result = SOF(p,1);
  505. break;
  506. case 0xDA:  // start of scan
  507. if (!p->sos_no || p->progressive)
  508.             Result = SOS(p);
  509. continue;
  510. case 0xE0:
  511. case 0xE1:
  512. case 0xE2:
  513. case 0xE3:
  514. case 0xE4:
  515. case 0xE5:
  516. case 0xE6:
  517. case 0xE7:
  518. case 0xE8:
  519. case 0xE9:
  520. case 0xEA:
  521. case 0xEB:
  522. case 0xEC:
  523. case 0xED:
  524. case 0xEE:
  525. case 0xEF:
  526. Result = APP(p);
  527. break;
  528. case 0xC1: // extended sequential, huffman
  529. case 0xC3: // lossless, huffman
  530. case 0xC5: // differential sequential, huffman
  531. case 0xC6: // differential progressive, huffman
  532. case 0xC7: // differential lossless, huffman
  533. case 0xC9: // extended sequential, arithmetic
  534. case 0xCA: // progressive, arithmetic
  535. case 0xCB: // lossless, arithmetic
  536. case 0xCD: // differential sequential, arithmetic
  537. case 0xCE: // differential progressive, arithmetic
  538. case 0xCF: // differential lossless, arithmetic
  539. case 0xC8: // reserved
  540. Result = NotSupported(p);
  541. break;
  542.         }
  543. v = bitbytepos(&p->s) - ptr;
  544. ptr += v;
  545. num -= v;
  546.     }
  547. while (Result == ERR_NONE);
  548. if (p->sos_no)
  549. p->Codec.IDCT.Ptr->FrameEnd(p->Codec.IDCT.Ptr);
  550. return Result;
  551. }
  552. static int Flush(mjpeg* p)
  553. {
  554. p->startstate = 0;
  555. return ERR_NONE;
  556. }
  557. static bool_t FindNext(mjpeg* p)
  558. {
  559. const uint8_t* Ptr = p->Codec.Buffer.Data;
  560. int Len = p->Codec.Buffer.WritePos;
  561. int Pos = p->Codec.FrameEnd;
  562. for (;Pos<Len;++Pos)
  563. {
  564. uint8_t ch = Ptr[Pos];
  565. bool_t Valid;
  566. switch (p->startstate)
  567. {
  568. case -1:
  569. Valid = 0;
  570. break;
  571. case 1:
  572. Valid = ch == 0xD8;
  573. break;
  574. case 3:
  575. Valid = (ch >= 0xC0) && (ch <= 0xFE);
  576. break;
  577. default:
  578. Valid = ch == 0xFF;
  579. break;
  580. }
  581. if (!Valid)
  582. p->startstate = 0;
  583. else
  584. if (++p->startstate == 4)
  585. {
  586. p->Codec.FrameEnd = Pos-3;
  587. p->startstate = -1;
  588. return 1;
  589. }
  590. }
  591. p->Codec.FrameEnd = Pos;
  592. return 0;
  593. }
  594. static int UpdateInput(mjpeg* p)
  595. {
  596. int i,j;
  597. int Result = ERR_NONE;
  598. p->error = 0;
  599. IDCT_BLOCK_PREPARE(p,p->blockptr);
  600. memcpy(p->zigzag,zigzag,sizeof(zigzag));
  601. for (i=0;i<2;++i)
  602. for (j=0;j<4;++j)
  603. vlcdone(&p->v[i][j],&p->vsize[i][j]);
  604. if (p->Codec.In.Format.Type == PACKET_VIDEO)
  605. {
  606. Result = CodecIDCTSetFormat(&p->Codec,PF_YUV422|PF_YUV_PC,p->Codec.In.Format.Format.Video.Width,p->Codec.In.Format.Format.Video.Height,
  607.               p->Codec.In.Format.Format.Video.Width,p->Codec.In.Format.Format.Video.Height,
  608. p->Codec.In.Format.Format.Video.Aspect);
  609. if (Result == ERR_NONE)
  610. {
  611. for (i=0;i<2;++i)
  612. for (j=0;j<2;++j)
  613. if (!VLC(&p->v[i][j],&p->vsize[i][j],default_dht[i*2+j]))
  614. Result = ERR_OUT_OF_MEMORY;
  615. if (p->Codec.In.Format.PacketRate.Num>0)
  616. p->Codec.FrameTime = Scale(TICKSPERSEC,p->Codec.In.Format.PacketRate.Den,p->Codec.In.Format.PacketRate.Num);
  617. else
  618. p->Codec.FrameTime = 0;
  619. }
  620. }
  621. return Result;
  622. }
  623. static int Create(mjpeg* p)
  624. {
  625. p->Codec.MinCount = 1;
  626. p->Codec.Frame = (codecidctframe)Frame;
  627. p->Codec.UpdateInput = (nodefunc)UpdateInput;
  628. p->Codec.FindNext = (codecidctnext)FindNext;
  629. p->Codec.Flush = (nodefunc)Flush;
  630. return ERR_NONE;
  631. }
  632. static const nodedef MJPEG =
  633. {
  634. sizeof(mjpeg),
  635. MJPEG_ID,
  636. CODECIDCT_CLASS,
  637. PRI_DEFAULT,
  638. (nodecreate)Create,
  639. NULL,
  640. };
  641. //-------------------------------------------------------------------------------------------
  642. static const nodedef JPEG =
  643. {
  644. 0, // parent size
  645. JPEG_ID,
  646. RAWIMAGE_CLASS,
  647. PRI_DEFAULT,
  648. };
  649. //---------------------------------------------------------------------------------------------
  650. typedef struct webmjpeg
  651. {
  652. format_base Format;
  653. } webmjpeg;
  654. static int WEBMJPEGInit(rawaudio* p)
  655. {
  656. format_stream* s = Format_AddStream(&p->Format,sizeof(format_stream));
  657. if (s)
  658. {
  659. PacketFormatClear(&s->Format);
  660. s->Format.Type = PACKET_VIDEO;
  661. s->Format.Format.Video.Pixel.Flags = PF_FOURCC|PF_FRAGMENTED;
  662. s->Format.Format.Video.Pixel.FourCC = FOURCC('J','P','E','G');
  663. s->PacketBurst = 1;
  664. s->Fragmented = 1;
  665. s->DisableDrop = 1;
  666. Format_PrepairStream(&p->Format,s);
  667. }
  668. p->Format.HeaderLoaded = 1;
  669. p->Format.ProcessMinBuffer = 0;
  670. p->Format.ReadSize = WEBMJEG_READSIZE;
  671. return ERR_NONE;
  672. }
  673. static int WEBMJPEGPacket(rawaudio* p, format_reader* Reader, format_packet* Packet)
  674. {
  675. format_stream* Stream = p->Format.Streams[0];
  676. if (Reader->FilePos<=0)
  677. Packet->RefTime = 0;
  678. else
  679. Packet->RefTime = TIME_UNKNOWN;
  680. Packet->Data = Reader->ReadAsRef(Reader,-WEBMJEG_READSIZE);
  681. Packet->Stream = Stream;
  682. if (Stream->LastTime < TIME_UNKNOWN)
  683. Stream->LastTime = TIME_UNKNOWN;
  684. return ERR_NONE;
  685. }
  686. static int WEBMJPEGSeek(rawaudio* p, tick_t Time, filepos_t FilePos,bool_t PrevKey)
  687. {
  688. if (Time==0 || FilePos==0)
  689. p->Format.Reader->Seek(p->Format.Reader,0,SEEK_SET);
  690. return ERR_NONE;
  691. }
  692. static int WEBMJPEGCreate(rawaudio* p)
  693. {
  694. p->Format.Init = (fmtfunc)WEBMJPEGInit;
  695. p->Format.Seek = (fmtseek)WEBMJPEGSeek;
  696. p->Format.ReadPacket = (fmtreadpacket)WEBMJPEGPacket;
  697. return ERR_NONE;
  698. }
  699. static const nodedef WEBMJPEG =
  700. {
  701. sizeof(webmjpeg),
  702. WEB_MJPEG_ID,
  703. FORMATBASE_CLASS,
  704. PRI_DEFAULT,
  705. (nodecreate)WEBMJPEGCreate,
  706. NULL,
  707. };
  708. //---------------------------------------------------------------------------------------------
  709. void MJPEG_Init()
  710. {
  711. NodeRegisterClass(&MJPEG);
  712. NodeRegisterClass(&JPEG);
  713. NodeRegisterClass(&WEBMJPEG);
  714. }
  715. void MJPEG_Done()
  716. {
  717. NodeUnRegisterClass(MJPEG_ID);
  718. NodeUnRegisterClass(JPEG_ID);
  719. NodeUnRegisterClass(WEB_MJPEG_ID);
  720. }