~gma500/+junk/emgd160

« back to all changes in this revision

Viewing changes to mplayer-vaapi/libmpcodecs/ve_vfw.c

  • Committer: Luca Forina
  • Date: 2011-05-03 09:34:53 UTC
  • Revision ID: luca.forina@gmail.com-20110503093453-p1l4o1ck3g67vrha
added mplayer-vaapi

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of MPlayer.
 
3
 *
 
4
 * MPlayer is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * MPlayer is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License along
 
15
 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
 
16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
17
 */
 
18
 
 
19
#include <stdio.h>
 
20
#include <stdlib.h>
 
21
#include <string.h>
 
22
#include <unistd.h>
 
23
#include <inttypes.h>
 
24
#include <sys/stat.h>
 
25
 
 
26
#include "config.h"
 
27
 
 
28
#include "mp_msg.h"
 
29
#include "help_mp.h"
 
30
 
 
31
#include "codec-cfg.h"
 
32
//#include "stream/stream.h"
 
33
//#include "libmpdemux/demuxer.h"
 
34
//#include "libmpdemux/stheader.h"
 
35
 
 
36
#include "loader/loader.h"
 
37
//#include "loader/wine/mmreg.h"
 
38
#include "loader/wine/vfw.h"
 
39
#include "libmpdemux/aviheader.h"
 
40
#include "loader/wine/winerror.h"
 
41
#include "loader/wine/objbase.h"
 
42
 
 
43
#include "img_format.h"
 
44
#include "mp_image.h"
 
45
#include "vf.h"
 
46
 
 
47
#include "stream/stream.h"
 
48
#include "libmpdemux/muxer.h"
 
49
 
 
50
//===========================================================================//
 
51
 
 
52
static char *vfw_param_codec = NULL;
 
53
static char *vfw_param_compdata = NULL;
 
54
static HRESULT CoInitRes = -1;
 
55
 
 
56
#include "m_option.h"
 
57
 
 
58
const m_option_t vfwopts_conf[]={
 
59
    {"codec", &vfw_param_codec, CONF_TYPE_STRING, 0, 0, 0, NULL},
 
60
    {"compdata", &vfw_param_compdata, CONF_TYPE_STRING, 0, 0, 0, NULL},
 
61
    {NULL, NULL, 0, 0, 0, 0, NULL}
 
62
};
 
63
 
 
64
struct vf_priv_s {
 
65
    muxer_stream_t* mux;
 
66
    BITMAPINFOHEADER* bih;
 
67
};
 
68
 
 
69
static HIC encoder_hic;
 
70
static void* encoder_buf=NULL;
 
71
static int encoder_buf_size=0;
 
72
static int encoder_frameno=0;
 
73
 
 
74
//int init_vfw_encoder(char *dll_name, BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih)
 
75
static BITMAPINFOHEADER* vfw_open_encoder(char *dll_name, char *compdatafile, BITMAPINFOHEADER *input_bih,unsigned int out_fourcc)
 
76
{
 
77
  HRESULT ret;
 
78
  BITMAPINFOHEADER* output_bih=NULL;
 
79
  int temp_len;
 
80
  FILE *fd=NULL;
 
81
  char *drvdata=NULL;
 
82
  struct stat st;
 
83
 
 
84
//sh_video = malloc(sizeof(sh_video_t));
 
85
 
 
86
  mp_msg(MSGT_WIN32,MSGL_V,"======= Win32 (VFW) VIDEO Encoder init =======\n");
 
87
  CoInitRes = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
 
88
//  memset(&sh_video->o_bih, 0, sizeof(BITMAPINFOHEADER));
 
89
//  output_bih->biSize = sizeof(BITMAPINFOHEADER);
 
90
 
 
91
//  encoder_hic = ICOpen( 0x63646976, out_fourcc, ICMODE_COMPRESS);
 
92
    encoder_hic = ICOpen( (long) dll_name, out_fourcc, ICMODE_COMPRESS);
 
93
  if(!encoder_hic){
 
94
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICOpen failed! unknown codec / wrong parameters?\n");
 
95
    return NULL;
 
96
  }
 
97
  mp_msg(MSGT_WIN32,MSGL_INFO,"HIC: %x\n", encoder_hic);
 
98
 
 
99
{
 
100
  ICINFO icinfo;
 
101
 
 
102
  ret = ICGetInfo(encoder_hic, &icinfo, sizeof(ICINFO));
 
103
  mp_msg(MSGT_WIN32,MSGL_INFO,"%ld - %ld - %d\n", ret, icinfo.dwSize, sizeof(ICINFO));
 
104
  mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorType, icinfo.fccType);
 
105
  mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorSubtype, icinfo.fccHandler);
 
106
  mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorFlags,
 
107
    icinfo.dwFlags, icinfo.dwVersion, icinfo.dwVersionICM);
 
108
//printf("Compressor name: %s\n", icinfo.szName);
 
109
//printf("Compressor description: %s\n", icinfo.szDescription);
 
110
 
 
111
mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_Flags);
 
112
if (icinfo.dwFlags & VIDCF_QUALITY)
 
113
    mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_Quality);
 
114
if (icinfo.dwFlags & VIDCF_FASTTEMPORALD)
 
115
    mp_msg(MSGT_WIN32,MSGL_INFO," fast-decompr");
 
116
if (icinfo.dwFlags & VIDCF_QUALITYTIME)
 
117
    mp_msg(MSGT_WIN32,MSGL_INFO," temp-quality");
 
118
mp_msg(MSGT_WIN32,MSGL_INFO,"\n");
 
119
}
 
120
 
 
121
  if(compdatafile){
 
122
    if (!strncmp(compdatafile, "dialog", 6)){
 
123
      if (ICSendMessage(encoder_hic, ICM_CONFIGURE, -1, 0) != ICERR_OK){
 
124
        mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor doesn't have a configure dialog!\n");
 
125
        return NULL;
 
126
      }
 
127
      if (ICSendMessage(encoder_hic, ICM_CONFIGURE, 0, 0) != ICERR_OK){
 
128
        mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor configure dialog failed!\n");
 
129
        return NULL;
 
130
      }
 
131
    }
 
132
    else {
 
133
      if (stat(compdatafile, &st) < 0){
 
134
        mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor data file not found!\n");
 
135
        return NULL;
 
136
      }
 
137
      fd = fopen(compdatafile, "rb");
 
138
      if (!fd){
 
139
        mp_msg(MSGT_WIN32,MSGL_ERR,"Cannot open Compressor data file!\n");
 
140
        return NULL;
 
141
      }
 
142
      drvdata = malloc(st.st_size);
 
143
      if (fread(drvdata, st.st_size, 1, fd) != 1) {
 
144
        mp_msg(MSGT_WIN32,MSGL_ERR,"Cannot read Compressor data file!\n");
 
145
        fclose(fd);
 
146
        free(drvdata);
 
147
        return NULL;
 
148
      }
 
149
      fclose(fd);
 
150
      mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor data %d bytes\n", st.st_size);
 
151
      if (!(temp_len = (unsigned int) ICSendMessage(encoder_hic, ICM_SETSTATE, (LPARAM) drvdata, (int) st.st_size))){
 
152
        mp_msg(MSGT_WIN32,MSGL_ERR,"ICSetState failed!\n");
 
153
        free(drvdata);
 
154
        return NULL;
 
155
      }
 
156
      free(drvdata);
 
157
      mp_msg(MSGT_WIN32,MSGL_INFO,"ICSetState ret: %d\n", temp_len);
 
158
    }
 
159
  }
 
160
 
 
161
  temp_len = ICCompressGetFormatSize(encoder_hic, input_bih);
 
162
  mp_msg(MSGT_WIN32,MSGL_INFO,"ICCompressGetFormatSize ret: %d\n", temp_len);
 
163
 
 
164
  if (temp_len < sizeof(BITMAPINFOHEADER)) temp_len=sizeof(BITMAPINFOHEADER);
 
165
 
 
166
  output_bih = malloc(temp_len+4);
 
167
  memset(output_bih,0,temp_len);
 
168
  output_bih->biSize = temp_len; //sizeof(BITMAPINFOHEADER);
 
169
 
 
170
  return output_bih;
 
171
}
 
172
 
 
173
static int vfw_start_encoder(BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih){
 
174
  HRESULT ret;
 
175
  int temp_len=output_bih->biSize;
 
176
  int i;
 
177
 
 
178
  ret = ICCompressGetFormat(encoder_hic, input_bih, output_bih);
 
179
  if(ret < 0){
 
180
    unsigned char* temp=(unsigned char*)output_bih;
 
181
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressGetFormat failed: Error %d  (0x%X)\n", (int)ret, (int)ret);
 
182
    for (i=0; i < temp_len; i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02x ", temp[i]);
 
183
    return 0;
 
184
  }
 
185
  mp_msg(MSGT_WIN32,MSGL_V,"ICCompressGetFormat OK\n");
 
186
 
 
187
  if (temp_len > sizeof(BITMAPINFOHEADER))
 
188
  {
 
189
    unsigned char* temp=(unsigned char*)output_bih;
 
190
    mp_msg(MSGT_WIN32, MSGL_V, "Extra info in o_bih (%d bytes)!\n",
 
191
        temp_len-sizeof(BITMAPINFOHEADER));
 
192
    for(i=sizeof(output_bih);i<temp_len;i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02X ",temp[i]);
 
193
  }
 
194
 
 
195
//  if( mp_msg_test(MSGT_WIN32,MSGL_V) ) {
 
196
    printf("Starting compression:\n");
 
197
    printf(" Input format:\n");
 
198
        printf("  biSize %ld\n", input_bih->biSize);
 
199
        printf("  biWidth %ld\n", input_bih->biWidth);
 
200
        printf("  biHeight %ld\n", input_bih->biHeight);
 
201
        printf("  biPlanes %d\n", input_bih->biPlanes);
 
202
        printf("  biBitCount %d\n", input_bih->biBitCount);
 
203
        printf("  biCompression 0x%lx ('%.4s')\n", input_bih->biCompression, (char *)&input_bih->biCompression);
 
204
        printf("  biSizeImage %ld\n", input_bih->biSizeImage);
 
205
    printf(" Output format:\n");
 
206
        printf("  biSize %ld\n", output_bih->biSize);
 
207
        printf("  biWidth %ld\n", output_bih->biWidth);
 
208
        printf("  biHeight %ld\n", output_bih->biHeight);
 
209
        printf("  biPlanes %d\n", output_bih->biPlanes);
 
210
        printf("  biBitCount %d\n", output_bih->biBitCount);
 
211
        printf("  biCompression 0x%lx ('%.4s')\n", output_bih->biCompression, (char *)&output_bih->biCompression);
 
212
        printf("  biSizeImage %ld\n", output_bih->biSizeImage);
 
213
//  }
 
214
 
 
215
  output_bih->biWidth=input_bih->biWidth;
 
216
  output_bih->biHeight=input_bih->biHeight;
 
217
 
 
218
  ret = ICCompressQuery(encoder_hic, input_bih, output_bih);
 
219
  if(ret){
 
220
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressQuery failed: Error %d\n", (int)ret);
 
221
    return 0;
 
222
  } else
 
223
  mp_msg(MSGT_WIN32,MSGL_V,"ICCompressQuery OK\n");
 
224
 
 
225
  ret = ICCompressBegin(encoder_hic, input_bih, output_bih);
 
226
  if(ret){
 
227
    mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressBegin failed: Error %d\n", (int)ret);
 
228
//    return 0;
 
229
  } else
 
230
    mp_msg(MSGT_WIN32,MSGL_V,"ICCompressBegin OK\n");
 
231
    mp_msg(MSGT_WIN32,MSGL_INFO," Output format after query/begin:\n");
 
232
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biSize %ld\n", output_bih->biSize);
 
233
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biWidth %ld\n", output_bih->biWidth);
 
234
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biHeight %ld\n", output_bih->biHeight);
 
235
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biPlanes %d\n", output_bih->biPlanes);
 
236
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biBitCount %d\n", output_bih->biBitCount);
 
237
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biCompression 0x%lx ('%.4s')\n", output_bih->biCompression, (char *)&output_bih->biCompression);
 
238
    mp_msg(MSGT_WIN32,MSGL_INFO,"  biSizeImage %ld\n", output_bih->biSizeImage);
 
239
 
 
240
  encoder_buf_size=input_bih->biSizeImage;
 
241
  encoder_buf=malloc(encoder_buf_size);
 
242
  encoder_frameno=0;
 
243
 
 
244
  mp_msg(MSGT_WIN32,MSGL_V,"VIDEO CODEC Init OK!!! ;-)\n");
 
245
  return 1;
 
246
}
 
247
 
 
248
static int vfw_encode_frame(BITMAPINFOHEADER* biOutput,void* OutBuf,
 
249
                     BITMAPINFOHEADER* biInput,void* Image,
 
250
                     long* keyframe, int quality){
 
251
    HRESULT ret;
 
252
 
 
253
//long VFWAPIV ICCompress(
 
254
//      HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpOutputBuf,
 
255
//      LPBITMAPINFOHEADER lpbiInput,void* lpImage,long* lpckid,
 
256
//      long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality,
 
257
//      LPBITMAPINFOHEADER lpbiInputPrev,void* lpImagePrev
 
258
//);
 
259
 
 
260
//    printf("vfw_encode_frame(%p,%p, %p,%p, %p,%d)\n",biOutput,OutBuf,biInput,Image,keyframe,quality);
 
261
 
 
262
    ret=ICCompress(encoder_hic, 0,
 
263
        biOutput, OutBuf,
 
264
        biInput, Image,
 
265
        NULL, keyframe, encoder_frameno, 0, quality,
 
266
        biInput, encoder_buf);
 
267
 
 
268
//    printf("ok. size=%ld\n",biOutput->biSizeImage);
 
269
 
 
270
    memcpy(encoder_buf,Image,encoder_buf_size);
 
271
    ++encoder_frameno;
 
272
 
 
273
    return (int)ret;
 
274
}
 
275
#define mux_v (vf->priv->mux)
 
276
#define vfw_bih (vf->priv->bih)
 
277
 
 
278
static int config(struct vf_instance *vf,
 
279
        int width, int height, int d_width, int d_height,
 
280
        unsigned int flags, unsigned int outfmt){
 
281
 
 
282
    vfw_bih->biWidth=width;
 
283
    vfw_bih->biHeight=height;
 
284
    vfw_bih->biSizeImage=width*height*((vfw_bih->biBitCount+7)/8);
 
285
    mux_v->aspect = (float)d_width/d_height;
 
286
 
 
287
    if(!vfw_start_encoder(vfw_bih, mux_v->bih)) return 0;
 
288
 
 
289
//    mux_v->bih->biWidth=width;
 
290
//    mux_v->bih->biHeight=height;
 
291
//    mux_v->bih->biSizeImage=width*height*((mux_v->bih->biBitCount+7)/8);
 
292
 
 
293
    return 1;
 
294
}
 
295
 
 
296
static int control(struct vf_instance *vf, int request, void* data){
 
297
 
 
298
    return CONTROL_UNKNOWN;
 
299
}
 
300
 
 
301
static int query_format(struct vf_instance *vf, unsigned int fmt){
 
302
    if(fmt==IMGFMT_BGR24) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_FLIPPED;
 
303
    return 0;
 
304
}
 
305
 
 
306
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
 
307
    long flags=0;
 
308
    int ret;
 
309
//    flip_upside_down(vo_image_ptr,vo_image_ptr,3*vo_w,vo_h); // dirty hack
 
310
    ret=vfw_encode_frame(mux_v->bih, mux_v->buffer, vfw_bih, mpi->planes[0], &flags, 10000);
 
311
//    if (ret != ICERR_OK)
 
312
//      return 0;
 
313
    muxer_write_chunk(mux_v,mux_v->bih->biSizeImage,flags, pts, pts);
 
314
    return 1;
 
315
}
 
316
 
 
317
static void uninit(struct vf_instance *vf)
 
318
{
 
319
    HRESULT ret;
 
320
 
 
321
    if(encoder_hic){
 
322
        if(encoder_buf){
 
323
            ret=ICCompressEnd(encoder_hic);
 
324
            if(ret) mp_msg(MSGT_WIN32, MSGL_WARN, "ICCompressEnd failed: %ld\n", ret);
 
325
            free(encoder_buf);
 
326
            encoder_buf=NULL;
 
327
        }
 
328
        ret=ICClose(encoder_hic);
 
329
        if(ret) mp_msg(MSGT_WIN32, MSGL_WARN, "ICClose failed: %ld\n", ret);
 
330
        encoder_hic=0;
 
331
        if ((CoInitRes == S_OK) || (CoInitRes == S_FALSE)) CoUninitialize();
 
332
    }
 
333
}
 
334
 
 
335
//===========================================================================//
 
336
 
 
337
static int vf_open(vf_instance_t *vf, char* args){
 
338
    vf->config=config;
 
339
    vf->default_caps=VFCAP_CONSTANT;
 
340
    vf->control=control;
 
341
    vf->query_format=query_format;
 
342
    vf->put_image=put_image;
 
343
    vf->uninit=uninit;
 
344
    vf->priv=malloc(sizeof(struct vf_priv_s));
 
345
    memset(vf->priv,0,sizeof(struct vf_priv_s));
 
346
    vf->priv->mux=(muxer_stream_t*)args;
 
347
 
 
348
    vfw_bih=calloc(1, sizeof(BITMAPINFOHEADER));
 
349
    vfw_bih->biSize=sizeof(BITMAPINFOHEADER);
 
350
    vfw_bih->biWidth=0; // FIXME ?
 
351
    vfw_bih->biHeight=0;
 
352
    vfw_bih->biPlanes=1;
 
353
    vfw_bih->biBitCount=24;
 
354
    vfw_bih->biCompression=0;
 
355
//    vfw_bih->biSizeImage=vo_w*vo_h*((vfw_bih->biBitCount+7)/8);
 
356
 
 
357
    if (!vfw_param_codec)
 
358
    {
 
359
        mp_msg(MSGT_WIN32,MSGL_WARN, MSGTR_MPCODECS_NoVfwCodecSpecified);
 
360
        return 0;
 
361
    }
 
362
//    mux_v->bih=vfw_open_encoder("divxc32.dll",vfw_bih,mmioFOURCC('D', 'I', 'V', '3'));
 
363
//    mux_v->bih=vfw_open_encoder("AvidAVICodec.dll",vfw_bih, 0);
 
364
    mux_v->bih = vfw_open_encoder(vfw_param_codec, vfw_param_compdata, vfw_bih, 0);
 
365
    if(!mux_v->bih) return 0;
 
366
 
 
367
    return 1;
 
368
}
 
369
 
 
370
const vf_info_t ve_info_vfw = {
 
371
    "Win32/VfW encoders",
 
372
    "vfw",
 
373
    "A'rpi",
 
374
    "for internal use by mencoder",
 
375
    vf_open
 
376
};
 
377
 
 
378
//===========================================================================//