summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/mplayer.188
-rw-r--r--DOCS/xml/en/faq.xml10
-rw-r--r--Makefile2
-rwxr-xr-xconfigure2
-rw-r--r--etc/codecs.conf7
-rw-r--r--libmpcodecs/vd_qtvideo.c12
-rw-r--r--libmpcodecs/ve_qtvideo.c2
-rw-r--r--libmpcodecs/vf.c2
-rw-r--r--libmpcodecs/vf_fixpts.c137
-rw-r--r--libmpdemux/mp_taglists.c1
-rw-r--r--libvo/vo_fbdev.c38
-rw-r--r--loader/dshow/DS_Filter.c7
-rw-r--r--loader/dshow/allocator.c8
-rw-r--r--loader/dshow/graph.c163
-rw-r--r--loader/dshow/graph.h57
-rw-r--r--loader/dshow/guids.c4
-rw-r--r--loader/dshow/guids.h2
-rw-r--r--loader/dshow/interfaces.h28
-rw-r--r--loader/qtx/qtxsdk/components.h6
-rw-r--r--loader/win32.c196
-rw-r--r--mencoder.c129
-rw-r--r--mplayer.c2
-rw-r--r--stream/stream.h5
-rw-r--r--stream/stream_cddb.c4
-rw-r--r--stream/stream_file.c2
-rw-r--r--stream/stream_live555.c4
26 files changed, 828 insertions, 90 deletions
diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1
index beb16e4551..e542154378 100644
--- a/DOCS/man/en/mplayer.1
+++ b/DOCS/man/en/mplayer.1
@@ -7480,6 +7480,48 @@ Larger radius makes for smoother gradients, but also prevents the filter
from modifying pixels near detailed regions (default: 16).
.RE
.
+.TP
+.B fixpts[=options]
+Fixes the presentation timestamps (PTS) of the frames.
+By default, the PTS passed to the next filter is dropped, but the following
+options can change that:
+.RSs
+.IPs print
+Print the incoming PTS.
+.IPs fps=<fps>
+Specify a frame per second value.
+.IPs start=<pts>
+Specify an initial value for the PTS.
+.IPs autostart=<n>
+Uses the
+.IR n th
+incoming PTS as the initial PTS.
+All previous pts are kept, so setting a huge value or \-1 keeps the PTS
+intact.
+.IPs autofps=<n>
+Uses the
+.IR n th
+incoming PTS after the end of autostart to determine the framerate.
+.RE
+.sp 1
+.RS
+.I EXAMPLE:
+.RE
+.PD 0
+.RSs
+.IPs "\-vf fixpts=fps=24000/1001,ass,fixpts"
+Generates a new sequence of PTS, uses it for ASS subtitles, then drops it.
+Generating a new sequence is useful when the timestamps are reset during the
+program; this is frequent on DVDs.
+Dropping it may be necessary to avoid confusing encoders.
+.RE
+.PD 1
+.sp 1
+.RS
+.I NOTE:
+Using this filter together with any sort of seeking (including -ss and EDLs)
+may make demons fly out of your nose.
+.RE
.
.
.SH "GENERAL ENCODING OPTIONS (MENCODER ONLY)"
@@ -10668,6 +10710,52 @@ SVC encodes.
.TP
.B (no)aud
Write access unit delimeters to the stream (default: disabled).
+Enable this only if your target container format requires access unit
+delimiters.
+.
+.TP
+.B overscan=<undef|show|crop>
+Include VUI overscan information in the stream (default: disabled).
+See doc/vui.txt in the x264 source code for more information.
+.
+.TP
+.B videoformat=<component|pal|ntsc|secam|mac|undef>
+Include VUI video format information in the stream (default: disabled).
+This is a purely informative setting for describing the original source.
+See doc/vui.txt in the x264 source code for more information.
+.
+.TP
+.B (no)fullrange
+Include VUI full range information in the stream (default: disabled).
+Use this option if your source video is not range limited.
+See doc/vui.txt in the x264 source code for more information.
+.
+.TP
+.B colorprim=<bt709|bt470m|bt470bg|smpte170m|smpte240m|film|undef>
+Include color primaries information (default: disabled).
+This can be used for color correction.
+See doc/vui.txt in the x264 source code for more information.
+.
+.TP
+.B transfer=<bt709|bt470m|bt470bg|linear|log100|log316|smpte170m|smpte240m>
+Include VUI transfer characteristics information in the stream
+(default: disabled).
+This can be used for color correction.
+See doc/vui.txt in the x264 source code for more information.
+.
+.TP
+.B colormatrix=<bt709|fcc|bt470bg|smpte170m|smpte240m|GBR|YCgCo>
+Include VUI matrix coefficients in the stream (default: disabled).
+This can be used for color correction.
+See doc/vui.txt in the x264 source code for more information.
+.
+.TP
+.B chromaloc=<0-5>
+Include VUI chroma sample location information in the stream (default:
+disabled).
+Use this option to ensure alignment of the chroma and luma planes after
+color space conversions.
+See doc/vui.txt in the x264 source code for more information.
.
.TP
.B log=<\-1\-3>
diff --git a/DOCS/xml/en/faq.xml b/DOCS/xml/en/faq.xml
index 9234ad7334..58450c3d83 100644
--- a/DOCS/xml/en/faq.xml
+++ b/DOCS/xml/en/faq.xml
@@ -789,14 +789,8 @@ while seeking through RealMedia streams?
What about DVD navigation/menus?
</para></question>
<answer><para>
-<application>MPlayer</application> does not support DVD menus due to serious
-architectural limitations that prevent proper handling of still images and
-interactive content. If you want to have fancy menus, you will have to use
-another player like <application>xine</application>,
-<application>VLC</application> or <application>Ogle</application>.
-If you want to see DVD navigation in <application>MPlayer</application> you
-will have to implement it yourself, but be aware that it is a major
-undertaking.
+<application>MPlayer</application> should support DVD menus nowadays.
+Your mileage may vary.
</para></answer>
</qandaentry>
diff --git a/Makefile b/Makefile
index 6fcf358b0b..b2735bd913 100644
--- a/Makefile
+++ b/Makefile
@@ -313,6 +313,7 @@ SRCS_COMMON-$(WIN32DLL) += libmpcodecs/ad_acm.c \
loader/dshow/DS_VideoDecoder.c \
loader/dshow/allocator.c \
loader/dshow/cmediasample.c \
+ loader/dshow/graph.c \
loader/dshow/guids.c \
loader/dshow/inputpin.c \
loader/dshow/mediatype.c \
@@ -425,6 +426,7 @@ SRCS_COMMON = asxparser.c \
libmpcodecs/vf_field.c \
libmpcodecs/vf_fil.c \
libmpcodecs/vf_filmdint.c \
+ libmpcodecs/vf_fixpts.c \
libmpcodecs/vf_flip.c \
libmpcodecs/vf_format.c \
libmpcodecs/vf_framestep.c \
diff --git a/configure b/configure
index bb5c2715a7..93804a8734 100755
--- a/configure
+++ b/configure
@@ -289,7 +289,7 @@ Codecs:
--enable-jpeg enable JPEG input/output support [autodetect]
--enable-libcdio enable libcdio support [autodetect]
--enable-liblzo enable liblzo support [autodetect]
- --disable-win32dll disable Win32 DLL support [enabled]
+ --disable-win32dll disable Win32 DLL support [autodetect]
--disable-qtx disable QuickTime codecs support [enabled]
--disable-xanim disable XAnim codecs support [enabled]
--disable-real disable RealPlayer codecs support [enabled]
diff --git a/etc/codecs.conf b/etc/codecs.conf
index f78c2ea32c..d52e7c7a3d 100644
--- a/etc/codecs.conf
+++ b/etc/codecs.conf
@@ -3677,6 +3677,13 @@ audiocodec raatrcmac
driver realaud
dll "atrc.bundle/Contents/MacOS/atrc"
+audiocodec ffadpcmadx
+ info "FFmpeg SEGA CRI adx codec"
+ status working
+ fourcc Sadx ; internal MPlayer FourCC
+ driver ffmpeg
+ dll adpcm_adx
+
audiocodec ffadpcmimaamv
info "FFmpeg AMV IMA ADPCM audio"
status working
diff --git a/libmpcodecs/vd_qtvideo.c b/libmpcodecs/vd_qtvideo.c
index 8e73c84753..aeead624e0 100644
--- a/libmpcodecs/vd_qtvideo.c
+++ b/libmpcodecs/vd_qtvideo.c
@@ -90,7 +90,7 @@ static OSErr (*QTNewGWorldFromPtr)(GWorldPtr *gw,
GWorldFlags flags,
void *baseAddr,
long rowBytes);
-static OSErr (*NewHandleClear)(Size byteCount);
+static Handle (*NewHandleClear)(Size byteCount);
#endif /* #ifndef CONFIG_QUICKTIME */
// to set/get/query special features/parameters
@@ -103,7 +103,7 @@ static int codec_initialized=0;
// init driver
static int init(sh_video_t *sh){
#ifndef CONFIG_QUICKTIME
- long result = 1;
+ OSErr result = 1;
#endif
ComponentResult cres;
ComponentDescription desc;
@@ -156,7 +156,7 @@ static int init(sh_video_t *sh){
result=InitializeQTML(6+16);
// result=InitializeQTML(0);
- mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"InitializeQTML returned %li\n",result);
+ mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"InitializeQTML returned %d\n",result);
// result=EnterMovies();
// printf("EnterMovies->%d\n",result);
#endif /* CONFIG_QUICKTIME */
@@ -305,7 +305,7 @@ static void uninit(sh_video_t *sh){
// decode a frame
static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
- long result = 1;
+ OSErr result = 1;
int i;
mp_image_t* mpi;
ComponentResult cres;
@@ -335,7 +335,7 @@ if(!codec_initialized){
0,
mpi->planes[0],
mpi->stride[0]);
- mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"NewGWorldFromPtr returned:%ld\n",65536-(result&0xffff));
+ mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"NewGWorldFromPtr returned:%d\n",result);
// if (65536-(result&0xFFFF) != 10000)
// return NULL;
@@ -406,7 +406,7 @@ if(!codec_initialized){
++decpar.frameNumber;
- if(cres&0xFFFF){
+ if(cres) {
mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageCodecBandDecompress cres=0x%X (-0x%X) %d\n",cres,-cres,cres);
return NULL;
}
diff --git a/libmpcodecs/ve_qtvideo.c b/libmpcodecs/ve_qtvideo.c
index 92b76fb252..f3bba153e4 100644
--- a/libmpcodecs/ve_qtvideo.c
+++ b/libmpcodecs/ve_qtvideo.c
@@ -69,7 +69,7 @@ static OSErr (*QTNewGWorldFromPtr)(GWorldPtr *gw,
GWorldFlags flags,
void *baseAddr,
long rowBytes);
-static OSErr (*NewHandleClear)(Size byteCount);
+static Handle (*NewHandleClear)(Size byteCount);
static OSErr (*CompressSequenceBegin) (
ImageSequence *seqID,
PixMapHandle src,
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index fa72ad25aa..cc0d01c55e 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -118,6 +118,7 @@ extern const vf_info_t vf_info_yadif;
extern const vf_info_t vf_info_blackframe;
extern const vf_info_t vf_info_geq;
extern const vf_info_t vf_info_ow;
+extern const vf_info_t vf_info_fixpts;
// list of available filters:
static const vf_info_t* const filter_list[]={
@@ -219,6 +220,7 @@ static const vf_info_t* const filter_list[]={
&vf_info_yadif,
&vf_info_blackframe,
&vf_info_ow,
+ &vf_info_fixpts,
NULL
};
diff --git a/libmpcodecs/vf_fixpts.c b/libmpcodecs/vf_fixpts.c
new file mode 100644
index 0000000000..5ceb516c6b
--- /dev/null
+++ b/libmpcodecs/vf_fixpts.c
@@ -0,0 +1,137 @@
+/*
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+struct vf_priv_s {
+ double current;
+ double step;
+ int autostart;
+ int autostep;
+ unsigned have_step:1;
+ unsigned print:1;
+};
+
+static int put_image(vf_instance_t *vf, mp_image_t *src, double pts)
+{
+ struct vf_priv_s *p = vf->priv;
+
+ if (p->print) {
+ if (pts == MP_NOPTS_VALUE)
+ mp_msg(MSGT_VFILTER, MSGL_INFO, "PTS: undef\n");
+ else
+ mp_msg(MSGT_VFILTER, MSGL_INFO, "PTS: %f\n", pts);
+ }
+ if (pts != MP_NOPTS_VALUE && p->autostart != 0) {
+ p->current = pts;
+ if (p->autostart > 0)
+ p->autostart--;
+ } else if (pts != MP_NOPTS_VALUE && p->autostep > 0) {
+ p->step = pts - p->current;
+ p->current = pts;
+ p->autostep--;
+ p->have_step = 1;
+ } else if (p->have_step) {
+ p->current += p->step;
+ pts = p->current;
+ } else {
+ pts = MP_NOPTS_VALUE;
+ }
+ return vf_next_put_image(vf, src, pts);
+}
+
+static void uninit(vf_instance_t *vf)
+{
+ free(vf->priv);
+}
+
+static int parse_args(struct vf_priv_s *p, const char *args)
+{
+ int pos;
+ double num, denom = 1;
+ int iarg;
+
+ while (*args != 0) {
+ pos = 0;
+ if (sscanf(args, "print%n", &pos) == 0 && pos > 0) {
+ p->print = 1;
+ } else if (sscanf(args, "fps=%lf%n/%lf%n", &num, &pos, &denom, &pos) >=
+ 1 && pos > 0) {
+ p->step = denom / num;
+ p->have_step = 1;
+ } else if (sscanf(args, "start=%lf%n", &num, &pos) >= 1 && pos > 0) {
+ p->current = num;
+ } else if (sscanf(args, "autostart=%d%n", &iarg, &pos) == 1 && pos > 0) {
+ p->autostart = iarg;
+ } else if (sscanf(args, "autofps=%d%n", &iarg, &pos) == 1 && pos > 0) {
+ p->autostep = iarg;
+ } else {
+ mp_msg(MSGT_VFILTER, MSGL_FATAL,
+ "fixpts: unknown suboption: %s\n", args);
+ return 0;
+ }
+ args += pos;
+ if (*args == ':')
+ args++;
+ }
+ return 1;
+}
+
+static int open(vf_instance_t *vf, char *args)
+{
+ struct vf_priv_s *p;
+ struct vf_priv_s ptmp = {
+ .current = 0,
+ .step = 0,
+ .autostart = 0,
+ .autostep = 0,
+ .have_step = 0,
+ .print = 0,
+ };
+
+ if (!parse_args(&ptmp, args == NULL ? "" : args))
+ return 0;
+
+ vf->put_image = put_image;
+ vf->uninit = uninit;
+ vf->priv = p = malloc(sizeof(struct vf_priv_s));
+ *p = ptmp;
+ p->current = -p->step;
+
+ return 1;
+}
+
+vf_info_t vf_info_fixpts = {
+ "Fix presentation timestamps",
+ "fixpts",
+ "Nicolas George",
+ "",
+ &open,
+ NULL
+};
diff --git a/libmpdemux/mp_taglists.c b/libmpdemux/mp_taglists.c
index adfe1059b2..7fc68db5f9 100644
--- a/libmpdemux/mp_taglists.c
+++ b/libmpdemux/mp_taglists.c
@@ -27,6 +27,7 @@
static const struct mp_AVCodecTag mp_wav_tags[] = {
{ CODEC_ID_ADPCM_4XM, MKTAG('4', 'X', 'M', 'A')},
+ { CODEC_ID_ADPCM_ADX, MKTAG('S', 'a', 'd', 'x')},
{ CODEC_ID_ADPCM_EA, MKTAG('A', 'D', 'E', 'A')},
{ CODEC_ID_ADPCM_EA_MAXIS_XA, MKTAG('A', 'D', 'X', 'A')},
{ CODEC_ID_ADPCM_IMA_WS, MKTAG('A', 'I', 'W', 'S')},
diff --git a/libvo/vo_fbdev.c b/libvo/vo_fbdev.c
index df3f21299c..4534b17d9f 100644
--- a/libvo/vo_fbdev.c
+++ b/libvo/vo_fbdev.c
@@ -572,6 +572,7 @@ static int fb_bpp_we_want; // 32: 32 24: 24 16: 16 15: 15
static int fb_line_len;
static int fb_xres;
static int fb_yres;
+static int fb_page;
static void (*draw_alpha_p)(int w, int h, unsigned char *src,
unsigned char *srca, int stride,
unsigned char *dst, int dstride);
@@ -804,6 +805,12 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
set_bpp(&fb_vinfo, fb_bpp);
fb_vinfo.xres_virtual = fb_vinfo.xres;
fb_vinfo.yres_virtual = fb_vinfo.yres;
+ fb_page = 0;
+ if (vo_doublebuffering) {
+ fb_vinfo.yres_virtual <<= 1;
+ fb_vinfo.yoffset = 0;
+ fb_page = 1; // start writing into the page we don't display
+ }
if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) {
mp_msg(MSGT_VO, MSGL_V, "Can't set graphics mode: %s\n", strerror(errno));
@@ -903,6 +910,12 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
fb_line_len = fb_finfo.line_length;
fb_size = fb_finfo.smem_len;
+ if (vo_doublebuffering && fb_size < 2 * fb_yres * fb_line_len)
+ {
+ mp_msg(MSGT_VO, MSGL_WARN, "framebuffer too small for double-buffering, disabling\n");
+ vo_doublebuffering = 0;
+ fb_page = 0;
+ }
#ifdef CONFIG_VIDIX
if (vidix_name) {
@@ -963,14 +976,19 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
center = frame_buffer +
( (out_width - in_width) / 2 ) * fb_pixel_size +
( (out_height - in_height) / 2 ) * fb_line_len +
- x_offset * fb_pixel_size + y_offset * fb_line_len;
+ x_offset * fb_pixel_size + y_offset * fb_line_len +
+ fb_page * fb_yres * fb_line_len;
mp_msg(MSGT_VO, MSGL_DBG2, "frame_buffer @ %p\n", frame_buffer);
mp_msg(MSGT_VO, MSGL_DBG2, "center @ %p\n", center);
mp_msg(MSGT_VO, MSGL_V, "pixel per line: %d\n", fb_line_len / fb_pixel_size);
- if (fs || vm)
- memset(frame_buffer, '\0', fb_line_len * fb_yres);
+ if (fs || vm) {
+ int clear_size = fb_line_len * fb_yres;
+ if (vo_doublebuffering)
+ clear_size <<= 1;
+ memset(frame_buffer, 0, clear_size);
+ }
}
vt_set_textarea(last_row, fb_yres);
@@ -1027,6 +1045,20 @@ static void check_events(void)
static void flip_page(void)
{
+ int next_page = !fb_page;
+ int page_delta = next_page - fb_page;
+#ifdef CONFIG_VIDIX
+ if (vidix_name)
+ return;
+#endif
+ if (!vo_doublebuffering)
+ return;
+
+ fb_vinfo.yoffset = fb_page * fb_yres;
+ ioctl(fb_dev_fd, FBIOPAN_DISPLAY, &fb_vinfo);
+
+ center += page_delta * fb_yres * fb_line_len;
+ fb_page = next_page;
}
static void draw_osd(void)
diff --git a/loader/dshow/DS_Filter.c b/loader/dshow/DS_Filter.c
index e3102cf264..693d59c25f 100644
--- a/loader/dshow/DS_Filter.c
+++ b/loader/dshow/DS_Filter.c
@@ -5,6 +5,7 @@
#include "config.h"
#include "DS_Filter.h"
+#include "graph.h"
#include "loader/drv.h"
#include "loader/com.h"
#include <stdio.h>
@@ -125,6 +126,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
// char eb[250];
const char* em = NULL;
MemAllocator* tempAll;
+ FilterGraph* graph;
ALLOCATOR_PROPERTIES props,props1;
DS_Filter* This = malloc(sizeof(DS_Filter));
if (!This)
@@ -166,6 +168,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
ULONG fetched;
HRESULT result;
unsigned int i;
+ static const uint16_t filter_name[] = { 'F', 'i', 'l', 't', 'e', 'r', 0 };
This->m_iHandle = LoadLibraryA(dllname);
if (!This->m_iHandle)
@@ -199,6 +202,10 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
em = "object does not provide IBaseFilter interface";
break;
}
+
+ graph = FilterGraphCreate();
+ result = This->m_pFilter->vt->JoinFilterGraph(This->m_pFilter, (IFilterGraph*)graph, filter_name);
+
// enumerate pins
result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins);
if (result || !enum_pins)
diff --git a/loader/dshow/allocator.c b/loader/dshow/allocator.c
index b75f1bebfb..a90bd9d3d2 100644
--- a/loader/dshow/allocator.c
+++ b/loader/dshow/allocator.c
@@ -116,7 +116,7 @@ static inline avm_list_t* avm_list_find(avm_list_t* head, void* member)
static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** ppv)
{
- IMemAllocator* p;
+ IUnknown* p;
int result;
if (!ppv)
return -1;
@@ -124,9 +124,9 @@ static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** pp
if (memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID)))
return -1;
- p = (IMemAllocator*) MemAllocatorCreate();
- result = p->vt->QueryInterface((IUnknown*)p, iid, ppv);
- p->vt->Release((IUnknown*)p);
+ p = (IUnknown*) MemAllocatorCreate();
+ result = p->vt->QueryInterface(p, iid, ppv);
+ p->vt->Release(p);
return result;
}
diff --git a/loader/dshow/graph.c b/loader/dshow/graph.c
new file mode 100644
index 0000000000..01bf6c7253
--- /dev/null
+++ b/loader/dshow/graph.c
@@ -0,0 +1,163 @@
+/*
+ * Implemention of FilterGraph. Based on allocator.c.
+ * Copyright 2010 Steinar H. Gunderson
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Modified for use with MPlayer, detailed changelog at
+ * http://svn.mplayerhq.hu/mplayer/trunk/
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "loader/com.h"
+#include "loader/dshow/graph.h"
+#include "loader/wine/winerror.h"
+
+// How many FilterGraph objects exist.
+// Used for knowing when to register and unregister the class in COM.
+static int GraphKeeper = 0;
+
+static long FilterGraph_CreateGraph(GUID* clsid, const GUID* iid, void** ppv)
+{
+ IUnknown* p;
+ int result;
+ if (!ppv)
+ return -1;
+ *ppv = 0;
+ if (memcmp(clsid, &CLSID_FilterGraph, sizeof(*clsid)))
+ return -1;
+
+ p = (IUnknown*) FilterGraphCreate();
+ result = p->vt->QueryInterface(p, iid, ppv);
+ p->vt->Release(p);
+
+ return result;
+}
+
+static void FilterGraph_Destroy(FilterGraph* This)
+{
+ Debug printf("FilterGraph_Destroy(%p) called (%d, %d)\n", This, This->refcount, GraphKeeper);
+#ifdef WIN32_LOADER
+ if (--GraphKeeper == 0)
+ UnregisterComClass(&CLSID_FilterGraph, FilterGraph_CreateGraph);
+#endif
+ free(This->vt);
+ free(This);
+}
+
+HRESULT STDCALL FilterGraph_AddFilter(FilterGraph* This,
+ IBaseFilter* pFilter,
+ unsigned short* pName)
+{
+ Debug printf("FilterGraph_AddFilter(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_RemoveFilter(FilterGraph* This, IBaseFilter* pFilter)
+{
+ Debug printf("FilterGraph_RemoveFilter(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_EnumFilters(FilterGraph* This, IEnumFilters** ppEnum)
+{
+ Debug printf("FilterGraph_EnumFilters(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_FindFilterByName(FilterGraph* This,
+ unsigned short* pName,
+ IBaseFilter** ppFilter)
+{
+ Debug printf("FilterGraph_FindFilterByName(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_ConnectDirect(FilterGraph* This,
+ IPin* ppinOut,
+ IPin* ppinIn,
+ const AM_MEDIA_TYPE* pmt)
+{
+ Debug printf("FilterGraph_ConnectDirect(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_Reconnect(FilterGraph* This, IPin* ppin)
+{
+ Debug printf("FilterGraph_Reconnect(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_Disconnect(FilterGraph* This, IPin* ppin)
+{
+ Debug printf("FilterGraph_Disconnect(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_SetDefaultSyncSource(FilterGraph* This)
+{
+ Debug printf("FilterGraph_SetDefaultSyncSource(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+IMPLEMENT_IUNKNOWN(FilterGraph)
+
+FilterGraph* FilterGraphCreate()
+{
+ FilterGraph* This = calloc(1, sizeof(*This));
+
+ if (!This)
+ return NULL;
+
+ Debug printf("FilterGraphCreate() called -> %p\n", This);
+
+ This->refcount = 1;
+
+ This->vt = calloc(1, sizeof(*This->vt));
+
+ if (!This->vt) {
+ free(This);
+ return NULL;
+ }
+
+ This->vt->QueryInterface = FilterGraph_QueryInterface;
+ This->vt->AddRef = FilterGraph_AddRef;
+ This->vt->Release = FilterGraph_Release;
+
+ This->vt->AddFilter = FilterGraph_AddFilter;
+ This->vt->RemoveFilter = FilterGraph_RemoveFilter;
+ This->vt->EnumFilters = FilterGraph_EnumFilters;
+ This->vt->FindFilterByName = FilterGraph_FindFilterByName;
+ This->vt->ConnectDirect = FilterGraph_ConnectDirect;
+ This->vt->Reconnect = FilterGraph_Reconnect;
+ This->vt->Disconnect = FilterGraph_Disconnect;
+ This->vt->SetDefaultSyncSource = FilterGraph_SetDefaultSyncSource;
+
+ This->interfaces[0] = IID_IUnknown;
+ This->interfaces[1] = IID_IFilterGraph;
+
+#ifdef WIN32_LOADER
+ if (GraphKeeper++ == 0)
+ RegisterComClass(&CLSID_FilterGraph, FilterGraph_CreateGraph);
+#endif
+
+ return This;
+}
+
diff --git a/loader/dshow/graph.h b/loader/dshow/graph.h
new file mode 100644
index 0000000000..7667f5a39e
--- /dev/null
+++ b/loader/dshow/graph.h
@@ -0,0 +1,57 @@
+#ifndef MPLAYER_GRAPH_H
+#define MPLAYER_GRAPH_H
+
+/*
+ * Copyright 2010 Steinar H. Gunderson
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "interfaces.h"
+#include "cmediasample.h"
+
+typedef struct FilterGraph FilterGraph;
+
+struct FilterGraph {
+ IFilterGraph_vt* vt;
+ DECLARE_IUNKNOWN();
+ GUID interfaces[2];
+
+ HRESULT STDCALL (*AddFilter)(FilterGraph* This,
+ /* [in] */ IBaseFilter* pFilter,
+ /* [string][in] */ unsigned short* pName);
+ HRESULT STDCALL (*RemoveFilter)(FilterGraph* This,
+ /* [in] */ IBaseFilter* pFilter);
+ HRESULT STDCALL (*EnumFilters)(FilterGraph* This,
+ /* [out] */ IEnumFilters** ppEnum);
+ HRESULT STDCALL (*FindFilterByName)(FilterGraph* This,
+ /* [string][in] */ unsigned sh