Why DirectShow load video subtitle file?

0

I use this class (found from CodeProject, some methods and properties removed to reduce code) to play video file by DirectShow, it works fine. but if subtitle file exist on same folder that the file is playing, subtitle shows automatically.

I want to know which part of code is concerning to subtitle file. how can I remove or customize it?! (such as color, font size, font name)

Is it inside the SampleGrabber filter?!

class MediaPlayer : IDisposable
{
    public enum FileType
    {
        Video,
        Audio,
        Invalid
    }

    public enum GraphState
    {
        Stopped,
        Paused,
        Running,
        Exiting
    }

    public IVideoFrameStep frameStep = null;
    public FileType fileType = FileType.Invalid;
    public IGraphBuilder graphBuilder = null;
    public IMediaControl mediaControl = null;
    public IVideoWindow videoWindow = null;
    public IBasicVideo basicVideo = null;
    public ISampleGrabber sampleGrabber = null;
    public IMediaSeeking mediaSeeking = null;
    public IMediaPosition mediaPosition = null;
    public IMediaDet mediaDet = null;
    public IBasicAudio basicAudio = null;
    public IMediaEventEx mediaEvent;
    public Control control;
    public MediaInfo mediaInfo = new MediaInfo();
    public List<Frames> segmentationImages;
    private string filename;
    private ManualResetEvent manualResetEvent = null;
    volatile private GraphState currentState = GraphState.Stopped;
    public event HotMediaEvent StopPlay;

    public void Dispose()
    {
        CloseInterfaces();
    }

    ~MediaPlayer()
    {
        CloseInterfaces();
    }

    public MediaPlayer(string fileName)
    {
        try
        {
            IntPtr eventHandler;
            this.filename = fileName;
            this.SetupInterfaces(fileName);
            DsError.ThrowExceptionForHR(mediaEvent.GetEventHandle(out eventHandler));
            manualResetEvent = new ManualResetEvent(false);
            manualResetEvent.SafeWaitHandle = new Microsoft.Win32.SafeHandles.SafeWaitHandle(eventHandler, true);
            Thread t = new Thread(new ThreadStart(this.EventWait));
            t.Name = "HotMediaEvent Thread";
            t.Start();
        }
        catch
        {
            Dispose();
            throw;
        }
    }


    public void SetupInterfaces(string fileName)
    {
        this.graphBuilder = (IGraphBuilder)new FilterGraph();
        this.sampleGrabber = (ISampleGrabber)new SampleGrabber();
        ConfigSampleGrabber(this.sampleGrabber);
        this.graphBuilder.AddFilter((IBaseFilter)sampleGrabber, "SampleGrabber");
        DsError.ThrowExceptionForHR(this.graphBuilder.RenderFile(fileName, null));
        this.mediaControl = (IMediaControl)this.graphBuilder;
        this.mediaEvent = (IMediaEventEx)this.graphBuilder;
        this.mediaSeeking = (IMediaSeeking)this.graphBuilder;
        this.mediaPosition = (IMediaPosition)this.graphBuilder;
        this.videoWindow = this.graphBuilder as IVideoWindow;
        this.basicVideo = this.graphBuilder as IBasicVideo;
        this.basicAudio = this.graphBuilder as IBasicAudio;

        this.frameStep = this.graphBuilder as IVideoFrameStep;

        this.mediaDet = (IMediaDet)new MediaDet();
        this.mediaDet.put_Filename(fileName);
        this.CheckFileType();
        if (this.fileType == FileType.Video)
            this.GetMediaInfo();
    }


    public void SetupVideoWindow(Control control)
    {
        int hr = 0;
        this.control = control;
        if (this.fileType == FileType.Video)
        {
            //this.sampleGrabber.SetCallback(((MainForm)this.control.Parent.Parent), 1);
            this.GetMediaInfo();
            hr = this.videoWindow.put_Owner(control.Handle);
            DsError.ThrowExceptionForHR(hr);
            hr = this.videoWindow.put_WindowStyle((WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings));
            DsError.ThrowExceptionForHR(hr);
            hr = this.videoWindow.put_Visible(OABool.True);
            DsError.ThrowExceptionForHR(hr);
            hr = this.videoWindow.put_MessageDrain(control.Handle);
            this.SizeWindow();
            DsError.ThrowExceptionForHR(hr);
        }
    } 

    public void ClearVideoWindow()
    {
        int hr = 0;
        if (this.fileType == FileType.Video)
        {
            hr = this.videoWindow.put_Owner(IntPtr.Zero);
            DsError.ThrowExceptionForHR(hr);
            hr = this.videoWindow.put_Visible(OABool.False);
            DsError.ThrowExceptionForHR(hr);
            hr = this.videoWindow.put_MessageDrain(IntPtr.Zero);
            DsError.ThrowExceptionForHR(hr);
        }
    }

    private void CheckFileType()
    {
        int hr;
        if ((this.videoWindow != null) || (this.basicVideo != null))
            this.fileType = FileType.Video;
        else if ((this.basicAudio != null))
            this.fileType = FileType.Audio;
        else
            this.fileType = FileType.Invalid;

        OABool lVisible;
        hr = this.videoWindow.get_Visible(out lVisible);
        if (hr < 0)
        {
            if (hr == unchecked((int)0x80004002)) //E_NOINTERFACE
                this.fileType = FileType.Audio;
            else
                DsError.ThrowExceptionForHR(hr);
        }
    }

    private void EventWait()
    {
        int hr;
        //WS UPDATED changed int to IntPtr
        IntPtr firstParameter, secondParameter;
        EventCode eventCode;
        do
        {
            manualResetEvent.WaitOne(-1, true);
            lock (this)
            {
                if (currentState != GraphState.Exiting)
                {
                    hr = mediaEvent.GetEvent(out eventCode, out firstParameter, out secondParameter, 0);
                    while (hr >= 0)
                    {
                        if (eventCode == EventCode.Complete)
                        {
                            Stop();
                            if (StopPlay != null)
                                StopPlay(this);
                        }
                        hr = mediaEvent.FreeEventParams(eventCode, firstParameter, secondParameter);
                        DsError.ThrowExceptionForHR(hr);
                        hr = mediaEvent.GetEvent(out eventCode, out firstParameter, out secondParameter, 0);
                    }
                    if (hr != unchecked((int)0x80004004))
                        DsError.ThrowExceptionForHR(hr);
                }
                else
                    break;
            }
        } while (true);
    }

    public void SizeWindow()
    {
        int hr;
        Rectangle rc = control.ClientRectangle;
        int windowWidth, windowHeight;
        windowWidth = rc.Width;
        windowHeight = rc.Height;
        int videoWidth = this.mediaInfo.MediaWidth;
        int videoHeight = this.mediaInfo.MediaHeight;
        int x, y, width, height;
        double videoRatio = (double)videoWidth / (double)videoHeight;
        double windowRatio = (double)windowWidth / (double)windowHeight;
        if (videoRatio > windowRatio)
        {
            double ratio = (double)windowWidth / (double)videoWidth;
            x = (int)((windowWidth - videoWidth * ratio) / 2);
            y = (int)((windowHeight - videoHeight * ratio) / 2);
            width = (int)(videoWidth * ratio);
            height = (int)(videoHeight * ratio);
            hr = videoWindow.SetWindowPosition(x, y, width, height);
        }
        else
        {
            double ratio = (double)windowHeight / (double)videoHeight;
            x = (int)((windowWidth - videoWidth * ratio) / 2);
            y = (int)((windowHeight - videoHeight * ratio) / 2);
            width = (int)(videoWidth * ratio);
            height = (int)(videoHeight * ratio);
            hr = videoWindow.SetWindowPosition(x, y, width, height);
        }
        DsError.ThrowExceptionForHR(hr);
    }

    void ConfigSampleGrabber(ISampleGrabber sampGrabber)
    {
        AMMediaType media;
        media = new AMMediaType();
        media.majorType = MediaType.Video;
        media.subType = MediaSubType.RGB24;
        media.formatType = FormatType.VideoInfo;
        this.sampleGrabber.SetMediaType(media);
        DsUtils.FreeAMMediaType(media);
        media = null;
        int hr = sampGrabber.SetBufferSamples(true);
        DsError.ThrowExceptionForHR(hr);
    }

    private void GetMediaInfo()
    {
        AMMediaType media = new AMMediaType();
        this.sampleGrabber.GetConnectedMediaType(media);
        if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
        {
            throw new Exception("Format type incorrect");
        }

        int videoWidth, videoHeight, videoStride;
        this.basicVideo.GetVideoSize(out videoWidth, out videoHeight);
        VideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
        videoStride = videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8);
        this.mediaInfo.MediaWidth = videoWidth;
        this.mediaInfo.MediaHeight = videoHeight;
        this.mediaInfo.MediaStride = videoStride;
        this.mediaInfo.MediaBitCount = videoInfoHeader.BmiHeader.BitCount;
        this.mediaInfo.fps = this.getFramePerSecond();
        this.mediaInfo.duration = this.getDuration();

        this.mediaInfo.sFilePath = this.filename.ToString();

        DsUtils.FreeAMMediaType(media);
        media = null;
    }


    private void CloseInterfaces()
    {
        lock (this)
        {
            int hr;
            try
            {
                if (this.mediaControl != null)
                {
                    hr = this.mediaControl.StopWhenReady();
                    this.mediaControl = null;
                }
                if (currentState != GraphState.Exiting)
                {
                    currentState = GraphState.Exiting;
                    if (manualResetEvent != null)
                        manualResetEvent.Set();
                }
                if (this.videoWindow != null)
                {
                    hr = this.videoWindow.put_Visible(OABool.False);
                    hr = this.videoWindow.put_Owner(IntPtr.Zero);
                    this.videoWindow = null;
                }
                this.mediaSeeking = null;
                this.mediaPosition = null;
                this.basicVideo = null;
                this.basicAudio = null;
                this.mediaDet = null;
                if (this.graphBuilder != null)
                    Marshal.ReleaseComObject(this.graphBuilder);
                this.graphBuilder = null;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                return;
            }
        }
        GC.Collect();
    }


    public void Start()
    {
        if (this.currentState == GraphState.Stopped || this.currentState == GraphState.Paused)
        {
            DsError.ThrowExceptionForHR(mediaControl.Run());
            this.currentState = GraphState.Running;
        }
    }

    public void Stop()
    {
        if (this.currentState == GraphState.Running || this.currentState == GraphState.Paused)
        {
            DsError.ThrowExceptionForHR(mediaControl.Stop());
            currentState = GraphState.Stopped;
        }
    }


    public void End()
    {
        double endPosition = 0;
        this.mediaDet.get_StreamLength(out endPosition);
        DsError.ThrowExceptionForHR(mediaPosition.put_CurrentPosition(endPosition));
    }

}
c#
video
directshow
directshow.net
subtitle
asked on Stack Overflow Jun 30, 2017 by Shahram.HF • edited Jun 30, 2017 by Roman R.

1 Answer

0

Most likely is that you have a DirectVobSub filter installed (often as a part of some codec pack), which is registering itself at high merit (priority), which allows it to break in during filter graph construction process and insert itself into your pipeline without even being a part of your code.

The filter looks for subtitle files and load them automatically, then updates the video feed.

DirectVobSub (formerly known as VSFilter) is a software add-on for Microsoft Windows (a DirectShow filter) that is able to read external subtitle files and superimposes them on a playing video file.

You want to uninstall it, or disable it's automatic self-activating functionality.

See also:

answered on Stack Overflow Jun 30, 2017 by Roman R. • edited Jun 30, 2017 by Roman R.

User contributions licensed under CC BY-SA 3.0