~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libmpcodecs/ve_vfw.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <unistd.h>
 
5
#include <inttypes.h>
 
6
 
 
7
#include "config.h"
 
8
#ifdef USE_WIN32DLL
 
9
 
 
10
#include "mp_msg.h"
 
11
 
 
12
#include "codec-cfg.h"
 
13
//#include "stream.h"
 
14
//#include "demuxer.h"
 
15
//#include "stheader.h"
 
16
 
 
17
#include "loader.h"
 
18
//#include "wine/mmreg.h"
 
19
#include "wine/vfw.h"
 
20
#include "wine/avifmt.h"
 
21
 
 
22
#include "img_format.h"
 
23
#include "mp_image.h"
 
24
#include "vf.h"
 
25
 
 
26
#include "muxer.h"
 
27
 
 
28
//===========================================================================//
 
29
 
 
30
static char *vfw_param_codec = NULL;
 
31
 
 
32
#include "m_option.h"
 
33
 
 
34
m_option_t vfwopts_conf[]={
 
35
    {"codec", &vfw_param_codec, CONF_TYPE_STRING, 0, 0, 0, NULL},
 
36
    {NULL, NULL, 0, 0, 0, 0, NULL}
 
37
};
 
38
 
 
39
struct vf_priv_s {
 
40
    muxer_stream_t* mux;
 
41
    BITMAPINFOHEADER* bih;
 
42
};
 
43
 
 
44
static HIC encoder_hic;
 
45
static void* encoder_buf=NULL;
 
46
static int encoder_buf_size=0;
 
47
static int encoder_frameno=0;
 
48
 
 
49
//int init_vfw_encoder(char *dll_name, BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih)
 
50
static BITMAPINFOHEADER* vfw_open_encoder(char *dll_name, BITMAPINFOHEADER *input_bih,unsigned int out_fourcc)
 
51
{
 
52
  HRESULT ret;
 
53
  BITMAPINFOHEADER* output_bih=NULL;
 
54
  int temp_len;
 
55
 
 
56
//sh_video = malloc(sizeof(sh_video_t));
 
57
 
 
58
  mp_msg(MSGT_WIN32,MSGL_V,"======= Win32 (VFW) VIDEO Encoder init =======\n");
 
59
 
 
60
//  memset(&sh_video->o_bih, 0, sizeof(BITMAPINFOHEADER));
 
61
//  output_bih->biSize = sizeof(BITMAPINFOHEADER);
 
62
 
 
63
//  encoder_hic = ICOpen( 0x63646976, out_fourcc, ICMODE_COMPRESS);
 
64
    encoder_hic = ICOpen( (long) dll_name, out_fourcc, ICMODE_COMPRESS);
 
65
  if(!encoder_hic){
 
66
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICOpen failed! unknown codec / wrong parameters?\n");
 
67
    return NULL;
 
68
  }
 
69
  printf("HIC: %x\n", encoder_hic);
 
70
 
 
71
#if 1
 
72
{
 
73
  ICINFO icinfo;
 
74
 
 
75
  ret = ICGetInfo(encoder_hic, &icinfo, sizeof(ICINFO));
 
76
  printf("%ld - %ld - %d\n", ret, icinfo.dwSize, sizeof(ICINFO));
 
77
printf("Compressor type: %.4lx\n", icinfo.fccType);
 
78
printf("Compressor subtype: %.4lx\n", icinfo.fccHandler);
 
79
printf("Compressor flags: %lu, version %lu, ICM version: %lu\n",
 
80
    icinfo.dwFlags, icinfo.dwVersion, icinfo.dwVersionICM);
 
81
//printf("Compressor name: %s\n", icinfo.szName);
 
82
//printf("Compressor description: %s\n", icinfo.szDescription);
 
83
 
 
84
printf("Flags:");
 
85
if (icinfo.dwFlags & VIDCF_QUALITY)
 
86
    printf(" quality");
 
87
if (icinfo.dwFlags & VIDCF_FASTTEMPORALD)
 
88
    printf(" fast-decompr");
 
89
if (icinfo.dwFlags & VIDCF_QUALITYTIME)
 
90
    printf(" temp-quality");
 
91
printf("\n");
 
92
}
 
93
#endif
 
94
 
 
95
  temp_len = ICCompressGetFormatSize(encoder_hic, input_bih);
 
96
  printf("ICCompressGetFormatSize ret: %d\n", temp_len);
 
97
 
 
98
  if (temp_len < sizeof(BITMAPINFOHEADER)) temp_len=sizeof(BITMAPINFOHEADER);
 
99
 
 
100
  output_bih = malloc(temp_len+4);
 
101
  memset(output_bih,0,temp_len);
 
102
  output_bih->biSize = temp_len; //sizeof(BITMAPINFOHEADER);
 
103
 
 
104
  return output_bih;
 
105
}
 
106
 
 
107
static int vfw_start_encoder(BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih){
 
108
  HRESULT ret;
 
109
  int temp_len=output_bih->biSize;
 
110
  int i;
 
111
 
 
112
  ret = ICCompressGetFormat(encoder_hic, input_bih, output_bih);
 
113
  if(ret < 0){
 
114
    unsigned char* temp=(unsigned char*)output_bih;
 
115
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressGetFormat failed: Error %d  (0x%X)\n", (int)ret, (int)ret);
 
116
    for (i=0; i < temp_len; i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02x ", temp[i]);
 
117
    return 0;
 
118
  }
 
119
  mp_msg(MSGT_WIN32,MSGL_V,"ICCompressGetFormat OK\n");
 
120
  
 
121
  if (temp_len > sizeof(BITMAPINFOHEADER))
 
122
  {
 
123
    unsigned char* temp=(unsigned char*)output_bih;
 
124
    mp_msg(MSGT_WIN32, MSGL_V, "Extra info in o_bih (%d bytes)!\n",
 
125
        temp_len-sizeof(BITMAPINFOHEADER));
 
126
    for(i=sizeof(output_bih);i<temp_len;i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02X ",temp[i]);
 
127
  }
 
128
 
 
129
//  if(verbose) {
 
130
    printf("Starting compression:\n");
 
131
    printf(" Input format:\n");
 
132
        printf("  biSize %d\n", input_bih->biSize);
 
133
        printf("  biWidth %d\n", input_bih->biWidth);
 
134
        printf("  biHeight %d\n", input_bih->biHeight);
 
135
        printf("  biPlanes %d\n", input_bih->biPlanes);
 
136
        printf("  biBitCount %d\n", input_bih->biBitCount);
 
137
        printf("  biCompression 0x%x ('%.4s')\n", input_bih->biCompression, (char *)&input_bih->biCompression);
 
138
        printf("  biSizeImage %d\n", input_bih->biSizeImage);
 
139
    printf(" Output format:\n");
 
140
        printf("  biSize %d\n", output_bih->biSize);
 
141
        printf("  biWidth %d\n", output_bih->biWidth);
 
142
        printf("  biHeight %d\n", output_bih->biHeight);
 
143
        printf("  biPlanes %d\n", output_bih->biPlanes);
 
144
        printf("  biBitCount %d\n", output_bih->biBitCount);
 
145
        printf("  biCompression 0x%x ('%.4s')\n", output_bih->biCompression, (char *)&output_bih->biCompression);
 
146
        printf("  biSizeImage %d\n", output_bih->biSizeImage);
 
147
//  }
 
148
 
 
149
  output_bih->biWidth=input_bih->biWidth;
 
150
  output_bih->biHeight=input_bih->biHeight;
 
151
 
 
152
  ret = ICCompressQuery(encoder_hic, input_bih, output_bih);
 
153
  if(ret){
 
154
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressQuery failed: Error %d\n", (int)ret);
 
155
    return 0;
 
156
  } else
 
157
  mp_msg(MSGT_WIN32,MSGL_V,"ICCompressQuery OK\n");
 
158
 
 
159
  ret = ICCompressBegin(encoder_hic, input_bih, output_bih);
 
160
  if(ret){
 
161
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressBegin failed: Error %d\n", (int)ret);
 
162
//    return 0;
 
163
  } else
 
164
  mp_msg(MSGT_WIN32,MSGL_V,"ICCompressBegin OK\n");
 
165
 
 
166
    printf(" Output format after query/begin:\n");
 
167
        printf("  biSize %d\n", output_bih->biSize);
 
168
        printf("  biWidth %d\n", output_bih->biWidth);
 
169
        printf("  biHeight %d\n", output_bih->biHeight);
 
170
        printf("  biPlanes %d\n", output_bih->biPlanes);
 
171
        printf("  biBitCount %d\n", output_bih->biBitCount);
 
172
        printf("  biCompression 0x%x ('%.4s')\n", output_bih->biCompression, (char *)&output_bih->biCompression);
 
173
        printf("  biSizeImage %d\n", output_bih->biSizeImage);
 
174
  
 
175
  encoder_buf_size=input_bih->biSizeImage;
 
176
  encoder_buf=malloc(encoder_buf_size);
 
177
  encoder_frameno=0;
 
178
 
 
179
  mp_msg(MSGT_WIN32,MSGL_V,"VIDEO CODEC Init OK!!! ;-)\n");
 
180
  return 1;
 
181
}
 
182
 
 
183
static int vfw_encode_frame(BITMAPINFOHEADER* biOutput,void* OutBuf,
 
184
                     BITMAPINFOHEADER* biInput,void* Image,
 
185
                     long* keyframe, int quality){
 
186
    HRESULT ret;
 
187
 
 
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
 
193
//);
 
194
 
 
195
//    printf("vfw_encode_frame(%p,%p, %p,%p, %p,%d)\n",biOutput,OutBuf,biInput,Image,keyframe,quality);
 
196
 
 
197
    ret=ICCompress(encoder_hic, 0,
 
198
        biOutput, OutBuf,
 
199
        biInput, Image,
 
200
        NULL, keyframe, encoder_frameno, 0, quality,
 
201
        biInput, encoder_buf);
 
202
 
 
203
//    printf("ok. size=%d\n",biOutput->biSizeImage);
 
204
 
 
205
    memcpy(encoder_buf,Image,encoder_buf_size);
 
206
    ++encoder_frameno;
 
207
 
 
208
    return (int)ret;
 
209
}
 
210
#define mux_v (vf->priv->mux)
 
211
#define vfw_bih (vf->priv->bih)
 
212
 
 
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){
 
216
 
 
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;
 
221
 
 
222
    if(!vfw_start_encoder(vfw_bih, mux_v->bih)) return 0;
 
223
 
 
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);
 
227
 
 
228
    return 1;
 
229
}
 
230
 
 
231
static int control(struct vf_instance_s* vf, int request, void* data){
 
232
 
 
233
    return CONTROL_UNKNOWN;
 
234
}
 
235
 
 
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;
 
238
    return 0;
 
239
}
 
240
 
 
241
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
 
242
    long flags=0;
 
243
    int ret;
 
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);
 
247
    return 1;
 
248
}
 
249
 
 
250
//===========================================================================//
 
251
 
 
252
static int vf_open(vf_instance_t *vf, char* args){
 
253
    vf->config=config;
 
254
    vf->default_caps=VFCAP_CONSTANT;
 
255
    vf->control=control;
 
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;
 
261
 
 
262
    vfw_bih=calloc(1, sizeof(BITMAPINFOHEADER));
 
263
    vfw_bih->biSize=sizeof(BITMAPINFOHEADER);
 
264
    vfw_bih->biWidth=0; // FIXME ?
 
265
    vfw_bih->biHeight=0;
 
266
    vfw_bih->biPlanes=1;
 
267
    vfw_bih->biBitCount=24;
 
268
    vfw_bih->biCompression=0;
 
269
//    vfw_bih->biSizeImage=vo_w*vo_h*((vfw_bih->biBitCount+7)/8);
 
270
 
 
271
    if (!vfw_param_codec)
 
272
    {
 
273
        printf("No VfW codec specified! It's required!\n");
 
274
        return 0;
 
275
    }
 
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;
 
280
 
 
281
    return 1;
 
282
}
 
283
 
 
284
vf_info_t ve_info_vfw = {
 
285
    "Win32/VfW encoders",
 
286
    "vfw",
 
287
    "A'rpi",
 
288
    "for internal use by mencoder",
 
289
    vf_open
 
290
};
 
291
 
 
292
//===========================================================================//
 
293
#endif