divx4.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**************************************************************************
  2.  *
  3.  * XVID MPEG-4 VIDEO CODEC
  4.  * opendivx api wrapper
  5.  *
  6.  * This program is an implementation of a part of one or more MPEG-4
  7.  * Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
  8.  * to use this software module in hardware or software products are
  9.  * advised that its use may infringe existing patents or copyrights, and
  10.  * any such use would be at such party's own risk.  The original
  11.  * developer of this software module and his/her company, and subsequent
  12.  * editors and their companies, will have no liability for use of this
  13.  * software or modifications or derivatives thereof.
  14.  *
  15.  * This program is free software; you can redistribute it and/or modify
  16.  * it under the terms of the GNU General Public License as published by
  17.  * the Free Software Foundation; either version 2 of the License, or
  18.  * (at your option) any later version.
  19.  *
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU General Public License for more details.
  24.  *
  25.  * You should have received a copy of the GNU General Public License
  26.  * along with this program; if not, write to the Free Software
  27.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  28.  *
  29.  *************************************************************************/
  30. /**************************************************************************
  31.  *
  32.  * History:
  33.  *
  34.  * 26.02.2001 fixed dec_csp bugs
  35.  * 26.12.2001 xvid_init() support
  36.  * 22.12.2001 removed some compiler warnings
  37.  * 16.12.2001 inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>
  38.  *
  39.  *************************************************************************/
  40. #include <stdlib.h>
  41. #include <string.h>     // memset
  42. #include "xvid.h"
  43. #include "divx4.h"
  44. #include "decoder.h"
  45. #include "encoder.h"
  46. #define EMULATED_DIVX_VERSION 20011001
  47. // decore
  48. typedef struct DINST
  49. {
  50. unsigned long key;
  51. struct DINST * next;
  52. void * handle;
  53. XVID_DEC_FRAME xframe;
  54. } DINST;
  55. static DINST * dhead = NULL;
  56. static
  57. DINST * dinst_find(unsigned long key)
  58. {
  59. DINST * dcur = dhead;
  60. while (dcur)
  61. {
  62. if (dcur->key == key)
  63. {
  64. return dcur;
  65. }
  66. dcur = dcur->next;
  67. }
  68. return NULL;
  69. }
  70. static
  71. DINST * dinst_add(unsigned long key)
  72. {
  73. DINST * dnext = dhead;
  74. dhead = malloc(sizeof(DINST));
  75. if (dhead == NULL)
  76. {
  77. dhead = dnext;
  78. return NULL;
  79. }
  80. dhead->key = key;
  81. dhead->next = dnext;
  82. return dhead;
  83. }
  84. static
  85. void dinst_remove(unsigned long key)
  86. {
  87. DINST * dcur = dhead;
  88. if (dhead == NULL)
  89. {
  90. return;
  91. }
  92. if (dcur->key == key)
  93. {
  94. dhead = dcur->next;
  95. free(dcur);
  96. return;
  97. }
  98. while (dcur->next)
  99. {
  100. if (dcur->next->key == key)
  101. {
  102. DINST * tmp = dcur->next;
  103. dcur->next = tmp->next;
  104. free(tmp);
  105. return;
  106. }
  107. dcur = dcur->next;
  108. }
  109. }
  110. static
  111. int xvid_to_opendivx_dec_csp(int csp)
  112. {
  113. switch(csp)
  114. {
  115. case DEC_YV12 :
  116. return XVID_CSP_YV12;
  117. case DEC_420 :
  118. return XVID_CSP_I420;
  119. case DEC_YUY2 :
  120. return XVID_CSP_YUY2;
  121. case DEC_UYVY :
  122. return XVID_CSP_UYVY;
  123. case DEC_RGB32 :
  124. return XVID_CSP_VFLIP | XVID_CSP_RGB32;
  125. case DEC_RGB24 :
  126. return XVID_CSP_VFLIP | XVID_CSP_RGB24;
  127. case DEC_RGB565 :
  128. return XVID_CSP_VFLIP | XVID_CSP_RGB565;
  129. case DEC_RGB555 :
  130. return XVID_CSP_VFLIP | XVID_CSP_RGB555;
  131. case DEC_RGB32_INV :
  132. return XVID_CSP_RGB32;
  133. case DEC_RGB24_INV :
  134. return XVID_CSP_RGB24;
  135. case DEC_RGB565_INV :
  136. return XVID_CSP_RGB565;
  137. case DEC_RGB555_INV :
  138. return XVID_CSP_RGB555;
  139. case DEC_USER :
  140. return XVID_CSP_USER;    
  141. default :
  142. return -1;
  143. }
  144. }
  145. int decore(unsigned long key, unsigned long opt,
  146. void * param1, void * param2)
  147. {
  148. int xerr;
  149. switch (opt)
  150. {
  151. case DEC_OPT_MEMORY_REQS :
  152. {
  153. memset(param2, 0, sizeof(DEC_MEM_REQS));
  154. return DEC_OK;
  155. }
  156. case DEC_OPT_INIT :
  157. {
  158. DEC_PARAM * dparam = (DEC_PARAM *)param1;
  159. XVID_INIT_PARAM xinit;
  160. XVID_DEC_PARAM xparam;
  161. DINST * dcur = dinst_find(key);
  162. if (dcur == NULL)
  163. {
  164. dcur = dinst_add(key);
  165. }
  166. xinit.cpu_flags = 0;
  167. xvid_init(NULL, 0, &xinit, NULL);
  168. xparam.width = dparam->x_dim;
  169. xparam.height = dparam->y_dim;
  170. dcur->xframe.colorspace = xvid_to_opendivx_dec_csp(dparam->output_format);
  171. xerr = decoder_create(&xparam);
  172. dcur->handle = xparam.handle;
  173. break;
  174. }
  175. case DEC_OPT_RELEASE :
  176. {
  177. DINST * dcur = dinst_find(key);
  178. if (dcur == NULL)
  179. {
  180. return DEC_EXIT;
  181. }
  182. xerr = decoder_destroy(dcur->handle);
  183. dinst_remove(key);
  184. break;
  185. }
  186. case DEC_OPT_SETPP :
  187. {
  188. // DEC_SET * dset = (DEC_SET *)param1;
  189. DINST * dcur = dinst_find(key);
  190. if (dcur == NULL)
  191. {
  192. return DEC_EXIT;
  193. }
  194. // dcur->xframe.pp = dset->postproc_level;
  195. return DEC_OK;
  196. }
  197. case DEC_OPT_SETOUT :
  198. {
  199. DEC_PARAM * dparam = (DEC_PARAM *)param1;
  200. DINST * dcur = dinst_find(key);
  201. if (dcur == NULL)
  202. {
  203. return DEC_EXIT;
  204. }
  205. dcur->xframe.colorspace = xvid_to_opendivx_dec_csp(dparam->output_format);
  206. return DEC_OK;
  207. }
  208. case DEC_OPT_FRAME:
  209. {
  210. int csp_tmp = 0;
  211. DEC_FRAME * dframe = (DEC_FRAME *)param1;
  212. DINST * dcur = dinst_find(key);
  213. if (dcur == NULL)
  214. {
  215. return DEC_EXIT;
  216. }
  217. dcur->xframe.bitstream = dframe->bitstream;
  218. dcur->xframe.length = dframe->length;
  219. dcur->xframe.image = dframe->bmp;
  220. dcur->xframe.stride = dframe->stride;
  221. if (!dframe->render_flag)
  222. {
  223. csp_tmp = dcur->xframe.colorspace;
  224. dcur->xframe.colorspace = XVID_CSP_NULL;
  225. }
  226. xerr = decoder_decode(dcur->handle, &dcur->xframe);
  227. if (!dframe->render_flag)
  228. {
  229. dcur->xframe.colorspace = csp_tmp;
  230. }
  231. break;
  232. }
  233. case DEC_OPT_FRAME_311 :
  234. return DEC_EXIT;
  235. case DEC_OPT_VERSION:
  236. return EMULATED_DIVX_VERSION;
  237. default :
  238. return DEC_EXIT;
  239. }
  240. switch(xerr)
  241. {
  242. case XVID_ERR_OK : return DEC_OK;
  243. case XVID_ERR_MEMORY : return DEC_MEMORY;
  244. case XVID_ERR_FORMAT : return DEC_BAD_FORMAT;
  245. default : // case XVID_ERR_FAIL : 
  246. return DEC_EXIT;
  247. }
  248. }
  249. // encore
  250. #define FRAMERATE_INCR 1001
  251. int divx4_motion_presets[7] = {
  252. 0, PMV_QUICKSTOP16, PMV_EARLYSTOP16, PMV_EARLYSTOP16 | PMV_EARLYSTOP8,
  253. PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8,
  254. PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8,
  255. PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 |
  256. PMV_EARLYSTOP8 | PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8
  257. };
  258. int quality;
  259. int encore(void * handle, int opt, void * param1, void * param2)
  260. {
  261. int xerr;
  262. switch(opt)
  263. {
  264. case ENC_OPT_INIT :
  265. {
  266. ENC_PARAM * eparam = (ENC_PARAM *)param1;
  267. XVID_INIT_PARAM xinit;
  268. XVID_ENC_PARAM xparam;
  269. xinit.cpu_flags = 0;
  270. xvid_init(NULL, 0, &xinit, NULL);
  271. xparam.width = eparam->x_dim;
  272. xparam.height = eparam->y_dim;
  273. if ((eparam->framerate - (int)eparam->framerate) == 0)
  274. {
  275. xparam.fincr = 1; 
  276. xparam.fbase = (int)eparam->framerate;
  277. }
  278. else
  279. {
  280. xparam.fincr = FRAMERATE_INCR;
  281. xparam.fbase = (int)(FRAMERATE_INCR * eparam->framerate);
  282. }
  283. xparam.bitrate = eparam->bitrate;
  284. xparam.rc_buffersize = 16;
  285. xparam.min_quantizer = eparam->min_quantizer;
  286. xparam.max_quantizer = eparam->max_quantizer;
  287. xparam.max_key_interval = eparam->max_key_interval;
  288. quality = eparam->quality;
  289. xerr = encoder_create(&xparam);
  290. eparam->handle = xparam.handle;
  291. break;
  292. }
  293. case ENC_OPT_RELEASE :
  294. {
  295. xerr = encoder_destroy((Encoder *) handle);
  296. break;
  297. }
  298. case ENC_OPT_ENCODE :
  299. case ENC_OPT_ENCODE_VBR :
  300. {
  301. ENC_FRAME * eframe = (ENC_FRAME *)param1;
  302. ENC_RESULT * eresult = (ENC_RESULT *)param2;
  303. XVID_ENC_FRAME xframe;
  304. XVID_ENC_STATS xstats;
  305. xframe.bitstream = eframe->bitstream;
  306. xframe.length = eframe->length;
  307. xframe.general = XVID_HALFPEL | XVID_H263QUANT;
  308. if(quality > 3)
  309. xframe.general |= XVID_INTER4V;
  310. xframe.motion = divx4_motion_presets[quality];
  311. xframe.image = eframe->image;
  312. switch (eframe->colorspace)
  313. {
  314. case ENC_CSP_RGB24 : 
  315. xframe.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB24;
  316. break;
  317. case ENC_CSP_YV12 :
  318. xframe.colorspace = XVID_CSP_YV12;
  319. break;
  320. case ENC_CSP_YUY2 :
  321. xframe.colorspace = XVID_CSP_YUY2;
  322. break;
  323. case ENC_CSP_UYVY :
  324. xframe.colorspace = XVID_CSP_UYVY;
  325. break;
  326. case ENC_CSP_I420 :
  327. xframe.colorspace = XVID_CSP_I420;
  328. break;
  329. }
  330. if (opt == ENC_OPT_ENCODE_VBR)
  331. {
  332. xframe.intra = eframe->intra;
  333. xframe.quant = eframe->quant;
  334. }
  335. else
  336. {
  337. xframe.intra = -1;
  338. xframe.quant = 0;
  339. }
  340. xerr = encoder_encode((Encoder *) handle, &xframe, (eresult ? &xstats : NULL) );
  341. if (eresult)
  342. {
  343. eresult->is_key_frame = xframe.intra;
  344. eresult->quantizer = xstats.quant;
  345. eresult->total_bits = xframe.length * 8;
  346. eresult->motion_bits = xstats.hlength * 8;
  347. eresult->texture_bits = eresult->total_bits - eresult->motion_bits;
  348. }
  349. eframe->length = xframe.length;
  350. break;
  351. }
  352. default:
  353. return ENC_FAIL;
  354. }
  355. switch(xerr)
  356. {
  357. case XVID_ERR_OK : return ENC_OK;
  358. case XVID_ERR_MEMORY : return ENC_MEMORY;
  359. case XVID_ERR_FORMAT : return ENC_BAD_FORMAT;
  360. default : // case XVID_ERR_FAIL : 
  361. return ENC_FAIL;
  362. }
  363. }