views:

375

answers:

3

I currently have a DirectShow.NET graph that properly plays but I would like it to also be able to play in reverse (start at the end and play backwards to the start).

I've tried playing around with the IMediaSeeking::SetRate(double) method but that only works for positive values. When I try with a negative value it crashes.

Help!

I'm using .avi video files but would be open to trying different formats if that would do the trick.

+2  A: 

Have you tried with a variety of video files? Many files can only be played forwards due to temporal compression techniques (i.e. the information in a frame depends on information in the previous frames).

You can use GSpot to inspect your file and see if it contains any P-frames; if it does, you're unlikely to be able to play it in reverse. AVI is a container and the video inside it could use any codec.

GraemeF
do you recommend any codecs that would allow reverse playback?
mwahab
I don't know - this link suggests the Indeo 5 codec (http://vvvv.org/tiki-index.php?page=FAQ+Codecs#Reverse_Playing) but quality will be poor. You could see if you could find a Motion JPEG codec as they are pretty much a sequence of JPEG frames, or try Quicktime RLE if you can get that to play in DirectShow.
GraemeF
+4  A: 

Actually, I'm not sure that the stock AVI demux will support negative rates for any format, even if the format does not use temporal compression. And certainly most other demux filters will not support negative rate. So you will probably need a custom demux filter to do this. If you do this, make sure you use a container format with an index (mp4 for example).

If you use a format without temporal compression (motion jpeg, i-frames only mpeg-2 etc), you will pay a considerable price in frame compression in order to be able to play in reverse. If you want to do this really well, consider the approach taken by some DVD implementations. Some of them play in reverse by playing only the i-frame, so you have 1 or 2 fps. But the top-end implementation will decode a whole GOP (approx 15 frames) and will then render these frames in reverse order while decoding the previous GOP. This is expensive in development terms and in system resources, but gets a good end result.

G

Geraint Davies
+1  A: 

Repeatedly calling IMediaSeeking::SetPositions to framestep backwards one frame at a time will give you reverse playback. It will be very unlikely to be smooth, but I think it's going to be the best you can achieve without writing multiple custom filters.

Using a codec without any temporal compression like mjpeg or jpeg2000 would help a lot with this technique. For regular modern codecs lowering the resolution and bitrate would help.

Do you need to be able to reverse playback at any random time for any arbitrary file? If you can preprocess your media files, it wouldn't be hard to prepare a reversed version that you could switch to. Avisynth could do it if you're comfortable with low-level tools.

Alan
I've been playing around with stepping backwards with SetPositions and get less-than great results as you predicted.In the end I'm just going to preprocess the files to create a reversed version I can switch to at run time. Thanks!
mwahab