Huh.
> > >>> >>>>>> > [wmav2 @ 0x106829e20] prev_block_len_bits N out of range
> > >>> >>>>>> > (where N is in the range 4..6).
> > >>> >>>>>>
> > >>> >>>>>> Do these errors occur when you're decoding only a single file,
> > >>> >>>>>> without
> > >>> >>>>>> threading?
> > >>> >>>>>
> > >>> >>>>> Yes they do, and on both platforms, though I've never seen them
> > >>> >>>>> cause
> > >>> >>>>> a segfault when not parallelised. Also interspersed with those
> > >>> >>>>> errors
> > >>> >>>>> are
> > >>> >>>>> [wmav2 @ 0x1030a9800] overflow in spectral RLE, ignoring
> > >>> >>>>> [wmav2 @ 0x1030a9800] frame_len overflow
> > >>> >>>>>
> > >>> >>>>> And very occasionally
> > >>> >>>>> [wmav2 @ 0x1030a9800] len -211 invalid
> > >>> >>>>>
> > >>> >>>>> Do these errors suggest anything in particular to you?
> > >>> >>>>
> > >>> >>>> Yes, is it possible you're not setting AVCodecContext->bit_rate,
> > >>> >>>> ->block_align, ->extradata or ->extradata_size?
> > >>> >>>
> > >>> >>> I had thought (based on what I'd read in the ffmpeg doxygen) that
> > >>> >>> all
> > >>> >>> of those fields (certainly bit_rate, extra_data and extradata_size)
> > >>> >>> were set internally by libav for decoding, and only needed to be set
> > >>> >>> by the user for encoding?
> > >>> >>>
> > >>> >>> If I'm wrong, could you suggest what I should set them to, for a
> > >>> >>> general decoding solution? I'm seeing no examples online that set
> > >>> >>> them.
> > >>> >>
> > >>> >> They are set, but (in the case of WMA) by the demuxer instead of the
> > >>> >> decoder. My impression is you're not using the
> > >>> >> AVFormatContext->streams[%d]->codec for decoding, but rather create
> > >>> >> one independently. Then you need to copy the demuxer values to the
> > >>> >> decoder values. If you're using your own demuxer instead of
> > >>> >> libavformat's, see libavformat for how to read them.
> > >>> >>
> > >>> >
> > >>> > I'm doing something in the neighbourhood of this:
> > >>> >
> > >>> > AVCodecContext* cCtx = fCtx->streams[audioStream]->codec;
> > >>> > codec = avcodec_find_decoder(cCtx->codec_id);
> > >>> > if(codec == NULL){
> > >>> > throw Exception();
> > >>> > }
> > >>> > if(avcodec_open2(cCtx, codec, &opts) < 0){
> > >>> > throw Exception();
> > >>> > }
> > >>> >
> > >>> > And then passing that codec context into the decode job. So I think
> > >>> > that should be fine, no?
> > >>>
> > >>> Probably. Can a tool like avconv or avplay playback the file
> > >>> succesfully without throwing errors?
> > >>
> > >> Yes. Plays back with no errors at all.
> > >
> > > Can we see your full code? It's possible you're initializing the code
> > > at the wrong moment when these things aren't known yet...
> >
> > Sure thing:
> > https://github.com/ibsh/is_KeyFinder/blob/master/decoderlibav.cpp
> >
> > Although the function at line 155 (which is probably the one you're
> > most interested) now does its memory management with av_malloc as
> > mentioned earlier in the thread, I just haven't merged that commit
> > yet:
> >
> > int LibAvDecoder::decodePacket(AVCodecContext* cCtx, AVPacket* avpkt,
> > AudioStream* ab){
> > while(avpkt->size > 0){
> > int outputBufferSize = ((AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2) *
> > sizeof(int16_t);
> > int16_t* outputBuffer = (int16_t*)av_malloc(outputBufferSize);
> > int bytesConsumed = avcodec_decode_audio3(cCtx, outputBuffer,
> > &outputBufferSize, avpkt);
> > if(bytesConsumed <= 0){
> > avpkt->size = 0;
> > av_free(outputBuffer);
> > return 1;
> > }
> > int newSamplesDecoded = outputBufferSize / sizeof(int16_t);
> > int oldSampleCount = ab->getSampleCount();
> > try{
> > ab->addToSampleCount(newSamplesDecoded);
> > }catch(Exception& e){
> > av_free(outputBuffer);
> > throw e;
> > }
> > for(int i = 0; i < newSamplesDecoded; i++)
> > ab->setSample(oldSampleCount+i, (float)outputBuffer[i]);
> > if(bytesConsumed < avpkt->size){
> > size_t newLength = avpkt->size - bytesConsumed;
> > uint8_t* datacopy = avpkt->data;
> > avpkt->data = (uint8_t*)av_malloc(newLength);
> > memcpy(avpkt->data, datacopy + bytesConsumed, newLength);
> > av_free(datacopy);
> > }
> > avpkt->size -= bytesConsumed;
> > av_free(outputBuffer);
> > }
> > return 0;
> > }
> >
> > Ibrahim
>
> What do you think, Ronald? Can you see an initialisation problem?
>
> I've been poring over this myself but I just can't see any issues with
> the memory allocation, though I must admit I'm not happy with the
> memcpy to reduce the packet data.
>
> Am I barking up the wrong tree, do you think? I've been toying with
> starting from first principles and remodelling what avplay does, since
> it seems to avoid the decoding errors. But if the issue is in the
> parallelisation, that may not help with the segfault.
This is interesting. Having commented out the line:
av_dict_set(&dict, "b", "2.5M", 0);
The Windows Media files are now decoding correctly (at least on Mac);
I'll need to try this on Windows to see if it has an effect on the
segfault.
I note that that line appears in lots of example code online but it's
not explained anywhere what the "b" key represents. Can someone
explain what it does?. Anyway I'll check on my Windows VM when I get
home and report the effects.
Thanks so much for your help Ronald.
Ibrahim
_______________________________________________
libav-api mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-api