On Sat, Apr 10, 2010 at 1:44 PM, Bruce Wheaton <[email protected]> wrote: > On Apr 10, 2010, at 12:59 PM, Thomas Worth wrote: > >> On Sat, Apr 10, 2010 at 10:37 AM, Bruce Wheaton <[email protected]> >> wrote: >>> >>> On Apr 10, 2010, at 4:07 AM, Thomas Worth wrote: >>> >>>> I have a loop that decodes frames using avcodec_decode_video2(), and >>>> am spawning threads to convert the data put into the AVFrame struct >>>> and write it to disk. However, even though I allocated multiple >>>> structs to hold the picture data, frames are overwriting each other: >>> >>> Are you serializing access to the file? Possibly the frames are fine but >>> all >>> the threads are doing overlapping writes to the file. >>> >>> Bruce >> >> Yep. Each new thread gets its own AVFrame and unique file number. Its >> job is to write one frame to disk, using the passed AVFrame struct as >> its picture source. It uses the passed file number (from the main for >> loop) to serialize the output image sequence. So, each thread will >> only ever get one frame worth of data (the result from >> avcodec_decode_video2), making this problem seem impossible. However, >> I'm not sure how libavcodec handles this stuff internally so I'm not >> sure how to fix it. >> >> I noticed that allocating multiple AVFrame structures in an array >> doesn't make any difference versus just using the same struct over and >> over. >> >> Do I need to set up the program in such a way that the libav* >> libraries know I'm doing simultaneous (threaded) reads? > > Oh, I see. So you're writing each frame to disk? But you want each thread to > actually do decoding? Hmm. I'm not sure that's supported. There's an > ffmpeg-mt fork that I've been using, and it will jump off and do decoding of > simultaneous frames or slices of frames as the codec allows, but even that > comes back to a single thread to 'deliver' the final frames. > > The more I think about it, the more certain I am that you can't run > decode_video on the same movie from different threads - there's a fair > amount of 'global' state to the codec. I suggest you allow ffmpeg-mt to > multi-thread your decoding, then pick up the completed frames in one thread, > then pass them off to multiple threads to do the disk writing.
Well, I only have one thread that runs avcodec_decode_video2. And the only reason it runs in its own thread is to allow UI input, otherwise it would just run in the main thread. That "decode" thread, as we'll call it, contains the av_read_frame() loop, which contains the avcodec_decode_video2() function. I pass avcodec_decode_video2's resulting AVFrame struct that has been decoded to the worker threads. So, the actual decoding phase only runs once per loop iteration, just like it would normally. It seems like the AVFrame struct that avcodec_decode_video2 delivers (which contains the decoded video frame) is referencing something that is changed during the next decode cycle. This is the case whether I create an array of AVFrame*s or just use one. It seems to me that creating a unique AVFrame struct for each thread would only point to that exact part of the file, unless the next time avcodec_decode_video2 is called overwrites all previous AVFrame structures. _______________________________________________ libav-user mailing list [email protected] https://lists.mplayerhq.hu/mailman/listinfo/libav-user
