开发者

Can I get timecode from directshow video?

I'm trying to make a timecode 开发者_C百科counter for a video player based on GMFBridge and DirectShow.

I'm using a Timer to call GetCurrentPosition() every 200ms but I believe it's not accurate. I'd like at least to get the frame number (from start) of the current frame when a video is running.

Can this actually be done?

I'm using DirectShowLib .NET library.


To my knowledge this is hard to achieve, in a solution I work on I did the following to get 'frame number':

 public int NumberOfFrames
    {
        get
        {
            return (int)(Duration / AverageTimePerFrame);
        }
    }

    public double AverageTimePerFrame
    {
        get
        {
            return videoInfoHeader.AvgTimePerFrame / 10000000.0;   
        }
    }


        public int GetCurrentFrame(double currentTime)
        {
            int noOfFrames = (int)(Duration / AverageTimePerFrame);

            return Convert.ToInt32(Math.Min(noOfFrames - 1, Math.Floor(currentTime / AverageTimePerFrame)));
        }

I got the videoInfoHeader by doing:

  // Get the media type from the SampleGrabber
    AMMediaType media = new AMMediaType();
    hr = sampGrabber.GetConnectedMediaType(media);
    DsError.ThrowExceptionForHR(hr);

    if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
    {
        throw new NotSupportedException("Unknown Grabber Media Format");
    }

    // Grab the size info
    videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));          
    DsUtils.FreeAMMediaType(media);

However this is obviously tailored to my own use-case, hopefully it helps you a bit though. Good luck!

Updated Added CurrentTime code (the locker is for my own usage you can most likely remove that):

public double CurrentTime
{
    set
    {
        lock (locker)
        {
            IMediaPosition mediaPos = fFilterGraph as IMediaPosition;
            int hr;

            if (value >= 0 && value <= Duration)
            {
                hr = mediaPos.put_CurrentPosition(value);
                DsError.ThrowExceptionForHR(hr);
            }
        }
    }

    get
    {
        lock (locker)
        {
            IMediaPosition mediaPos = fFilterGraph as IMediaPosition;
            int hr;

            double currentTime;
            hr = mediaPos.get_CurrentPosition(out currentTime);
            DsError.ThrowExceptionForHR(hr);

            return currentTime;
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜