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:
@@ -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
|
||||
|
||||
17
src/FFmpeg.h
17
src/FFmpeg.h
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user