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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #include "../libmpeg3.h"
  2. #include "../mpeg3private.h"
  3. #include "../mpeg3protos.h"
  4. #include "mpeg3video.h"
  5. #include "mpeg3videoprotos.h"
  6. #ifndef SDL_THREADS
  7. #include <pthread.h>
  8. #else
  9. #include "SDL.h"
  10. #include "SDL_thread.h"
  11. #endif
  12. #include <stdlib.h>
  13. // "脚悼绕" <doogle@shinbiro.com>
  14. unsigned char mpeg3_zig_zag_scan_mmx[64] =
  15. {
  16.     0*8+0 /* 0*/, 1*8+0 /* 1*/, 0*8+1 /* 8*/, 0*8+2 /*16*/, 1*8+1 /* 9*/, 2*8+0 /* 2*/, 3*8+0 /* 3*/, 2*8+1 /*10*/,
  17.     1*8+2 /*17*/, 0*8+3 /*24*/, 0*8+4 /*32*/, 1*8+3 /*25*/, 2*8+2 /*18*/, 3*8+1 /*11*/, 4*8+0 /* 4*/, 5*8+0 /* 5*/,
  18.     4*8+1 /*12*/, 3*8+2 /*19*/, 2*8+3 /*26*/, 1*8+4 /*33*/, 0*8+5 /*40*/, 0*8+6 /*48*/, 1*8+5 /*41*/, 2*8+4 /*34*/,
  19.     3*8+3 /*27*/, 4*8+2 /*20*/, 5*8+1 /*13*/, 6*8+0 /* 6*/, 7*8+0 /* 7*/, 6*8+1 /*14*/, 5*8+2 /*21*/, 4*8+3 /*28*/,
  20.     3*8+4 /*35*/, 2*8+5 /*42*/, 1*8+6 /*49*/, 0*8+7 /*56*/, 1*8+7 /*57*/, 2*8+6 /*50*/, 3*8+5 /*43*/, 4*8+4 /*36*/,
  21.     5*8+3 /*29*/, 6*8+2 /*22*/, 7*8+1 /*15*/, 7*8+2 /*23*/, 6*8+3 /*30*/, 5*8+4 /*37*/, 4*8+5 /*44*/, 3*8+6 /*51*/,
  22.     2*8+7 /*58*/, 3*8+7 /*59*/, 4*8+6 /*52*/, 5*8+5 /*45*/, 6*8+4 /*38*/, 7*8+3 /*31*/, 7*8+4 /*39*/, 6*8+5 /*46*/,
  23.     5*8+6 /*53*/, 4*8+7 /*60*/, 5*8+7 /*61*/, 6*8+6 /*54*/, 7*8+5 /*47*/, 7*8+6 /*55*/, 6*8+7 /*62*/, 7*8+7 /*63*/
  24. };
  25. /* alternate scan */
  26. unsigned char mpeg3_alternate_scan_mmx[64] =
  27. {
  28.      0*8+0 /*0 */, 0*8+1 /* 8*/, 0*8+2 /*16*/, 0*8+3 /*24*/, 1*8+0 /* 1*/, 1*8+1 /* 9*/, 2*8+0 /* 2*/, 2*8+1 /*10*/,
  29.      1*8+2 /*17*/, 1*8+3 /*25*/, 0*8+4 /*32*/, 0*8+5 /*40*/, 0*8+6 /*48*/, 0*8+7 /*56*/, 1*8+7 /*57*/, 1*8+6 /*49*/,
  30.      1*8+5 /*41*/, 1*8+4 /*33*/, 2*8+3 /*26*/, 2*8+2 /*18*/, 3*8+0 /* 3*/, 3*8+1 /*11*/, 4*8+0 /* 4*/, 4*8+1 /*12*/,
  31.      3*8+2 /*19*/, 3*8+3 /*27*/, 2*8+4 /*34*/, 2*8+5 /*42*/, 2*8+6 /*50*/, 2*8+7 /*58*/, 3*8+4 /*35*/, 3*8+5 /*43*/,
  32.      3*8+6 /*51*/, 3*8+7 /*59*/, 4*8+2 /*20*/, 4*8+3 /*28*/, 5*8+0 /* 5*/, 5*8+1 /*13*/, 6*8+0 /* 6*/, 6*8+1 /*14*/,
  33.      5*8+2 /*21*/, 5*8+3 /*29*/, 4*8+4 /*36*/, 4*8+5 /*44*/, 4*8+6 /*52*/, 4*8+7 /*60*/, 5*8+4 /*37*/, 5*8+5 /*45*/,
  34.      5*8+6 /*53*/, 5*8+7 /*61*/, 6*8+2 /*22*/, 6*8+3 /*30*/, 7*8+0 /* 7*/, 7*8+1 /*15*/, 7*8+2 /*23*/, 7*8+3 /*31*/,
  35.      6*8+4 /*38*/, 6*8+5 /*46*/, 6*8+6 /*54*/, 6*8+7 /*62*/, 7*8+4 /*39*/, 7*8+5 /*47*/, 7*8+6 /*55*/, 7*8+7 /*63*/
  36. };
  37. /* zig-zag scan */
  38. unsigned char mpeg3_zig_zag_scan_nommx[64] =
  39. {
  40.   0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 
  41.   12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 
  42.   35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 
  43.   58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
  44. };
  45. /* alternate scan */
  46. unsigned char mpeg3_alternate_scan_nommx[64] =
  47. {
  48.   0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49, 
  49.   41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43, 
  50.   51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45, 
  51.   53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63
  52. };
  53. /* default intra quantization matrix */
  54. unsigned char mpeg3_default_intra_quantizer_matrix[64] =
  55. {
  56.   8, 16, 19, 22, 26, 27, 29, 34,
  57.   16, 16, 22, 24, 27, 29, 34, 37,
  58.   19, 22, 26, 27, 29, 34, 34, 38,
  59.   22, 22, 26, 27, 29, 34, 37, 40,
  60.   22, 26, 27, 29, 32, 35, 40, 48,
  61.   26, 27, 29, 32, 35, 40, 48, 58,
  62.   26, 27, 29, 34, 38, 46, 56, 69,
  63.   27, 29, 35, 38, 46, 56, 69, 83
  64. };
  65. unsigned char mpeg3_non_linear_mquant_table[32] = 
  66. {
  67.    0, 1, 2, 3, 4, 5, 6, 7,
  68.    8, 10, 12, 14, 16, 18, 20, 22, 
  69.   24, 28, 32, 36, 40, 44, 48, 52, 
  70.   56, 64, 72, 80, 88, 96, 104, 112
  71. };
  72. double mpeg3_frame_rate_table[16] =
  73. {
  74.   0.0,   /* Pad */
  75.   24000.0/1001.0,       /* Official frame rates */
  76.   24.0,
  77.   25.0,
  78.   30000.0/1001.0,
  79.   30.0,
  80.   50.0,
  81.   ((60.0*1000.0)/1001.0),
  82.   60.0,
  83.   1,                    /* Unofficial economy rates */
  84.   5, 
  85.   10,
  86.   12,
  87.   15,
  88.   0,
  89.   0,
  90. };
  91. int mpeg3video_initdecoder(mpeg3video_t *video)
  92. {
  93. int blk_cnt_tab[3] = {6, 8, 12};
  94. int cc;
  95.    int i;
  96. long size[4], padding[2];         /* Size of Y, U, and V buffers */
  97. if(!video->mpeg2)
  98. {
  99. /* force MPEG-1 parameters */
  100.      video->prog_seq = 1;
  101.      video->prog_frame = 1;
  102.      video->pict_struct = FRAME_PICTURE;
  103.      video->frame_pred_dct = 1;
  104.      video->chroma_format = CHROMA420;
  105.      video->matrix_coefficients = 5;
  106. }
  107. /* Get dimensions rounded to nearest multiple of coded macroblocks */
  108. video->mb_width = (video->horizontal_size + 15) / 16;
  109. video->mb_height = (video->mpeg2 && !video->prog_seq) ? 
  110. (2 * ((video->vertical_size + 31) / 32)) : 
  111. ((video->vertical_size + 15) / 16);
  112. video->coded_picture_width = 16 * video->mb_width;
  113. video->coded_picture_height = 16 * video->mb_height;
  114. video->chrom_width = (video->chroma_format == CHROMA444) ? 
  115. video->coded_picture_width : 
  116. (video->coded_picture_width >> 1);
  117. video->chrom_height = (video->chroma_format != CHROMA420) ? 
  118. video->coded_picture_height : 
  119.                     (video->coded_picture_height >> 1);
  120. video->blk_cnt = blk_cnt_tab[video->chroma_format - 1];
  121. /* Get sizes of YUV buffers */
  122. padding[0] = 16 * video->coded_picture_width;
  123. size[0] = video->coded_picture_width * video->coded_picture_height + padding[0] * 2;
  124. padding[1] = 16 * video->chrom_width;
  125. size[1] = video->chrom_width * video->chrom_height + 2 * padding[1];
  126. size[2] = (video->llw * video->llh);
  127. size[3] = (video->llw * video->llh) / 4;
  128. /* Allocate contiguous fragments for YUV buffers for hardware YUV decoding */
  129. video->yuv_buffer[0] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
  130. video->yuv_buffer[1] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
  131. video->yuv_buffer[2] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
  132.     if(video->scalable_mode == SC_SPAT)
  133. {
  134. video->yuv_buffer[3] = (unsigned char*)calloc(1, size[2] + 2 * size[3]);
  135. video->yuv_buffer[4] = (unsigned char*)calloc(1, size[2] + 2 * size[3]);
  136. }
  137. /* Direct pointers to areas of contiguous fragments in YVU order per Microsoft */
  138. for(cc = 0; cc < 3; cc++)
  139. {
  140. video->llframe0[cc] = 0;
  141. video->llframe1[cc] = 0;
  142. video->newframe[cc] = 0;
  143. }
  144. video->refframe[0]    = video->yuv_buffer[0];
  145. video->oldrefframe[0] = video->yuv_buffer[1];
  146. video->auxframe[0]    = video->yuv_buffer[2];
  147. video->refframe[2]    = video->yuv_buffer[0] + size[0] + padding[0];
  148. video->oldrefframe[2] = video->yuv_buffer[1] + size[0] + padding[0];
  149. video->auxframe[2]    = video->yuv_buffer[2] + size[0] + padding[0];
  150. video->refframe[1]    = video->yuv_buffer[0] + size[0] + padding[0] + size[1] + padding[1];
  151. video->oldrefframe[1] = video->yuv_buffer[1] + size[0] + padding[0] + size[1] + padding[1];
  152. video->auxframe[1]    = video->yuv_buffer[2] + size[0] + padding[0] + size[1] + padding[1];
  153.     if(video->scalable_mode == SC_SPAT)
  154. {
  155. /* this assumes lower layer is 4:2:0 */
  156. video->llframe0[0] = video->yuv_buffer[3] + padding[0]     ;
  157. video->llframe1[0] = video->yuv_buffer[4] + padding[0]     ;
  158. video->llframe0[2] = video->yuv_buffer[3] + padding[1] + size[2]    ;
  159. video->llframe1[2] = video->yuv_buffer[4] + padding[1] + size[2]    ;
  160. video->llframe0[1] = video->yuv_buffer[3] + padding[1] + size[2] + size[3];
  161. video->llframe1[1] = video->yuv_buffer[4] + padding[1] + size[2] + size[3];
  162.     }
  163. /* Initialize the YUV tables for software YUV decoding */
  164. video->cr_to_r = malloc(sizeof(long) * 256);
  165. video->cr_to_g = malloc(sizeof(long) * 256);
  166. video->cb_to_g = malloc(sizeof(long) * 256);
  167. video->cb_to_b = malloc(sizeof(long) * 256);
  168. video->cr_to_r_ptr = video->cr_to_r + 128;
  169. video->cr_to_g_ptr = video->cr_to_g + 128;
  170. video->cb_to_g_ptr = video->cb_to_g + 128;
  171. video->cb_to_b_ptr = video->cb_to_b + 128;
  172. for(i = -128; i < 128; i++)
  173. {
  174. video->cr_to_r_ptr[i] = (long)( 1.371 * 65536 * i);
  175. video->cr_to_g_ptr[i] = (long)(-0.698 * 65536 * i);
  176. video->cb_to_g_ptr[i] = (long)(-0.336 * 65536 * i);
  177. video->cb_to_b_ptr[i] = (long)( 1.732 * 65536 * i);
  178. }
  179. return 0;
  180. }
  181. int mpeg3video_deletedecoder(mpeg3video_t *video)
  182. {
  183. int i, padding;
  184. free(video->yuv_buffer[0]);
  185. free(video->yuv_buffer[1]);
  186. free(video->yuv_buffer[2]);
  187. if(video->llframe0[0])
  188. {
  189. free(video->yuv_buffer[3]);
  190. free(video->yuv_buffer[4]);
  191. }
  192. free(video->cr_to_r);
  193. free(video->cr_to_g);
  194. free(video->cb_to_g);
  195. free(video->cb_to_b);
  196. return 0;
  197. }
  198. void mpeg3video_init_scantables(mpeg3video_t *video)
  199. {
  200. #ifdef HAVE_MMX
  201. if(video->have_mmx)
  202. {
  203. video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_mmx;
  204. video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_mmx;
  205. }
  206. else
  207. #endif
  208. {
  209. video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_nommx;
  210. video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_nommx;
  211. }
  212. }
  213. mpeg3video_t *mpeg3video_allocate_struct(void)
  214. {
  215. int i;
  216. mpeg3video_t *video = calloc(1, sizeof(mpeg3video_t));
  217. #ifndef SDL_THREADS
  218. pthread_mutexattr_t mutex_attr;
  219. #endif
  220. video->vstream = mpeg3bits_new_stream();
  221. //printf("mpeg3video_allocate_struct %dn", mpeg3bits_eof(video->vstream));
  222. video->last_number = -1;
  223. /* First frame is all green */
  224. video->framenum = -1;
  225. video->have_mmx = mpeg3_mmx_test();
  226. video->percentage_seek = -1;
  227. video->frame_seek = -1;
  228. mpeg3video_init_scantables(video);
  229. mpeg3video_init_output();
  230. #ifndef SDL_THREADS
  231. pthread_mutexattr_init(&mutex_attr);
  232. // pthread_mutexattr_setkind_np(&mutex_attr, PTHREAD_MUTEX_FAST_NP);
  233. pthread_mutex_init(&(video->test_lock), &mutex_attr);
  234. pthread_mutex_init(&(video->slice_lock), &mutex_attr);
  235. #else
  236. video->test_lock = SDL_CreateMutex();
  237. video->slice_lock = SDL_CreateMutex();
  238. #endif
  239. return video;
  240. }
  241. int mpeg3video_delete_struct(mpeg3video_t *video)
  242. {
  243. int i;
  244. mpeg3bits_delete_stream(video->vstream);
  245. #ifndef SDL_THREADS
  246. pthread_mutex_destroy(&(video->test_lock));
  247. pthread_mutex_destroy(&(video->slice_lock));
  248. #else
  249. SDL_DestroyMutex(video->test_lock);
  250. SDL_DestroyMutex(video->slice_lock);
  251. #endif
  252. if(video->x_table)
  253. {
  254. free(video->x_table);
  255. free(video->y_table);
  256. }
  257. if(video->total_slice_decoders)
  258. {
  259. for(i = 0; i < video->total_slice_decoders; i++)
  260. mpeg3_delete_slice_decoder(&(video->slice_decoders[i]));
  261. }
  262. for(i = 0; i < video->slice_buffers_initialized; i++)
  263. mpeg3_delete_slice_buffer(&(video->slice_buffers[i]));
  264. free(video);
  265. return 0;
  266. }
  267. int mpeg3video_read_frame_backend(mpeg3video_t *video, int skip_bframes)
  268. {
  269. int result = 0;
  270. if(mpeg3bits_eof(video->vstream)) result = 1;
  271. if(!result) result = mpeg3video_get_header(video, 0);
  272. //printf("frame type %dn", video->pict_type);
  273. /* skip_bframes is the number of bframes we can skip successfully. */
  274. /* This is in case a skipped B-frame is repeated and the second repeat happens */
  275. /* to be a B frame we need. */
  276. video->skip_bframes = skip_bframes;
  277. if(!result)
  278. result = mpeg3video_getpicture(video, video->framenum);
  279. #ifdef HAVE_MMX
  280. if(video->have_mmx)
  281. __asm__ __volatile__ ("emms");
  282. #endif
  283. if(!result)
  284. {
  285. video->last_number = video->framenum;
  286. video->framenum++;
  287. }
  288. return result;
  289. }
  290. int* mpeg3video_get_scaletable(int input_w, int output_w)
  291. {
  292. int *result = malloc(sizeof(int) * output_w);
  293. float i;
  294. float scale = (float)input_w / output_w;
  295. for(i = 0; i < output_w; i++)
  296. {
  297. result[(int)i] = (int)(scale * i);
  298. }
  299. return result;
  300. }
  301. /* Get the first I frame. */
  302. int mpeg3video_get_firstframe(mpeg3video_t *video,
  303.       unsigned char *input, 
  304.       long size)
  305. {
  306. int result = 0;
  307. video->repeat_count = video->current_repeat = 0;
  308. return mpeg3video_process_frame(video, input, size);
  309. }
  310. int mpeg3video_process_frame(mpeg3video_t *video,
  311.      unsigned char *input, 
  312.      long size)
  313. {
  314. mpeg3bits_use_ptr_len(video->vstream, input, size);
  315. return mpeg3video_read_frame_backend(video, 0);
  316. }
  317. static long gop_to_frame(mpeg3video_t *video, mpeg3_timecode_t *gop_timecode)
  318. {
  319. int hour, minute, second, frame, fps;
  320. long result;
  321. // Mirror of what mpeg2enc does
  322. fps = (int)(video->frame_rate + 0.5);
  323. hour = gop_timecode->hour;
  324. minute = gop_timecode->minute;
  325. second = gop_timecode->second;
  326. frame = gop_timecode->frame;
  327. result = (long)hour * 60 * 60 * fps + 
  328. minute * 60 * fps + 
  329. second * fps +
  330. frame;
  331. return result;
  332. }
  333. /* ======================================================================= */
  334. /*                                    ENTRY POINTS */
  335. /* ======================================================================= */
  336. mpeg3video_t* mpeg3video_new(int is_video_stream,
  337.      int cpus)
  338. {
  339. mpeg3video_t *video;
  340. int result = 0;
  341. video = mpeg3video_allocate_struct();
  342. video->cpus = cpus;
  343. return video;
  344. }
  345. int mpeg3video_delete(mpeg3video_t *video)
  346. {
  347. if(video->decoder_initted)
  348. {
  349. mpeg3video_deletedecoder(video);
  350. }
  351. mpeg3video_delete_struct(video);
  352. return 0;
  353. }
  354. int mpeg3video_set_cpus(mpeg3video_t *video, int cpus)
  355. {
  356. return 0;
  357. }
  358. int mpeg3video_set_mmx(mpeg3video_t *video, int use_mmx)
  359. {
  360. video->have_mmx = use_mmx;
  361. mpeg3video_init_scantables(video);
  362. return 0;
  363. }
  364. int mpeg3video_read_frame(mpeg3video_t *video, 
  365.   unsigned char *input,
  366.   long input_size,
  367.   unsigned char **output_rows,
  368.   int in_x, 
  369.   int in_y, 
  370.   int in_w, 
  371.   int in_h, 
  372.   int out_w, 
  373.   int out_h, 
  374.   int color_model)
  375. {
  376. int result = 0;
  377. mpeg3bits_use_ptr_len(video->vstream, input, input_size); 
  378. video->want_yvu = 0;
  379. video->output_rows = output_rows;
  380. video->color_model = color_model;
  381. //printf("mpeg3video_read_frame 1n");
  382. /* Get scaling tables */
  383. if(video->out_w != out_w || video->out_h != out_h ||
  384. video->in_w != in_w || video->in_h != in_h ||
  385. video->in_x != in_x || video->in_y != in_y)
  386. {
  387. if(video->x_table)
  388. {
  389. free(video->x_table);
  390. free(video->y_table);
  391. video->x_table = 0;
  392. video->y_table = 0;
  393. }
  394. }
  395. video->out_w = out_w;
  396. video->out_h = out_h;
  397. video->in_w = in_w;
  398. video->in_h = in_h;
  399. video->in_x = in_x;
  400. video->in_y = in_y;
  401. if(!video->x_table)
  402. {
  403. video->x_table = mpeg3video_get_scaletable(video->in_w, video->out_w);
  404. video->y_table = mpeg3video_get_scaletable(video->in_h, video->out_h);
  405. }
  406. //printf("mpeg3video_read_frame 4n");
  407. if(!result) result = mpeg3video_read_frame_backend(video, 0);
  408. //printf("mpeg3video_read_frame 5n");
  409. if(video->output_src) mpeg3video_present_frame(video);
  410. //printf("mpeg3video_read_frame 6n");
  411. return result;
  412. }
  413. int mpeg3video_read_yuvframe(mpeg3video_t *video, 
  414.      unsigned char *input,
  415.      long input_size,
  416.      char *y_output,
  417.      char *u_output,
  418.      char *v_output,
  419.      int in_x,
  420.      int in_y,
  421.      int in_w,
  422.      int in_h)
  423. {
  424. int result = 0;
  425. mpeg3bits_use_ptr_len(video->vstream, input, input_size); 
  426. video->want_yvu = 1;
  427. video->y_output = y_output;
  428. video->u_output = u_output;
  429. video->v_output = v_output;
  430. video->in_x = in_x;
  431. video->in_y = in_y;
  432. video->in_w = in_w;
  433. video->in_h = in_h;
  434. if(!result) result = mpeg3video_read_frame_backend(video, 0);
  435. if(video->output_src) mpeg3video_present_frame(video);
  436. video->want_yvu = 0;
  437. video->percentage_seek = -1;
  438. return result;
  439. }
  440. int mpeg3video_read_yuvframe_ptr(mpeg3video_t *video, 
  441.  unsigned char *input,
  442.  long input_size,
  443.  char **y_output,
  444.  char **u_output,
  445.  char **v_output)
  446. {
  447. int result = 0;
  448. mpeg3bits_use_ptr_len(video->vstream, input, input_size); 
  449. video->want_yvu = 1;
  450. if(!result) result = mpeg3video_read_frame_backend(video, 0);
  451. if (video->output_src) {
  452. *y_output = video->output_src[0];
  453. *u_output = video->output_src[1];
  454. *v_output = video->output_src[2];
  455. }
  456. video->want_yvu = 0;
  457. video->percentage_seek = -1;
  458. return result;
  459. }
  460. int mpeg3video_colormodel(mpeg3video_t *video)
  461. {
  462. switch(video->chroma_format)
  463. {
  464. case CHROMA422:
  465. return MPEG3_YUV422P;
  466. break;
  467. case CHROMA420:
  468. return MPEG3_YUV420P;
  469. break;
  470. }
  471. return MPEG3_YUV420P;
  472. }