encore.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:9k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "encore.h"
  2. #include "vop_code.h"
  3. #include "text_dct.h"
  4. #include "bitstream.h"
  5. #include "vm_common_defs.h"
  6. #include "rate_ctl.h"
  7. typedef struct _REFERENCE
  8. {
  9. unsigned long handle;
  10. float framerate;
  11. long bitrate;
  12. long rc_period;
  13. long rc_reaction_period;
  14. long rc_reaction_ratio;
  15. long max_key_interval;
  16. int x_dim, y_dim;
  17. int prev_rounding;
  18. int search_range;
  19. int max_quantizer;
  20. int min_quantizer;
  21. long seq;
  22. long curr_run;       
  23. Vop *current;        
  24. Vop *reference;      
  25. Vop *reconstruct;    
  26. Vop *error;          
  27. struct _REFERENCE *pnext;
  28. } REFERENCE;
  29. FILE *ftrace = NULL;
  30. int max_quantizer, min_quantizer;
  31. void init_vol_config(VolConfig *vol_config);
  32. void init_vop(Vop *vop);
  33. Int get_fcode (Int sr);
  34. int PutVoVolHeader(int vol_width, int vol_height, int time_increment_resolution, float frame_rate);
  35. int YUV2YUV (int x_dim, int y_dim, void *yuv, void *y_out, void *u_out, void *v_out);
  36. int encore(unsigned long handle, unsigned long enc_opt, void *param1, void *param2)
  37. {
  38. static REFERENCE *ref = NULL;
  39. static VolConfig *vol_config;
  40. REFERENCE *ref_curr, *ref_last = NULL;
  41. int x_dim, y_dim, size, length;
  42. int headerbits = 0;
  43. Vop *curr;
  44. ref_curr = ref_last = ref;
  45. while (ref_curr != NULL)
  46. {
  47. if (ref_curr->handle == handle) break;
  48. ref_last = ref_curr;
  49. ref_curr = ref_last->pnext;
  50. }
  51. if (ref_curr == NULL)
  52. {
  53. if (enc_opt & ENC_OPT_RELEASE) return ENC_OK;
  54. ref_curr = (REFERENCE *)malloc(sizeof(REFERENCE));
  55. ref_curr->handle = handle;
  56. ref_curr->seq = 0;
  57. ref_curr->curr_run = 0;
  58. ref_curr->pnext = NULL;
  59. if (ref) ref_last->pnext = ref_curr;
  60. else ref = ref_curr;
  61. }
  62. if (enc_opt & ENC_OPT_INIT)
  63. {
  64. #ifdef _RC_
  65. ftrace = fopen("trace.txt", "w");
  66. fflush(ftrace);
  67. #endif
  68. init_fdct_enc();
  69. init_idct_enc();
  70. ref_curr->framerate = ((ENC_PARAM *)param1)->framerate;
  71. ref_curr->bitrate = ((ENC_PARAM *)param1)->bitrate;
  72. ref_curr->rc_period = ((ENC_PARAM *)param1)->rc_period;
  73. ref_curr->rc_reaction_period = ((ENC_PARAM *)param1)->rc_reaction_period;
  74. ref_curr->rc_reaction_ratio = ((ENC_PARAM *)param1)->rc_reaction_ratio;
  75. ref_curr->x_dim = ((ENC_PARAM *)param1)->x_dim;
  76. ref_curr->y_dim = ((ENC_PARAM *)param1)->y_dim;
  77. ref_curr->max_key_interval = ((ENC_PARAM *)param1)->max_key_interval;
  78. ref_curr->search_range = ((ENC_PARAM *)param1)->search_range;
  79. ref_curr->max_quantizer = ((ENC_PARAM *)param1)->max_quantizer;
  80. ref_curr->min_quantizer = ((ENC_PARAM *)param1)->min_quantizer;
  81. ref_curr->current = AllocVop(ref_curr->x_dim, ref_curr->y_dim);
  82. ref_curr->reference = AllocVop(ref_curr->x_dim + 2 * 16, 
  83. ref_curr->y_dim + 2 * 16);
  84. ref_curr->reconstruct = AllocVop(ref_curr->x_dim, ref_curr->y_dim);
  85. ref_curr->error = AllocVop(ref_curr->x_dim, ref_curr->y_dim);
  86. init_vop(ref_curr->current);
  87. init_vop(ref_curr->reference);
  88. init_vop(ref_curr->reconstruct);
  89. init_vop(ref_curr->error);
  90. ref_curr->reference->hor_spat_ref = -16;
  91. ref_curr->reference->ver_spat_ref = -16;
  92. SetConstantImage(ref_curr->reference->y_chan, 0);
  93. vol_config = (VolConfig *)malloc(sizeof(VolConfig));
  94. init_vol_config(vol_config);
  95. vol_config->frame_rate = ref_curr->framerate;
  96. vol_config->bit_rate = ref_curr->bitrate;
  97. RateCtlInit(8 , vol_config->bit_rate / vol_config->frame_rate,
  98. ref_curr->rc_period, ref_curr->rc_reaction_period, ref_curr->rc_reaction_ratio);
  99. return ENC_OK;
  100. }
  101. if (enc_opt & ENC_OPT_RELEASE)
  102. {
  103. if (ref_curr == ref) ref = NULL;
  104. else ref_last->pnext = ref_curr->pnext;
  105. if (ref_curr->current) FreeVop(ref_curr->current);
  106. if (ref_curr->reference) FreeVop(ref_curr->reference);
  107. if (ref_curr->reconstruct) FreeVop(ref_curr->reconstruct);
  108. if (ref_curr->error) FreeVop(ref_curr->error);
  109. free(ref_curr);
  110. free(vol_config);
  111. if (ftrace) {
  112. fclose(ftrace);
  113. ftrace = NULL;
  114. };
  115. return ENC_OK;
  116. }
  117. max_quantizer = ref_curr->max_quantizer;
  118. min_quantizer = ref_curr->min_quantizer;
  119. x_dim = ref_curr->x_dim;
  120. y_dim = ref_curr->y_dim;
  121. size = x_dim * y_dim;
  122. curr = ref_curr->current;
  123. curr->width = x_dim;
  124. curr->height = y_dim;
  125. curr->sr_for = ref_curr->search_range;
  126. curr->fcode_for = get_fcode(curr->sr_for);
  127. YUV2YUV(x_dim, y_dim, ((ENC_FRAME *)param1)->image,
  128. curr->y_chan->f, curr->u_chan->f, curr->v_chan->f);
  129. curr->rounding_type = 1 - ref_curr->prev_rounding;
  130. Bitstream_Init((void *)(((ENC_FRAME *)param1)->bitstream));
  131. if (ref_curr->seq == 0) {
  132. headerbits = PutVoVolHeader(x_dim, y_dim, curr->time_increment_resolution, ref_curr->framerate);
  133. }
  134. #ifdef _RC_
  135. fflush(ftrace);
  136. fprintf(ftrace, "nCoding frame #%dn", ref_curr->seq);
  137. #endif
  138. if (ref_curr->curr_run % ref_curr->max_key_interval == 0) {
  139. curr->prediction_type = I_VOP;
  140. #ifdef _RC_
  141. fprintf(ftrace, "This frame is forced to be coded in INTRA.n");
  142. fprintf(ftrace, "It has been %d frame since the last INTRA.n", ref_curr->curr_run);
  143. #endif
  144. }
  145. else curr->prediction_type = P_VOP;
  146. VopCode(curr,
  147. ref_curr->reference,
  148. ref_curr->reconstruct,
  149. ref_curr->error,
  150. 1, 
  151. (float)ref_curr->seq/ref_curr->framerate,  
  152. vol_config);
  153. length = Bitstream_Close();
  154. ((ENC_FRAME *)param1)->length = length;
  155. RateCtlUpdate(length * 8);
  156. ref_curr->prev_rounding = curr->rounding_type;
  157. ref_curr->seq ++;
  158. ref_curr->curr_run ++;
  159. if (curr->prediction_type == I_VOP) {
  160. ((ENC_RESULT *)param2)->isKeyFrame = 1;
  161. ref_curr->curr_run = 1;
  162. } else 
  163. ((ENC_RESULT *)param2)->isKeyFrame = 0;
  164. return ENC_OK;
  165. }
  166. void init_vol_config(VolConfig *vol_config)
  167. {
  168. vol_config->M = 1;
  169. vol_config->frame_skip = 1;
  170. vol_config->quantizer = 8;
  171. vol_config->intra_quantizer = 8;
  172. vol_config->modulo_time_base[0] =0;
  173. vol_config->modulo_time_base[1] =0;
  174. vol_config->frame_rate = 30;
  175. vol_config->bit_rate = 800000;
  176. }
  177. void init_vop(Vop *vop)
  178. {
  179. vop->quant_precision = 5;
  180. vop->bits_per_pixel = 8;
  181. vop->time_increment_resolution = 30000;
  182. vop->intra_acdc_pred_disable = 0;
  183. vop->intra_dc_vlc_thr = 0;
  184. vop->sr_for = 512;
  185. vop->fcode_for = get_fcode(512);
  186. vop->y_chan->type = SHORT_TYPE;
  187. vop->u_chan->type = SHORT_TYPE;
  188. vop->v_chan->type = SHORT_TYPE;
  189. vop->hor_spat_ref = 0;
  190. vop->ver_spat_ref = 0;
  191. }
  192. Int get_fcode (Int sr)
  193. {
  194. if (sr<=16) return 1;
  195. else if (sr<=32) return 2;
  196. else if (sr<=64) return 3;
  197. else if (sr<=128) return 4;
  198. else if (sr<=256) return 5;
  199. else if (sr<=512) return 6;
  200. else if (sr<=1024) return 7;
  201. else return (-1);
  202. }
  203. int PutVoVolHeader(int vol_width, int vol_height, int time_increment_resolution, float frame_rate)
  204. {
  205. int written = 0;
  206. int bits, fixed_vop_time_increment;
  207. Bitstream_PutBits(VO_START_CODE_LENGTH, VO_START_CODE);
  208. Bitstream_PutBits(5, 0);
  209. written += VO_START_CODE_LENGTH + 5;
  210. Bitstream_PutBits(VOL_START_CODE_LENGTH, VOL_START_CODE);
  211. Bitstream_PutBits(4, 0);
  212. written += VOL_START_CODE_LENGTH + 4;
  213. Bitstream_PutBits(1, 0);
  214. Bitstream_PutBits(8, 1);
  215. Bitstream_PutBits(1, 1);
  216. Bitstream_PutBits(4, 2);
  217. Bitstream_PutBits(3, 1);
  218. written += 1 + 8 + 1 + 4 + 3;
  219. Bitstream_PutBits(4, 1);
  220. Bitstream_PutBits(1, 0);
  221. Bitstream_PutBits(2, 0);
  222. Bitstream_PutBits(1, 1);
  223. written += 4 + 1 + 2 + 1;
  224. Bitstream_PutBits(16, time_increment_resolution);
  225. Bitstream_PutBits(1, 1);
  226. Bitstream_PutBits(1, 1);
  227. bits = (int)ceil(log((double)time_increment_resolution)/log(2.0));
  228.     if (bits<1) bits=1;
  229. fixed_vop_time_increment = (int)(time_increment_resolution / frame_rate + 0.1);
  230. Bitstream_PutBits(bits, fixed_vop_time_increment);
  231. Bitstream_PutBits(1, 1);
  232. written += 16 + 1 + 1 + bits + 1;
  233. Bitstream_PutBits(13, vol_width);
  234. Bitstream_PutBits(1, 1);
  235. Bitstream_PutBits(13, vol_height);
  236. Bitstream_PutBits(1, 1);
  237. written += 13 + 1 + 13 + 1;
  238. Bitstream_PutBits(1, 0);
  239. Bitstream_PutBits(1, 1);
  240. Bitstream_PutBits(2, 0);
  241. Bitstream_PutBits(1, 0);
  242. written += 1 + 1 + 2 + 1;
  243. Bitstream_PutBits(1, 0);
  244. Bitstream_PutBits(1, 0);
  245. Bitstream_PutBits(1, 1);
  246. Bitstream_PutBits(1, 1);
  247. Bitstream_PutBits(1, 0);
  248. Bitstream_PutBits(1, 0);
  249. written += 1 + 1 + 1 + 1 + 1 + 1;
  250. written += Bitstream_NextStartCode();
  251. return(written);
  252. }
  253. int YUV2YUV (int x_dim, int y_dim, void *yuv, void *y_out, void *u_out, void *v_out)
  254. {
  255. unsigned char *in;
  256. short int *out;
  257. long size;
  258. in = yuv;
  259. out = y_out;
  260. size = x_dim * y_dim;
  261. while (size --) *(out ++) = *(in ++);
  262. out = u_out;
  263. size = x_dim * y_dim / 4;
  264. while (size --) *(out ++) = *(in ++);
  265. out = v_out;
  266. size = x_dim * y_dim / 4;
  267. while (size --) *(out ++) = *(in ++);
  268. return 0;
  269. }