locked
IMFSinkWriter: WriteFrame returns E_CHANGED_STATE when encoding H.264 (but not WMV)

    Question

  • I am using a C++/CX component to encode video using IMFSinkWriter, and everything works fine when I encode using the WMV3 codec, but when I try to use the H.264 codec I get E_CHANGED_STATE (0x8000000c: "A concurrent or interleaved operation changed the state of the object, invalidating this operation.") errors. I can't find any reason to believe this is a threading issue, which was my first thought: the component is being called from an async/await C# method, but everything awaitable is being awaited, as far as I can see, and there's no other threading-like behavior going on in the app.

    My second thought was that somehow the sink writer's throttling (on by default) was being turned off. But this doesn't seem to be the case. In fact, I tried to explicitly enable throttling, but this didn't have any effect:

    spAttr->SetUINT32(MF_SINK_WRITER_DISABLE_THROTTLING, false);

    The encoding source is an RGB32 stream, and I am encoding at a 1.5Mbps bitrate, 25 FPS.

    The error happens every time I try to encode a video of any real-world length: it'll usually pop up before it gets about 10% of the way through a 5 minute output file. However, it isn't entirely deterministic: sometimes it will get partway through the third (of 58) segments, while other times it will happend on the first.

    None of these problems affect WMV encoding. Can anyone offer any suggestions for things to try?

    Monday, June 3, 2013 1:01 AM

Answers

  • Over a year later, I found the solution. Part of the code was manually flushing the underlying stream after requesting an encode; for some reason the WMV encoder was far more durable in the face of this, though even with WMV I eventually observed the same errors. Whatever the reason, avoiding the stream flush fixed the problem entirely.

    (The reason the Flush was there in the first place was because the WMV version of the encoder would run out of memory because it didn't seem to ever flush the stream itself. I don't actually know how to mitigate that, but since the H.264 encoder is much more efficient I don't care enough to investigate further at this time.)

    Glad to finally have an answer on this one!

    • Marked as answer by Dominic Pease Wednesday, October 1, 2014 7:25 PM
    Wednesday, October 1, 2014 7:25 PM