1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-12-25 14:11:28 +01:00

fix random fixed buffer size and add quick and simple planar import support

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Signed-off-by: Benjamin Drung <bdrung@debian.org>
This commit is contained in:
benjamin.drung@gmail.com
2014-05-23 20:27:54 +00:00
parent f8be1f9668
commit 5ae8679e3c
3 changed files with 62 additions and 31 deletions

View File

@@ -478,10 +478,32 @@ int import_ffmpeg_decode_frame(streamContext *sc, bool flushing)
}
}
AVPacket avpkt;
av_init_packet(&avpkt);
avpkt.data = pDecode;
avpkt.size = nDecodeSiz;
AVFrame *frame = av_frame_alloc();
int got_output = 0;
nBytesDecoded =
avcodec_decode_audio4(sc->m_codecCtx,
frame, // out
&got_output, // out
&avpkt); // in
sc->m_decodedAudioSamplesValidSiz = frame->nb_samples;
if (nBytesDecoded < 0)
{
// Decoding failed. Don't stop.
return -1;
}
sc->m_samplefmt = sc->m_codecCtx->sample_fmt;
sc->m_samplesize = av_get_bits_per_sample_format(sc->m_samplefmt) / 8;
unsigned int newsize = FFMAX(sc->m_pkt.size * sc->m_samplesize, 192000); //FIXME
int channels = sc->m_codecCtx->channels;
unsigned int newsize = sc->m_samplesize * frame->nb_samples * channels;
// Reallocate the audio sample buffer if it's smaller than the frame size.
if (newsize > sc->m_decodedAudioSamplesSiz )
{
@@ -499,38 +521,20 @@ int import_ffmpeg_decode_frame(streamContext *sc, bool flushing)
return -1;
}
}
sc->m_decodedAudioSamplesValidSiz = sc->m_decodedAudioSamplesSiz;
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 25, 0)
// avcodec_decode_audio3() expects the size of the output buffer as the 3rd parameter but
// also returns the number of bytes it decoded in the same parameter.
AVPacket avpkt;
av_init_packet(&avpkt);
avpkt.data = pDecode;
avpkt.size = nDecodeSiz;
nBytesDecoded =
avcodec_decode_audio3(sc->m_codecCtx,
(int16_t *)sc->m_decodedAudioSamples, // out
&sc->m_decodedAudioSamplesValidSiz, // in/out
&avpkt); // in
#else
// avcodec_decode_audio2() expects the size of the output buffer as the 3rd parameter but
// also returns the number of bytes it decoded in the same parameter.
nBytesDecoded =
avcodec_decode_audio2(sc->m_codecCtx,
(int16_t *) sc->m_decodedAudioSamples, // out
&sc->m_decodedAudioSamplesValidSiz, // in/out
pDecode, // in
nDecodeSiz); // in
#endif
if (nBytesDecoded < 0)
{
// Decoding failed. Don't stop.
return -1;
if (frame->data[1]) {
for (int i = 0; i<frame->nb_samples; i++) {
for (int ch = 0; ch<channels; ch++) {
memcpy(sc->m_decodedAudioSamples + sc->m_samplesize * (ch + channels*i),
frame->extended_data[ch] + sc->m_samplesize*i,
sc->m_samplesize);
}
}
} else {
memcpy(sc->m_decodedAudioSamples, frame->data[0], newsize);
}
av_frame_free(&frame);
// We may not have read all of the data from this packet. If so, the user can call again.
// Whether or not they do depends on if m_pktRemainingSiz == 0 (they can check).
sc->m_pktDataPtr += nBytesDecoded;
@@ -1015,6 +1019,7 @@ bool FFmpegLibs::InitLibs(wxString libpath_format, bool WXUNUSED(showerr))
FFMPEG_INITDYN(avcodec, avcodec_find_encoder_by_name);
FFMPEG_INITDYN(avcodec, avcodec_find_decoder);
FFMPEG_INITDYN(avcodec, avcodec_open2);
FFMPEG_INITDYN(avcodec, avcodec_decode_audio4);
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 25, 0)
FFMPEG_INITDYN(avcodec, avcodec_decode_audio3);
#else
@@ -1047,6 +1052,8 @@ bool FFmpegLibs::InitLibs(wxString libpath_format, bool WXUNUSED(showerr))
FFMPEG_INITDYN(avutil, av_freep);
FFMPEG_INITDYN(avutil, av_rescale_q);
FFMPEG_INITDYN(avutil, avutil_version);
FFMPEG_INITDYN(avutil, av_frame_alloc);
FFMPEG_INITDYN(avutil, av_frame_free);
wxLogMessage(wxT("All symbols loaded successfully. Initializing the library."));
#endif

View File

@@ -543,6 +543,12 @@ extern "C" {
(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options),
(avctx, codec, options);
);
FFMPEG_FUNCTION_WITH_RETURN(
int,
avcodec_decode_audio4,
(AVCodecContext *avctx, AVFrame *frame, int *got_output, const AVPacket *avpkt),
(avctx, frame, got_output, avpkt)
);
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 25, 0)
FFMPEG_FUNCTION_WITH_RETURN(
int,
@@ -874,6 +880,17 @@ extern "C" {
(const AVCodec *codec),
(codec)
);
FFMPEG_FUNCTION_WITH_RETURN(
AVFrame*,
av_frame_alloc,
(void),
()
);
FFMPEG_FUNCTION_NO_RETURN(
av_frame_free,
(AVFrame **frame),
(frame)
);
};
#endif

View File

@@ -493,6 +493,8 @@ int FFmpegImportFileHandle::Import(TrackFactory *trackFactory,
{
case AV_SAMPLE_FMT_U8:
case AV_SAMPLE_FMT_S16:
case AV_SAMPLE_FMT_U8P:
case AV_SAMPLE_FMT_S16P:
mScs[s]->m_osamplesize = sizeof(int16_t);
mScs[s]->m_osamplefmt = int16Sample;
break;
@@ -750,22 +752,27 @@ int FFmpegImportFileHandle::WriteData(streamContext *sc)
switch (sc->m_samplefmt)
{
case AV_SAMPLE_FMT_U8:
case AV_SAMPLE_FMT_U8P:
((int16_t *)tmp[chn])[index] = (int16_t) (*(uint8_t *)in - 0x80) << 8;
break;
case AV_SAMPLE_FMT_S16:
case AV_SAMPLE_FMT_S16P:
((int16_t *)tmp[chn])[index] = (int16_t) *(int16_t *)in;
break;
case AV_SAMPLE_FMT_S32:
case AV_SAMPLE_FMT_S32P:
((float *)tmp[chn])[index] = (float) *(int32_t *)in * (1.0 / (1 << 31));
break;
case AV_SAMPLE_FMT_FLT:
case AV_SAMPLE_FMT_FLTP:
((float *)tmp[chn])[index] = (float) *(float *)in;
break;
case AV_SAMPLE_FMT_DBL:
case AV_SAMPLE_FMT_DBLP:
((float *)tmp[chn])[index] = (float) *(double *)in;
break;