Mercurial > mplayer.hg
comparison dec_video.c @ 1294:0a8e0c7ddd0c
video decoder stuff
author | arpi |
---|---|
date | Sun, 08 Jul 2001 12:29:38 +0000 |
parents | |
children | 200c03672178 |
comparison
equal
deleted
inserted
replaced
1293:1b1213b1d58c | 1294:0a8e0c7ddd0c |
---|---|
1 | |
2 #include <stdio.h> | |
3 #include <stdlib.h> | |
4 | |
5 #include "config.h" | |
6 | |
7 extern int verbose; // defined in mplayer.c | |
8 extern int divx_quality; | |
9 | |
10 extern double video_time_usage; | |
11 extern double vout_time_usage; | |
12 | |
13 #include "stream.h" | |
14 #include "demuxer.h" | |
15 | |
16 #include "wine/mmreg.h" | |
17 #include "wine/avifmt.h" | |
18 #include "wine/vfw.h" | |
19 | |
20 #include "codec-cfg.h" | |
21 #include "stheader.h" | |
22 | |
23 //#include <inttypes.h> | |
24 //#include "libvo/img_format.h" | |
25 | |
26 #include "libvo/video_out.h" | |
27 | |
28 #include "libmpeg2/mpeg2.h" | |
29 #include "libmpeg2/mpeg2_internal.h" | |
30 | |
31 extern picture_t *picture; // exported from libmpeg2/decode.c | |
32 | |
33 extern int init_video_codec(sh_video_t *sh_video); | |
34 | |
35 #ifdef USE_DIRECTSHOW | |
36 #include "loader/DirectShow/DS_VideoDec.h" | |
37 #endif | |
38 | |
39 #ifdef USE_LIBAVCODEC | |
40 #include "libavcodec/avcodec.h" | |
41 AVCodec *lavc_codec=NULL; | |
42 AVCodecContext lavc_context; | |
43 AVPicture lavc_picture; | |
44 #endif | |
45 | |
46 #include "opendivx/decore.h" | |
47 | |
48 //**************************************************************************// | |
49 // The OpenDivX stuff: | |
50 //**************************************************************************// | |
51 | |
52 #ifndef NEW_DECORE | |
53 | |
54 static unsigned char *opendivx_src[3]; | |
55 static int opendivx_stride[3]; | |
56 | |
57 // callback, the opendivx decoder calls this for each frame: | |
58 void convert_linux(unsigned char *puc_y, int stride_y, | |
59 unsigned char *puc_u, unsigned char *puc_v, int stride_uv, | |
60 unsigned char *bmp, int width_y, int height_y){ | |
61 | |
62 // printf("convert_yuv called %dx%d stride: %d,%d\n",width_y,height_y,stride_y,stride_uv); | |
63 | |
64 opendivx_src[0]=puc_y; | |
65 opendivx_src[1]=puc_u; | |
66 opendivx_src[2]=puc_v; | |
67 | |
68 opendivx_stride[0]=stride_y; | |
69 opendivx_stride[1]=stride_uv; | |
70 opendivx_stride[2]=stride_uv; | |
71 } | |
72 #endif | |
73 | |
74 | |
75 int init_video(sh_video_t *sh_video){ | |
76 unsigned int out_fmt=sh_video->codec->outfmt[sh_video->outfmtidx]; | |
77 | |
78 switch(sh_video->codec->driver){ | |
79 case 2: { | |
80 if(!init_video_codec(sh_video)) { | |
81 // GUI_MSG( mplUnknowError ) | |
82 // exit(1); | |
83 return 0; | |
84 } | |
85 if(verbose) printf("INFO: Win32 video codec init OK!\n"); | |
86 break; | |
87 } | |
88 case 4: { // Win32/DirectShow | |
89 #ifndef USE_DIRECTSHOW | |
90 fprintf(stderr,"MPlayer was compiled WITHOUT directshow support!\n"); | |
91 return 0; | |
92 // GUI_MSG( mplCompileWithoutDSSupport ) | |
93 // exit(1); | |
94 #else | |
95 sh_video->our_out_buffer=NULL; | |
96 if(DS_VideoDecoder_Open(sh_video->codec->dll,&sh_video->codec->guid, sh_video->bih, 0, &sh_video->our_out_buffer)){ | |
97 // if(DS_VideoDecoder_Open(sh_video->codec->dll,&sh_video->codec->guid, sh_video->bih, 0, NULL)){ | |
98 printf("ERROR: Couldn't open required DirectShow codec: %s\n",sh_video->codec->dll); | |
99 printf("Maybe you forget to upgrade your win32 codecs?? It's time to download the new\n"); | |
100 printf("package from: ftp://thot.banki.hu/esp-team/linux/MPlayer/w32codec.zip !\n"); | |
101 printf("Or you should disable DShow support: make distclean;make -f Makefile.No-DS\n"); | |
102 return 0; | |
103 // #ifdef HAVE_GUI | |
104 // if ( !nogui ) | |
105 // { | |
106 // strcpy( mplShMem->items.videodata.codecdll,sh_video->codec->dll ); | |
107 // mplSendMessage( mplDSCodecNotFound ); | |
108 // usec_sleep( 10000 ); | |
109 // } | |
110 // #endif | |
111 // exit(1); | |
112 } | |
113 | |
114 switch(out_fmt){ | |
115 case IMGFMT_YUY2: | |
116 case IMGFMT_UYVY: | |
117 DS_VideoDecoder_SetDestFmt(16,out_fmt);break; // packed YUV | |
118 case IMGFMT_YV12: | |
119 case IMGFMT_I420: | |
120 case IMGFMT_IYUV: | |
121 DS_VideoDecoder_SetDestFmt(12,out_fmt);break; // planar YUV | |
122 default: | |
123 DS_VideoDecoder_SetDestFmt(out_fmt&255,0); // RGB/BGR | |
124 } | |
125 | |
126 DS_VideoDecoder_Start(); | |
127 | |
128 DS_SetAttr_DivX("Quality",divx_quality); | |
129 // printf("DivX setting result = %d\n", DS_SetAttr_DivX("Quality",divx_quality) ); | |
130 // printf("DivX setting result = %d\n", DS_SetValue_DivX("Brightness",60) ); | |
131 | |
132 if(verbose) printf("INFO: Win32/DShow video codec init OK!\n"); | |
133 break; | |
134 #endif | |
135 } | |
136 case 3: { // OpenDivX | |
137 if(verbose) printf("OpenDivX video codec\n"); | |
138 { DEC_PARAM dec_param; | |
139 DEC_SET dec_set; | |
140 #ifdef NEW_DECORE | |
141 DEC_MEM_REQS dec_mem; | |
142 dec_param.output_format=DEC_USER; | |
143 #else | |
144 dec_param.color_depth = 32; | |
145 #endif | |
146 dec_param.x_dim = sh_video->bih->biWidth; | |
147 dec_param.y_dim = sh_video->bih->biHeight; | |
148 #ifdef NEW_DECORE | |
149 // 0.50-CVS new malloc scheme | |
150 decore(0x123, DEC_OPT_MEMORY_REQS, &dec_param, &dec_mem); | |
151 dec_param.buffers.mp4_edged_ref_buffers=malloc(dec_mem.mp4_edged_ref_buffers_size); | |
152 dec_param.buffers.mp4_edged_for_buffers=malloc(dec_mem.mp4_edged_for_buffers_size); | |
153 dec_param.buffers.mp4_display_buffers=malloc(dec_mem.mp4_display_buffers_size); | |
154 dec_param.buffers.mp4_state=malloc(dec_mem.mp4_state_size); | |
155 dec_param.buffers.mp4_tables=malloc(dec_mem.mp4_tables_size); | |
156 dec_param.buffers.mp4_stream=malloc(dec_mem.mp4_stream_size); | |
157 #endif | |
158 decore(0x123, DEC_OPT_INIT, &dec_param, NULL); | |
159 | |
160 dec_set.postproc_level = divx_quality; | |
161 decore(0x123, DEC_OPT_SETPP, &dec_set, NULL); | |
162 | |
163 } | |
164 if(verbose) printf("INFO: OpenDivX video codec init OK!\n"); | |
165 break; | |
166 } | |
167 case 5: { // FFmpeg's libavcodec | |
168 #ifndef USE_LIBAVCODEC | |
169 fprintf(stderr,"MPlayer was compiled WITHOUT libavcodec support!\n"); | |
170 return 0; //exit(1); | |
171 #else | |
172 if(verbose) printf("FFmpeg's libavcodec video codec\n"); | |
173 avcodec_init(); | |
174 avcodec_register_all(); | |
175 lavc_codec = (AVCodec *)avcodec_find_decoder_by_name(sh_video->codec->dll); | |
176 if(!lavc_codec){ | |
177 fprintf(stderr,"Can't find codec '%s' in libavcodec...\n",sh_video->codec->dll); | |
178 return 0; //exit(1); | |
179 } | |
180 memset(&lavc_context, 0, sizeof(lavc_context)); | |
181 lavc_context.width=sh_video->disp_w; | |
182 lavc_context.height=sh_video->disp_h; | |
183 printf("libavcodec.size: %d x %d\n",lavc_context.width,lavc_context.height); | |
184 /* open it */ | |
185 if (avcodec_open(&lavc_context, lavc_codec) < 0) { | |
186 fprintf(stderr, "could not open codec\n"); | |
187 return 0; //exit(1); | |
188 } | |
189 | |
190 if(verbose) printf("INFO: libavcodec init OK!\n"); | |
191 break; | |
192 #endif | |
193 } | |
194 | |
195 case 1: { | |
196 // init libmpeg2: | |
197 #ifdef MPEG12_POSTPROC | |
198 picture->pp_options=divx_quality; | |
199 #else | |
200 if(divx_quality){ | |
201 printf("WARNING! You requested image postprocessing for an MPEG 1/2 video,\n"); | |
202 printf(" but compiled MPlayer without MPEG 1/2 postprocessing support!\n"); | |
203 printf(" #define MPEG12_POSTPROC in config.h, and recompile libmpeg2!\n"); | |
204 } | |
205 #endif | |
206 mpeg2_allocate_image_buffers (picture); | |
207 break; | |
208 } | |
209 } | |
210 | |
211 return 1; | |
212 } | |
213 | |
214 int decode_video(vo_functions_t *video_out,sh_video_t *sh_video,unsigned char *start,int in_size,int drop_frame){ | |
215 unsigned int out_fmt=sh_video->codec->outfmt[sh_video->outfmtidx]; | |
216 int blit_frame=0; | |
217 | |
218 //-------------------- Decode a frame: ----------------------- | |
219 switch(sh_video->codec->driver){ | |
220 case 3: { | |
221 // OpenDivX | |
222 unsigned int t=GetTimer(); | |
223 unsigned int t2; | |
224 DEC_FRAME dec_frame; | |
225 #ifdef NEW_DECORE | |
226 DEC_PICTURE dec_pic; | |
227 #endif | |
228 // let's decode | |
229 dec_frame.length = in_size; | |
230 dec_frame.bitstream = start; | |
231 dec_frame.render_flag = 1; | |
232 #ifdef NEW_DECORE | |
233 dec_frame.bmp=&dec_pic; | |
234 dec_pic.y=dec_pic.u=dec_pic.v=NULL; | |
235 #endif | |
236 decore(0x123, 0, &dec_frame, NULL); | |
237 t2=GetTimer();t=t2-t;video_time_usage+=t*0.000001f; | |
238 | |
239 #ifdef NEW_DECORE | |
240 if(dec_pic.y){ | |
241 void* src[3]; | |
242 int stride[3]; | |
243 src[0]=dec_pic.y; | |
244 src[1]=dec_pic.u; | |
245 src[2]=dec_pic.v; | |
246 stride[0]=dec_pic.stride_y; | |
247 stride[1]=stride[2]=dec_pic.stride_uv; | |
248 video_out->draw_slice(src,stride, | |
249 sh_video->disp_w,sh_video->disp_h,0,0); | |
250 blit_frame=1; | |
251 } | |
252 #else | |
253 if(opendivx_src[0]){ | |
254 video_out->draw_slice(opendivx_src,opendivx_stride, | |
255 sh_video->disp_w,sh_video->disp_h,0,0); | |
256 opendivx_src[0]=NULL; | |
257 blit_frame=1; | |
258 } | |
259 #endif | |
260 t2=GetTimer()-t2;vout_time_usage+=t2*0.000001f; | |
261 | |
262 break; | |
263 } | |
264 #ifdef USE_DIRECTSHOW | |
265 case 4: { // W32/DirectShow | |
266 unsigned int t=GetTimer(); | |
267 unsigned int t2; | |
268 | |
269 if(drop_frame<2) DS_VideoDecoder_DecodeFrame(start, in_size, 0, !drop_frame); | |
270 | |
271 if(!drop_frame && sh_video->our_out_buffer){ | |
272 t2=GetTimer();t=t2-t;video_time_usage+=t*0.000001f; | |
273 if(out_fmt==IMGFMT_YV12||out_fmt==IMGFMT_IYUV||out_fmt==IMGFMT_I420){ | |
274 uint8_t* dst[3]; | |
275 int stride[3]; | |
276 stride[0]=sh_video->disp_w; | |
277 stride[1]=stride[2]=sh_video->disp_w/2; | |
278 dst[0]=sh_video->our_out_buffer; | |
279 dst[2]=dst[0]+sh_video->disp_w*sh_video->disp_h; | |
280 dst[1]=dst[2]+sh_video->disp_w*sh_video->disp_h/4; | |
281 video_out->draw_slice(dst,stride,sh_video->disp_w,sh_video->disp_h,0,0); | |
282 } else | |
283 video_out->draw_frame((uint8_t **)&sh_video->our_out_buffer); | |
284 t2=GetTimer()-t2;vout_time_usage+=t2*0.000001f; | |
285 blit_frame=1; | |
286 } | |
287 break; | |
288 } | |
289 #endif | |
290 #ifdef USE_LIBAVCODEC | |
291 case 5: { // libavcodec | |
292 unsigned int t=GetTimer(); | |
293 unsigned int t2; | |
294 int got_picture=0; | |
295 | |
296 if(drop_frame<2 && in_size>0){ | |
297 int ret = avcodec_decode_video(&lavc_context, &lavc_picture, | |
298 &got_picture, start, in_size); | |
299 if(ret<0) fprintf(stderr, "Error while decoding frame!\n"); | |
300 } | |
301 | |
302 if(!drop_frame && got_picture){ | |
303 t2=GetTimer();t=t2-t;video_time_usage+=t*0.000001f; | |
304 video_out->draw_slice(lavc_picture.data,lavc_picture.linesize,sh_video->disp_w,sh_video->disp_h,0,0); | |
305 t2=GetTimer()-t2;vout_time_usage+=t2*0.000001f; | |
306 blit_frame=1; | |
307 } | |
308 | |
309 break; | |
310 } | |
311 #endif | |
312 case 2: { | |
313 HRESULT ret; | |
314 unsigned int t=GetTimer(); | |
315 unsigned int t2; | |
316 | |
317 if(in_size){ | |
318 sh_video->bih->biSizeImage = in_size; | |
319 | |
320 // sh_video->bih->biWidth = 1280; | |
321 // sh_video->o_bih.biWidth = 1280; | |
322 // ret = ICDecompress(avi_header.hic, ICDECOMPRESS_NOTKEYFRAME|(ICDECOMPRESS_HURRYUP|ICDECOMPRESS_PREROL), | |
323 ret = ICDecompress(sh_video->hic, | |
324 ( (sh_video->ds->flags&1) ? 0 : ICDECOMPRESS_NOTKEYFRAME ) | | |
325 ( (drop_frame==2 && !(sh_video->ds->flags&1))?(ICDECOMPRESS_HURRYUP|ICDECOMPRESS_PREROL):0 ) , | |
326 sh_video->bih, start, | |
327 &sh_video->o_bih, | |
328 drop_frame ? 0 : sh_video->our_out_buffer); | |
329 | |
330 if(ret){ printf("Error decompressing frame, err=%d\n",(int)ret);break; } | |
331 } | |
332 // current_module="draw_frame"; | |
333 if(!drop_frame){ | |
334 t2=GetTimer();t=t2-t;video_time_usage+=t*0.000001f; | |
335 // if(out_fmt==IMGFMT_YV12){ | |
336 if(out_fmt==IMGFMT_YV12||out_fmt==IMGFMT_IYUV||out_fmt==IMGFMT_I420){ | |
337 uint8_t* dst[3]; | |
338 int stride[3]; | |
339 stride[0]=sh_video->disp_w; | |
340 stride[1]=stride[2]=sh_video->disp_w/2; | |
341 dst[0]=sh_video->our_out_buffer; | |
342 dst[2]=dst[0]+sh_video->disp_w*sh_video->disp_h; | |
343 dst[1]=dst[2]+sh_video->disp_w*sh_video->disp_h/4; | |
344 video_out->draw_slice(dst,stride,sh_video->disp_w,sh_video->disp_h,0,0); | |
345 } else | |
346 video_out->draw_frame((uint8_t **)&sh_video->our_out_buffer); | |
347 t2=GetTimer()-t2;vout_time_usage+=t2*0.000001f; | |
348 blit_frame=1; | |
349 } | |
350 break; | |
351 } | |
352 case 1: { | |
353 int in_frame=0; | |
354 int t=0; | |
355 float newfps; | |
356 | |
357 t-=GetTimer(); | |
358 mpeg2_decode_data(video_out, start, start+in_size,drop_frame); | |
359 t+=GetTimer(); video_time_usage+=t*0.000001; | |
360 blit_frame=1; | |
361 | |
362 break; | |
363 } | |
364 } // switch | |
365 //------------------------ frame decoded. -------------------- | |
366 | |
367 return blit_frame; | |
368 } |