summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarpi_esp <arpi_esp@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-03-20 22:11:38 +0000
committerarpi_esp <arpi_esp@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-03-20 22:11:38 +0000
commit86fd259ec33d68258b08e6f2d18285677e5af448 (patch)
tree977a2976faabbb9d0bc4dd08eaa3aaf11c7fb6c9
parent8b72384757f4bcfbd87c572bb1d41cf3ca0c0b03 (diff)
downloadmpv-86fd259ec33d68258b08e6f2d18285677e5af448.tar.bz2
mpv-86fd259ec33d68258b08e6f2d18285677e5af448.tar.xz
added DirectShow support
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@176 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--codecs.c15
-rw-r--r--mplayer.c119
2 files changed, 128 insertions, 6 deletions
diff --git a/codecs.c b/codecs.c
index 25e51136c6..b5e2109424 100644
--- a/codecs.c
+++ b/codecs.c
@@ -1,4 +1,8 @@
//#define ANGELPOTION
+//#define USE_DIRECTSHOW
+
+static GUID CLSID_DivxDecompressorCF={0x82CCd3E0, 0xF71A, 0x11D0,
+ { 0x9f, 0xe5, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa}};
char* get_vids_codec_name(){
// unsigned long fccHandler=avi_header.video.fccHandler;
@@ -6,6 +10,8 @@ char* get_vids_codec_name(){
avi_header.yuv_supported=0;
avi_header.yuv_hack_needed=0;
avi_header.flipped=0;
+ avi_header.vids_guid=NULL;
+
switch(fccHandler){
case mmioFOURCC('M', 'P', 'G', '4'):
case mmioFOURCC('m', 'p', 'g', '4'):
@@ -49,11 +55,17 @@ char* get_vids_codec_name(){
case mmioFOURCC('m', 'p', '4', '1'):
printf("Video in DivX ;-) format\n");
avi_header.yuv_supported=1;
+#ifdef USE_DIRECTSHOW
+ avi_header.vids_guid=&CLSID_DivxDecompressorCF;
+ return "divx_c32.ax";
+#else
avi_header.yuv_hack_needed=1;
#ifdef ANGELPOTION
return "APmpg4v1.dll";
-#endif
+#else
return "divxc32.dll";
+#endif
+#endif
case mmioFOURCC('I', 'V', '5', '0'):
case mmioFOURCC('i', 'v', '5', '0'):
@@ -131,6 +143,7 @@ char* get_vids_codec_name(){
char* get_auds_codec_name(){
int id=((WAVEFORMATEX*)avi_header.wf_ext)->wFormatTag;
+ avi_header.auds_guid=NULL;
switch (id){
case 0x161://DivX audio
// ((WAVEFORMATEX*)avi_header.wf_ext)->wFormatTag=0x160; //hack
diff --git a/mplayer.c b/mplayer.c
index dbf30d977c..02d3911a14 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -48,6 +48,18 @@
#include "loader.h"
#include "wine/avifmt.h"
+typedef struct
+{
+ long f1;
+ short f2;
+ short f3;
+ char f4[8];
+} GUID;
+
+#ifdef USE_DIRECTSHOW
+#include "DirectShow/DS_VideoDec.h"
+#endif
+
#include "opendivx/decore.h"
@@ -116,17 +128,19 @@ typedef struct {
BITMAPINFOHEADER bih; // in format
BITMAPINFOHEADER o_bih; // out format
HIC hic;
- void *our_out_buffer;
+ char *our_out_buffer;
unsigned int bitrate;
// video format flags: (filled by codecs.c)
char yuv_supported; // 1 if codec support YUY2 output format
char yuv_hack_needed; // requires for divx & mpeg4
char no_32bpp_support; // requires for INDEO 3.x, 4.x
char flipped; // image is upside-down
+ GUID* vids_guid;
// audio:
AVIStreamHeader audio;
char *audio_codec;
int audio_seekable;
+ GUID* auds_guid;
char wf_ext[64]; // in format
WAVEFORMATEX wf; // out format
HACMSTREAM srcstream;
@@ -331,8 +345,8 @@ int f; // filedes
int stream_type;
stream_t* stream=NULL;
int file_format=DEMUXER_TYPE_UNKNOWN;
-int has_audio=1; // audio format 0=none 1=mpeg 2=pcm 3=ac3 4=win32 5=alaw 6=msgsm
-int has_video=0; // video format 0=none 1=mpeg 2=win32 3=OpenDivX
+int has_audio=1; // audio format 0=no 1=mpeg 2=pcm 3=ac3 4=win32 5=alaw 6=msgsm
+int has_video=0; // video format 0=no 1=mpeg 2=win32/VfW 3=OpenDivX 4=w32/DShow
//
int audio_format=0; // override
#ifdef ALSA_TIMER
@@ -750,8 +764,7 @@ if(has_video==2){
// if(avi_header.bih.biCompression==mmioFOURCC('D', 'I', 'V', 'X')) has_video=3; // Gabucino
}
-switch(has_video){
- case 2: {
+if(has_video==2){
if(!avi_header.video_codec) avi_header.video_codec=get_vids_codec_name();
if(verbose)
printf("win32 video codec: '%s' %s%s%s\n",avi_header.video_codec,
@@ -760,6 +773,17 @@ switch(has_video){
avi_header.flipped?"[FLIP]":""
);
if(!avi_header.video_codec) exit(1); // unknown video codec
+ if(avi_header.vids_guid){
+#ifdef USE_DIRECTSHOW
+ has_video=4; // switching to DirectShow
+#else
+ printf("MPlayer was compiled without DirectShow support!\n");exit(1);
+#endif
+ }
+}
+
+switch(has_video){
+ case 2: {
if(avi_header.yuv_supported && video_out->query_format(IMGFMT_YUY2)) out_fmt=IMGFMT_YUY2; else
if(avi_header.no_32bpp_support && video_out->query_format(IMGFMT_BGR|32)) out_fmt=IMGFMT_BGR|24; else
if(video_out->query_format(IMGFMT_BGR|15)) out_fmt=IMGFMT_BGR|16; else
@@ -798,6 +822,59 @@ switch(has_video){
movie_size_y=abs(avi_header.o_bih.biHeight);
break;
}
+#ifdef USE_DIRECTSHOW
+ case 4: { // Win32/DirectShow
+ if(avi_header.yuv_supported && video_out->query_format(IMGFMT_YUY2)) out_fmt=IMGFMT_YUY2; else
+// if(avi_header.no_32bpp_support && video_out->query_format(IMGFMT_BGR|32)) out_fmt=IMGFMT_BGR|24; else
+ if(video_out->query_format(IMGFMT_BGR|15)) out_fmt=IMGFMT_BGR|15; else
+ if(video_out->query_format(IMGFMT_BGR|16)) out_fmt=IMGFMT_BGR|16; else
+ if(video_out->query_format(IMGFMT_BGR|24)) out_fmt=IMGFMT_BGR|24; else
+ if(video_out->query_format(IMGFMT_BGR|32)) out_fmt=IMGFMT_BGR|32; else {
+ printf("Sorry, selected video_out device is incompatible with this codec.\n");
+ printf("(It can't show 24bpp or 32bpp RGB images. Try to run X at 24/32bpp!)\n");
+// printf("(cannot convert between YUY2, YV12 and RGB colorspace formats)\n");
+ exit(1);
+ }
+ //if(verbose) printf("AVI out_fmt=%X\n",out_fmt);
+ if(verbose) if(out_fmt==IMGFMT_YUY2) printf("Using YUV/YUY2 video output format!\n");
+ avi_header.our_out_buffer=NULL;
+ DS_VideoDecoder_Open(avi_header.video_codec,avi_header.vids_guid, &avi_header.bih, 0, &avi_header.our_out_buffer);
+
+ if(out_fmt==IMGFMT_YUY2)
+ DS_VideoDecoder_SetDestFmt(16,mmioFOURCC('Y', 'U', 'Y', '2'));
+// DS_VideoDecoder_SetDestFmt(16,mmioFOURCC('Y', 'V', '1', '2'));
+ else
+ DS_VideoDecoder_SetDestFmt(out_fmt&255,0);
+
+ DS_VideoDecoder_Start();
+
+ printf("DivX setting result = %d\n", DS_SetAttr_DivX("Quality",divx_quality) );
+// printf("DivX setting result = %d\n", DS_SetValue_DivX("Brightness",60) );
+
+ if(verbose) printf("INFO: Win32/DShow video codec init OK!\n");
+
+ // calculating video bitrate:
+ avi_header.bitrate=avi_header.movi_end-avi_header.movi_start-avi_header.idx_size*8;
+ if(avi_header.audio.fccType) avi_header.bitrate-=avi_header.audio.dwLength;
+ if(verbose) printf("AVI video length=%d\n",avi_header.bitrate);
+ avi_header.bitrate=((float)avi_header.bitrate/(float)avi_header.video.dwLength)
+ *((float)avi_header.video.dwRate/(float)avi_header.video.dwScale);
+// default_fps=(float)avi_header.video.dwRate/(float)avi_header.video.dwScale;
+ printf("VIDEO: [%.4s] %dx%d %dbpp %4.2f fps %5.1f kbps (%4.1f kbyte/s)\n",
+ &avi_header.bih.biCompression,
+ avi_header.bih.biWidth,
+ avi_header.bih.biHeight,
+ avi_header.bih.biBitCount,
+ default_fps,
+ avi_header.bitrate*0.008f,
+ avi_header.bitrate/1024.0f );
+
+ // display info:
+ movie_size_x=avi_header.bih.biWidth;
+ movie_size_y=abs(avi_header.bih.biHeight);
+ break;
+ }
+#endif
case 3: { // OpenDivX
out_fmt=IMGFMT_YV12;
if(!video_out->query_format(out_fmt)) {
@@ -1439,6 +1516,38 @@ switch(has_video){
break;
}
+#ifdef USE_DIRECTSHOW
+ case 4: { // W32/DirectShow
+ char* start=NULL;
+ unsigned int t=GetTimer();
+ unsigned int t2;
+ float pts1=d_video->pts;
+ int in_size=ds_get_packet(d_video,&start);
+ float pts2=d_video->pts;
+ if(in_size<0){ eof=1;break;}
+ if(in_size>max_framesize) max_framesize=in_size;
+
+// printf("frame len = %5.4f\n",pts2-pts1);
+
+ DS_VideoDecoder_DecodeFrame(start, in_size, 0, 1);
+
+ t2=GetTimer();t=t2-t;video_time_usage+=t*0.000001f;
+ video_out->draw_frame((uint8_t **)&avi_header.our_out_buffer);
+// video_out->flip_page();
+ t2=GetTimer()-t2;vout_time_usage+=t2*0.000001f;
+
+ ++num_frames;
+
+ if(file_format==DEMUXER_TYPE_ASF){
+ float d=pts2-pts1;
+ if(d>0 && d<0.2) v_frame+=d;
+ } else
+ v_frame+=1.0f/default_fps; //(float)avi_header.video.dwScale/(float)avi_header.video.dwRate;
+ //v_pts+=1.0f/default_fps; //(float)avi_header.video.dwScale/(float)avi_header.video.dwRate;
+
+ break;
+ }
+#endif
case 2: {
HRESULT ret;
char* start=NULL;