On May 10, 2013, at 3:44 AM, mohM <[email protected]> wrote:

> I saw another thread on here similar to this, but it didn't really solve my
> problem. Basically, I'm still working on getting my audio encoding to work,
> and I'm now having trouble getting a basic audio encode to work...What I'm
> trying to do is get a single frame of audio to encode. The first call to
> avcodec_encode_audio2() is successfull, and if I leave out the flush loop,
> the console output tells me:
> 
> As far as I can understand from the documentation and my experience with
> video encoding, this is pretty normal. When I try to flush the frame by
> passing NULL into avcodec_encode_audio2(), however, the program crashes and
> says "Integer division by zero" in mlock.c. Am I doing something wrong here?
> Any ideas?

Hey there...I assume the "another thread" you are referring to is mine that was 
posted a few days ago on the same topic. I can identify where you are coming 
from. This issue, its proper handling, and surrounding implications are not 
outright documented as a whole in a single place, and where it is referred to 
in documentation (several places), there seems to be details that have to be 
inferred. Disclaimer -- I am no expert on this, and don't know if what I put 
here will help solve your problem, but it's the best of what I understand about 
it, for better or worse. Hopefully it will help. 

Here's where you can find some references to discussion of this: 

 - avcodec.h, line 4014, frame parameter. Here it mentions using NULL to flush. 
It doesn't mention exactly whether flushing is a bulk or repeated operation, 
nor the implications for pts or dts for flushed frames here. But it does 
reference CODEC_CAP_DELAY, and if you follow to to that parameter's doc, 
there's much more helpful info. 

- avcodec.h, line 737, CODEC_CAP_DELAY define. Explains that encoding needs to 
end with flushing, and says in so many words that you need to repeat the 
process of passing a NULL parameter until the encoder has no more frames. Make 
sure to read the NOTE, as it gives some important information about pts and 
dts. 

- decoding_encoding.h, line 447, flush loop -- it says "get the delayed frames" 
--  that's essentially flushing the encoder. It doesn't do anything with pts 
and dts (nor did it for anywhere in this example, but see the CODEC_CAP_DELAY 
doc for that detail). 

As I understand it, the general idea is this: when you execute 
avcodec_encode_audio2, you are giving the encoder an audio buffer of samples to 
encode. The encoder may optionally populate and output a packet for you to do 
further processing (presumably stream or write to drive). That part you 
probably know and have working. In the case where the encoder does not populate 
and output a packet in that call, it may have decided for some encoding reason 
to hold the data. What that means is that after you send the last of your 
sample data to the encoder in your last normal avcodec_encode_audio2 call, the 
encoder may still be holding on to data that you previously sent it.

You need to flush this data out of the encoder so that you can process it like 
the rest of the encoded data by repeating calls to avcodec_encode_audio2 with 
NULL as the frame parameter to tell the codec to release a single buffered 
frame. That's important -- this isn't a single call, it may be several. Repeat 
the process until got_packet_ptr returns a 0 value, indicating that no packet 
has been returned. Note that the decoding_encoding.c example references a use 
case where all of the data is known at the time of encoding -- in a streaming 
scenario, it will usually be the input's attempt to close the stream which 
should trigger the flushing of the codec. 

Note there are a number of unknowns still for me: 

- I do not know what codecs support CODEC_CAP_DELAY, or if there's something 
significant which determines if a codec supports it, or if it is entirely 
arbitrary. 
- I do not know whether you can or what determines if you can change the 
CODEC_CAP_DELAY value for an encoder from what it is set at after you create 
the encoder.  
- I do not know if a codec without CODEC_CAP_DELAY set can still buffer frames, 
and if so, how it would be flushed. 

That's the best I've pieced together. I hope it helps. If not, I wish you the 
best of success solving the problem. If I encounter anything which might seem 
relevant, I'll post it. 

Cheers, 

Brad



_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to