[Libav-user] How to read in planar data?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[Libav-user] How to read in planar data?

Mark McKay

I'm having trouble trying to figure out how to read in planar data.  I have a file that has data in the AV_SAMPLE_FMT_FLTP format with two channels.  Below is my attempt to read in the data.  This will crash with a memory problem if I try to read in the second channel (but it will complete if I bypass the second and just read from channel 0).  Am I doing this right?


void AudioReader::loadAudioFrame(AVPacket& packet)
{
int err = avcodec_send_packet(aCodecCtx, &packet);
if (err < 0)
{
qDebug("Error sending packet to decoder");
return;
}

int numChannels = aCodecCtx->channels;
while (err >= 0)
{
err = avcodec_receive_frame(aCodecCtx, aFrame);
if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
return;

if (err < 0)
{
qDebug() << "Error decoding packet: " << err;
return;
}

int bytesPerSample = av_get_bytes_per_sample(aCodecCtx->sample_fmt);
if (bytesPerSample < 0) {
/* This should not occur, checking just for paranoia */
fprintf(stderr, "Failed to calculate data size\n");
exit(1);
}


int bufferSize = av_samples_get_buffer_size(NULL,
aCodecCtx->channels,
aFrame->nb_samples,
aCodecCtx->sample_fmt,
1);

switch(aCodecCtx->sample_fmt)
{
...
case AV_SAMPLE_FMT_FLTP:
{
//Serial format - change to interleaved order
for (int i = 0; i < aFrame->nb_samples; i++)
{
for (int ch = 0; ch < numChannels; ch++)
{
_audioBytes.append((const char *)aFrame->data[ch] + i * sizeof(float), sizeof(float));
}
}
break;
}
}
}



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

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to read in planar data?

Paul B Mahol
On 12/6/19, Mark McKay <[hidden email]> wrote:

> I'm having trouble trying to figure out how to read in planar data.  I
> have a file that has data in the AV_SAMPLE_FMT_FLTP format with two
> channels.  Below is my attempt to read in the data.  This will crash
> with a memory problem if I try to read in the second channel (but it
> will complete if I bypass the second and just read from channel 0).  Am
> I doing this right?
>
> void AudioReader::loadAudioFrame(AVPacket& packet)
> {
> int err = avcodec_send_packet(aCodecCtx, &packet);
> if (err < 0)
> {
> qDebug("Error sending packet to decoder");
> return;
> }
>
> int numChannels = aCodecCtx->channels;
> while (err >= 0)
> {
> err = avcodec_receive_frame(aCodecCtx, aFrame);
> if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
> return;
>
> if (err < 0)
> {
> qDebug() << "Error decoding packet: " << err;
> return;
> }
>
> int bytesPerSample = av_get_bytes_per_sample(aCodecCtx->sample_fmt);
> if (bytesPerSample < 0) {
> /* This should not occur, checking just for paranoia */
> fprintf(stderr, "Failed to calculate data size\n");
> exit(1);
> }
>
> int bufferSize = av_samples_get_buffer_size(NULL,
> aCodecCtx->channels,
> aFrame->nb_samples,
> aCodecCtx->sample_fmt,
> 1);
>
> switch(aCodecCtx->sample_fmt)
> {
> ...
> case AV_SAMPLE_FMT_FLTP:
> {
> //Serial format - change to interleaved order
> for (int i = 0; i < aFrame->nb_samples; i++)
> {
> for (int ch = 0; ch < numChannels; ch++)
> {
> _audioBytes.append((const char *)aFrame->data[ch] + i * sizeof(float),
> sizeof(float));
> }
> }
> break;
> }
> }
> }

Use valgrind to point to exact position in your code that triggers crash.

>
> ---
> http://www.kitfox.com
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to read in planar data?

Mark McKay
In reply to this post by Mark McKay
Just reposting with properly formatted code:

void AudioReader::loadAudioFrame(AVPacket& packet)
{
     int err = avcodec_send_packet(aCodecCtx, &packet);
     if (err < 0)
     {
         qDebug("Error sending packet to decoder");
         return;
     }

     int numChannels = aCodecCtx->channels;
     while (err >= 0)
     {
         err = avcodec_receive_frame(aCodecCtx, aFrame);
         if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
         return;

         if (err < 0)
         {
             qDebug() << "Error decoding packet: " << err;
             return;
         }

         int bytesPerSample =
av_get_bytes_per_sample(aCodecCtx->sample_fmt);
         if (bytesPerSample < 0) {
         /* This should not occur, checking just for paranoia */
         fprintf(stderr, "Failed to calculate data size\n");
         exit(1);
         }


         int bufferSize = av_samples_get_buffer_size(NULL,
         aCodecCtx->channels,
         aFrame->nb_samples,
         aCodecCtx->sample_fmt,
         1);

         switch(aCodecCtx->sample_fmt)
         {
         ...
         case AV_SAMPLE_FMT_FLTP:
         {
             //Serial format - change to interleaved order
             for (int i = 0; i < aFrame->nb_samples; i++)
             {
                 for (int ch = 0; ch < numChannels; ch++)
                 {
                     _audioBytes.append((const char *)aFrame->data[ch] +
i * sizeof(float), sizeof(float));
                 }
             }
             break;
         }
         }
}



On 2019-12-06 15:55, Mark McKay wrote:

> I'm having trouble trying to figure out how to read in planar data.  I
> have a file that has data in the AV_SAMPLE_FMT_FLTP format with two
> channels.  Below is my attempt to read in the data.  This will crash
> with a memory problem if I try to read in the second channel (but it
> will complete if I bypass the second and just read from channel 0).  Am
> I doing this right?
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to read in planar data?

Mark McKay
I should have mentioned that the crash was happening at the line

     _audioBytes.append((const char *)aFrame->data[ch] + i *
sizeof(float), sizeof(float));

This happens after 590 packets have been read.




On 2019-12-06 17:05, Mark McKay wrote:

> Just reposting with properly formatted code:
>
> void AudioReader::loadAudioFrame(AVPacket& packet)
> {
>     int err = avcodec_send_packet(aCodecCtx, &packet);
>     if (err < 0)
>     {
>         qDebug("Error sending packet to decoder");
>         return;
>     }
>
>     int numChannels = aCodecCtx->channels;
>     while (err >= 0)
>     {
>         err = avcodec_receive_frame(aCodecCtx, aFrame);
>         if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
>         return;
>
>         if (err < 0)
>         {
>             qDebug() << "Error decoding packet: " << err;
>             return;
>         }
>
>         int bytesPerSample =
> av_get_bytes_per_sample(aCodecCtx->sample_fmt);
>         if (bytesPerSample < 0) {
>         /* This should not occur, checking just for paranoia */
>         fprintf(stderr, "Failed to calculate data size\n");
>         exit(1);
>         }
>
>
>         int bufferSize = av_samples_get_buffer_size(NULL,
>         aCodecCtx->channels,
>         aFrame->nb_samples,
>         aCodecCtx->sample_fmt,
>         1);
>
>         switch(aCodecCtx->sample_fmt)
>         {
>         ...
>         case AV_SAMPLE_FMT_FLTP:
>         {
>             //Serial format - change to interleaved order
>             for (int i = 0; i < aFrame->nb_samples; i++)
>             {
>                 for (int ch = 0; ch < numChannels; ch++)
>                 {
>                     _audioBytes.append((const char *)aFrame->data[ch] +
> i * sizeof(float), sizeof(float));
>                 }
>             }
>             break;
>         }
>         }
> }
>
>
>
> On 2019-12-06 15:55, Mark McKay wrote:
>
>> I'm having trouble trying to figure out how to read in planar data.  I
>> have a file that has data in the AV_SAMPLE_FMT_FLTP format with two
>> channels.  Below is my attempt to read in the data.  This will crash
>> with a memory problem if I try to read in the second channel (but it
>> will complete if I bypass the second and just read from channel 0).  
>> Am I doing this right?
> _______________________________________________
> Libav-user mailing list
> [hidden email]
> https://ffmpeg.org/mailman/listinfo/libav-user
>
> To unsubscribe, visit link above, or email
> [hidden email] with subject "unsubscribe".
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to read in planar data?

Mark McKay
Nevermind - it looks like  my problem is coming from running out of
memory.  I did however learn that I ought to use aFrame->extended_data
instead of aFrame->data when reading audio data.




On 2019-12-06 17:37, Mark McKay wrote:

> I should have mentioned that the crash was happening at the line
>
>     _audioBytes.append((const char *)aFrame->data[ch] + i *
> sizeof(float), sizeof(float));
>
> This happens after 590 packets have been read.
>
>
>
>
> On 2019-12-06 17:05, Mark McKay wrote:
>> Just reposting with properly formatted code:
>>
>> void AudioReader::loadAudioFrame(AVPacket& packet)
>> {
>>     int err = avcodec_send_packet(aCodecCtx, &packet);
>>     if (err < 0)
>>     {
>>         qDebug("Error sending packet to decoder");
>>         return;
>>     }
>>
>>     int numChannels = aCodecCtx->channels;
>>     while (err >= 0)
>>     {
>>         err = avcodec_receive_frame(aCodecCtx, aFrame);
>>         if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
>>         return;
>>
>>         if (err < 0)
>>         {
>>             qDebug() << "Error decoding packet: " << err;
>>             return;
>>         }
>>
>>         int bytesPerSample =
>> av_get_bytes_per_sample(aCodecCtx->sample_fmt);
>>         if (bytesPerSample < 0) {
>>         /* This should not occur, checking just for paranoia */
>>         fprintf(stderr, "Failed to calculate data size\n");
>>         exit(1);
>>         }
>>
>>
>>         int bufferSize = av_samples_get_buffer_size(NULL,
>>         aCodecCtx->channels,
>>         aFrame->nb_samples,
>>         aCodecCtx->sample_fmt,
>>         1);
>>
>>         switch(aCodecCtx->sample_fmt)
>>         {
>>         ...
>>         case AV_SAMPLE_FMT_FLTP:
>>         {
>>             //Serial format - change to interleaved order
>>             for (int i = 0; i < aFrame->nb_samples; i++)
>>             {
>>                 for (int ch = 0; ch < numChannels; ch++)
>>                 {
>>                     _audioBytes.append((const char *)aFrame->data[ch]
>> + i * sizeof(float), sizeof(float));
>>                 }
>>             }
>>             break;
>>         }
>>         }
>> }
>>
>>
>>
>> On 2019-12-06 15:55, Mark McKay wrote:
>>
>>> I'm having trouble trying to figure out how to read in planar data.  
>>> I have a file that has data in the AV_SAMPLE_FMT_FLTP format with two
>>> channels.  Below is my attempt to read in the data.  This will crash
>>> with a memory problem if I try to read in the second channel (but it
>>> will complete if I bypass the second and just read from channel 0).  
>>> Am I doing this right?
>> _______________________________________________
>> Libav-user mailing list
>> [hidden email]
>> https://ffmpeg.org/mailman/listinfo/libav-user
>>
>> To unsubscribe, visit link above, or email
>> [hidden email] with subject "unsubscribe".
> _______________________________________________
> Libav-user mailing list
> [hidden email]
> https://ffmpeg.org/mailman/listinfo/libav-user
>
> To unsubscribe, visit link above, or email
> [hidden email] with subject "unsubscribe".
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".