Tuesday, February 03, 2009 12:27 PMHi
As in my previous post, I'm writing a class to convert video files to WMV. Some of the video files I need to convert are already in WMV format, but still need to be converted/transcoded into wmv, for example with lower bitrate or in a lower resolution.
I'm building my graph by adding a AsfWriter filter and using the RenderFile method to take care building and connecting the rest of the graph. This is all working well as long as the source video files are not corrupted.
The file I'm try to transcoder is about 45 min long but around minute 24, there is some curruption in the file. If I try to play this file in WMP the media player stops and display an error message: "Windows Media Player encountered a problem while playing the file" however, if I seek pass the "corruption point" WMP can play the rest of the file. I've tried transcoding the file with WME but it also fails early in the transcoding process showing the error message: "The given data is currupted, badly formatted, or otherwise not valid. (0xC00D080D)".
While transcoding the file, I keeping track of the current position in the file my calling the "WaitForCompletion" method on the IMediaEvent interface (aquired from the graph) with a specified timeout value. On each timeout I reed the GetCurrentPosition from the IMediaSeeking interface (aquired from the AsfWriter filter) to figure how where in the progress I'am at each time. When my graph encounters the position where the corruption is, it stops processing, so I get the same position on each timeout. It's possible to detect this simply be keeping track of the last position and then throwing an error if the position is the same (similar to what WME does). My question is, is it poosible to ignore those "corruption points" by seeking a bit into the file. I've tried calling the SetPositions method from the IMediaSeeking interface (aquired from the AsfWriter fitler) to seek one second ahead but I always get hr 0x80004001 (Not implemented) while doing so.
Are there any other ways to skip past the "corruption points" or is this a hopeless case?
p.s. I don't mind if I miss for example one second from the original video if it means that the transcoded video wont be corrupted.
I've also tried reindexing the file with the File Editor utility that comes with WME but that doesn't help.
Tuesday, February 03, 2009 1:01 PMYou can pass corruption point in Windows Media Player - you can pass it using seeking in your conversion graph. The most likely problem is that your entire graph is not seekable because some of the filters (perhaps and hopefully it is your transformation filter) does not support IMediaSeeking interface, see Seeking on MSDN. If so you will need to implement IMediaSeeking using CPosPassThru class. Or otherwise, post your full graph topology here to see what other filter might be the seeking problem cause.
Tuesday, February 03, 2009 1:35 PM
Thanks for the answer my graph looks like this:
WM ASF Reader (input.wmv) -> WMAudio Decoder DMO ->
WM ASF Writer (output.wmv)
WMVideo Decoder DMO ->
I hope this "picture" is clear enough. I tried aquiring the IMediaSeeking interface from the graph it self like this:
IMediaSeeking mediaSeekingGraph = graphBuilder as IMediaSeeking;
But when calling
hr = mediaSeekingGraph.SetPositions(10000000,AMSeekingSeekingFlags.RelativePositioning, 0, AMSeekingSeekingFlags.RelativePositioning);
I get hr = 0x80004001. I've also tried this using absolute positioning.