13 #include "codec-cfg.h"
15 //#include "demuxer.h"
16 //#include "stheader.h"
19 //#include "wine/mmreg.h"
21 #include "wine/avifmt.h"
23 #include "img_format.h"
29 //===========================================================================//
31 static char *vfw_param_codec
= NULL
;
35 m_option_t vfwopts_conf
[]={
36 {"codec", &vfw_param_codec
, CONF_TYPE_STRING
, 0, 0, 0, NULL
},
37 {NULL
, NULL
, 0, 0, 0, 0, NULL
}
42 BITMAPINFOHEADER
* bih
;
45 static HIC encoder_hic
;
46 static void* encoder_buf
=NULL
;
47 static int encoder_buf_size
=0;
48 static int encoder_frameno
=0;
50 //int init_vfw_encoder(char *dll_name, BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih)
51 static BITMAPINFOHEADER
* vfw_open_encoder(char *dll_name
, BITMAPINFOHEADER
*input_bih
,unsigned int out_fourcc
)
54 BITMAPINFOHEADER
* output_bih
=NULL
;
57 //sh_video = malloc(sizeof(sh_video_t));
59 mp_msg(MSGT_WIN32
,MSGL_V
,"======= Win32 (VFW) VIDEO Encoder init =======\n");
61 // memset(&sh_video->o_bih, 0, sizeof(BITMAPINFOHEADER));
62 // output_bih->biSize = sizeof(BITMAPINFOHEADER);
64 // encoder_hic = ICOpen( 0x63646976, out_fourcc, ICMODE_COMPRESS);
65 encoder_hic
= ICOpen( (long) dll_name
, out_fourcc
, ICMODE_COMPRESS
);
67 mp_msg(MSGT_WIN32
,MSGL_ERR
,"ICOpen failed! unknown codec / wrong parameters?\n");
70 mp_msg(MSGT_WIN32
,MSGL_INFO
,"HIC: %x\n", encoder_hic
);
76 ret
= ICGetInfo(encoder_hic
, &icinfo
, sizeof(ICINFO
));
77 mp_msg(MSGT_WIN32
,MSGL_INFO
,"%ld - %ld - %d\n", ret
, icinfo
.dwSize
, sizeof(ICINFO
));
78 mp_msg(MSGT_WIN32
,MSGL_INFO
,MSGTR_MPCODECS_CompressorType
, icinfo
.fccType
);
79 mp_msg(MSGT_WIN32
,MSGL_INFO
,MSGTR_MPCODECS_CompressorSubtype
, icinfo
.fccHandler
);
80 mp_msg(MSGT_WIN32
,MSGL_INFO
,MSGTR_MPCODECS_CompressorFlags
,
81 icinfo
.dwFlags
, icinfo
.dwVersion
, icinfo
.dwVersionICM
);
82 //printf("Compressor name: %s\n", icinfo.szName);
83 //printf("Compressor description: %s\n", icinfo.szDescription);
85 mp_msg(MSGT_WIN32
,MSGL_INFO
,MSGTR_MPCODECS_Flags
);
86 if (icinfo
.dwFlags
& VIDCF_QUALITY
)
87 mp_msg(MSGT_WIN32
,MSGL_INFO
,MSGTR_MPCODECS_Quality
);
88 if (icinfo
.dwFlags
& VIDCF_FASTTEMPORALD
)
89 mp_msg(MSGT_WIN32
,MSGL_INFO
," fast-decompr");
90 if (icinfo
.dwFlags
& VIDCF_QUALITYTIME
)
91 mp_msg(MSGT_WIN32
,MSGL_INFO
," temp-quality");
92 mp_msg(MSGT_WIN32
,MSGL_INFO
,"\n");
96 temp_len
= ICCompressGetFormatSize(encoder_hic
, input_bih
);
97 mp_msg(MSGT_WIN32
,MSGL_INFO
,"ICCompressGetFormatSize ret: %d\n", temp_len
);
99 if (temp_len
< sizeof(BITMAPINFOHEADER
)) temp_len
=sizeof(BITMAPINFOHEADER
);
101 output_bih
= malloc(temp_len
+4);
102 memset(output_bih
,0,temp_len
);
103 output_bih
->biSize
= temp_len
; //sizeof(BITMAPINFOHEADER);
108 static int vfw_start_encoder(BITMAPINFOHEADER
*input_bih
, BITMAPINFOHEADER
*output_bih
){
110 int temp_len
=output_bih
->biSize
;
113 ret
= ICCompressGetFormat(encoder_hic
, input_bih
, output_bih
);
115 unsigned char* temp
=(unsigned char*)output_bih
;
116 mp_msg(MSGT_WIN32
,MSGL_ERR
,"ICCompressGetFormat failed: Error %d (0x%X)\n", (int)ret
, (int)ret
);
117 for (i
=0; i
< temp_len
; i
++) mp_msg(MSGT_WIN32
, MSGL_DBG2
, "%02x ", temp
[i
]);
120 mp_msg(MSGT_WIN32
,MSGL_V
,"ICCompressGetFormat OK\n");
122 if (temp_len
> sizeof(BITMAPINFOHEADER
))
124 unsigned char* temp
=(unsigned char*)output_bih
;
125 mp_msg(MSGT_WIN32
, MSGL_V
, "Extra info in o_bih (%d bytes)!\n",
126 temp_len
-sizeof(BITMAPINFOHEADER
));
127 for(i
=sizeof(output_bih
);i
<temp_len
;i
++) mp_msg(MSGT_WIN32
, MSGL_DBG2
, "%02X ",temp
[i
]);
130 // if( mp_msg_test(MSGT_WIN32,MSGL_V) ) {
131 printf("Starting compression:\n");
132 printf(" Input format:\n");
133 printf(" biSize %d\n", input_bih
->biSize
);
134 printf(" biWidth %d\n", input_bih
->biWidth
);
135 printf(" biHeight %d\n", input_bih
->biHeight
);
136 printf(" biPlanes %d\n", input_bih
->biPlanes
);
137 printf(" biBitCount %d\n", input_bih
->biBitCount
);
138 printf(" biCompression 0x%x ('%.4s')\n", input_bih
->biCompression
, (char *)&input_bih
->biCompression
);
139 printf(" biSizeImage %d\n", input_bih
->biSizeImage
);
140 printf(" Output format:\n");
141 printf(" biSize %d\n", output_bih
->biSize
);
142 printf(" biWidth %d\n", output_bih
->biWidth
);
143 printf(" biHeight %d\n", output_bih
->biHeight
);
144 printf(" biPlanes %d\n", output_bih
->biPlanes
);
145 printf(" biBitCount %d\n", output_bih
->biBitCount
);
146 printf(" biCompression 0x%x ('%.4s')\n", output_bih
->biCompression
, (char *)&output_bih
->biCompression
);
147 printf(" biSizeImage %d\n", output_bih
->biSizeImage
);
150 output_bih
->biWidth
=input_bih
->biWidth
;
151 output_bih
->biHeight
=input_bih
->biHeight
;
153 ret
= ICCompressQuery(encoder_hic
, input_bih
, output_bih
);
155 mp_msg(MSGT_WIN32
,MSGL_ERR
,"ICCompressQuery failed: Error %d\n", (int)ret
);
158 mp_msg(MSGT_WIN32
,MSGL_V
,"ICCompressQuery OK\n");
160 ret
= ICCompressBegin(encoder_hic
, input_bih
, output_bih
);
162 mp_msg(MSGT_WIN32
,MSGL_ERR
,"ICCompressBegin failed: Error %d\n", (int)ret
);
165 mp_msg(MSGT_WIN32
,MSGL_V
,"ICCompressBegin OK\n");
166 mp_msg(MSGT_WIN32
,MSGL_INFO
," Output format after query/begin:\n");
167 mp_msg(MSGT_WIN32
,MSGL_INFO
," biSize %d\n", output_bih
->biSize
);
168 mp_msg(MSGT_WIN32
,MSGL_INFO
," biWidth %d\n", output_bih
->biWidth
);
169 mp_msg(MSGT_WIN32
,MSGL_INFO
," biHeight %d\n", output_bih
->biHeight
);
170 mp_msg(MSGT_WIN32
,MSGL_INFO
," biPlanes %d\n", output_bih
->biPlanes
);
171 mp_msg(MSGT_WIN32
,MSGL_INFO
," biBitCount %d\n", output_bih
->biBitCount
);
172 mp_msg(MSGT_WIN32
,MSGL_INFO
," biCompression 0x%x ('%.4s')\n", output_bih
->biCompression
, (char *)&output_bih
->biCompression
);
173 mp_msg(MSGT_WIN32
,MSGL_INFO
," biSizeImage %d\n", output_bih
->biSizeImage
);
175 encoder_buf_size
=input_bih
->biSizeImage
;
176 encoder_buf
=malloc(encoder_buf_size
);
179 mp_msg(MSGT_WIN32
,MSGL_V
,"VIDEO CODEC Init OK!!! ;-)\n");
183 static int vfw_encode_frame(BITMAPINFOHEADER
* biOutput
,void* OutBuf
,
184 BITMAPINFOHEADER
* biInput
,void* Image
,
185 long* keyframe
, int quality
){
188 //long VFWAPIV ICCompress(
189 // HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpOutputBuf,
190 // LPBITMAPINFOHEADER lpbiInput,void* lpImage,long* lpckid,
191 // long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality,
192 // LPBITMAPINFOHEADER lpbiInputPrev,void* lpImagePrev
195 // printf("vfw_encode_frame(%p,%p, %p,%p, %p,%d)\n",biOutput,OutBuf,biInput,Image,keyframe,quality);
197 ret
=ICCompress(encoder_hic
, 0,
200 NULL
, keyframe
, encoder_frameno
, 0, quality
,
201 biInput
, encoder_buf
);
203 // printf("ok. size=%d\n",biOutput->biSizeImage);
205 memcpy(encoder_buf
,Image
,encoder_buf_size
);
210 #define mux_v (vf->priv->mux)
211 #define vfw_bih (vf->priv->bih)
213 static int config(struct vf_instance_s
* vf
,
214 int width
, int height
, int d_width
, int d_height
,
215 unsigned int flags
, unsigned int outfmt
){
217 vfw_bih
->biWidth
=width
;
218 vfw_bih
->biHeight
=height
;
219 vfw_bih
->biSizeImage
=width
*height
*((vfw_bih
->biBitCount
+7)/8);
220 mux_v
->aspect
= (float)d_width
/d_height
;
222 if(!vfw_start_encoder(vfw_bih
, mux_v
->bih
)) return 0;
224 // mux_v->bih->biWidth=width;
225 // mux_v->bih->biHeight=height;
226 // mux_v->bih->biSizeImage=width*height*((mux_v->bih->biBitCount+7)/8);
231 static int control(struct vf_instance_s
* vf
, int request
, void* data
){
233 return CONTROL_UNKNOWN
;
236 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
237 if(fmt
==IMGFMT_BGR24
) return VFCAP_CSP_SUPPORTED
| VFCAP_CSP_SUPPORTED_BY_HW
| VFCAP_FLIPPED
;
241 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
244 // flip_upside_down(vo_image_ptr,vo_image_ptr,3*vo_w,vo_h); // dirty hack
245 ret
=vfw_encode_frame(mux_v
->bih
, mux_v
->buffer
, vfw_bih
, mpi
->planes
[0], &flags
, 10000);
246 muxer_write_chunk(mux_v
,mux_v
->bih
->biSizeImage
,flags
, pts
, pts
);
250 //===========================================================================//
252 static int vf_open(vf_instance_t
*vf
, char* args
){
254 vf
->default_caps
=VFCAP_CONSTANT
;
256 vf
->query_format
=query_format
;
257 vf
->put_image
=put_image
;
258 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
259 memset(vf
->priv
,0,sizeof(struct vf_priv_s
));
260 vf
->priv
->mux
=(muxer_stream_t
*)args
;
262 vfw_bih
=calloc(1, sizeof(BITMAPINFOHEADER
));
263 vfw_bih
->biSize
=sizeof(BITMAPINFOHEADER
);
264 vfw_bih
->biWidth
=0; // FIXME ?
267 vfw_bih
->biBitCount
=24;
268 vfw_bih
->biCompression
=0;
269 // vfw_bih->biSizeImage=vo_w*vo_h*((vfw_bih->biBitCount+7)/8);
271 if (!vfw_param_codec
)
273 mp_msg(MSGT_WIN32
,MSGL_WARN
, MSGTR_MPCODECS_NoVfwCodecSpecified
);
276 // mux_v->bih=vfw_open_encoder("divxc32.dll",vfw_bih,mmioFOURCC('D', 'I', 'V', '3'));
277 // mux_v->bih=vfw_open_encoder("AvidAVICodec.dll",vfw_bih, 0);
278 mux_v
->bih
= vfw_open_encoder(vfw_param_codec
, vfw_bih
, 0);
279 if(!mux_v
->bih
) return 0;
284 vf_info_t ve_info_vfw
= {
285 "Win32/VfW encoders",
288 "for internal use by mencoder",
292 //===========================================================================//