Hi,
the attached patch should fix this bug.
--
Anton Khirnov
Index: avifile-0.7.48~20090503.ds/lib/aviread/FFReadStream.cpp
===================================================================
--- avifile-0.7.48~20090503.ds.orig/lib/aviread/FFReadStream.cpp 2014-03-01 07:53:20.000000000 +0000
+++ avifile-0.7.48~20090503.ds/lib/aviread/FFReadStream.cpp 2014-03-01 07:55:35.028095554 +0000
@@ -12,32 +12,32 @@
AVM_BEGIN_NAMESPACE;
-static int get_fcc(enum CodecID id)
+static int get_fcc(enum AVCodecID id)
{
const struct id2fcc {
- enum CodecID id;
+ enum AVCodecID id;
uint32_t fcc;
} id2fcct[] = {
- { CODEC_ID_MPEG1VIDEO, RIFFINFO_MPG1 },
- { CODEC_ID_MPEG1VIDEO, mmioFOURCC('P', 'I', 'M', '1') },
- { CODEC_ID_MPEG2VIDEO, RIFFINFO_MPG2 },
- { CODEC_ID_H263, mmioFOURCC('H', '2', '6', '3') },
- { CODEC_ID_H263P, mmioFOURCC('H', '2', '6', '3') },
- { CODEC_ID_H263I, mmioFOURCC('I', '2', '6', '3') },
- { CODEC_ID_H264, mmioFOURCC('H', '2', '6', '4') },
- { CODEC_ID_MSMPEG4V3, mmioFOURCC('D', 'I', 'V', '3') },
- { CODEC_ID_MPEG4, mmioFOURCC('D', 'I', 'V', 'X') },
- { CODEC_ID_MSMPEG4V2, mmioFOURCC('M', 'P', '4', '2') },
- { CODEC_ID_FLV1, mmioFOURCC('F', 'L', 'V', '1') },
- { CODEC_ID_MJPEG, mmioFOURCC('M', 'J', 'P', 'G') },
- { CODEC_ID_DTS, 0x10 },
- { CODEC_ID_MP2, 0x50 },
- { CODEC_ID_MP3, 0x55 },
- { CODEC_ID_AC3, WAVE_FORMAT_DVM },
- { CODEC_ID_AAC, 'M' | ('P' << 8) }, // MP4A
- { CODEC_ID_DVVIDEO, mmioFOURCC('D', 'V', 'S', 'D') },
- { CODEC_ID_DVAUDIO, ('D' << 8) | 'A' },
- { CODEC_ID_NONE }
+ { AV_CODEC_ID_MPEG1VIDEO, RIFFINFO_MPG1 },
+ { AV_CODEC_ID_MPEG1VIDEO, mmioFOURCC('P', 'I', 'M', '1') },
+ { AV_CODEC_ID_MPEG2VIDEO, RIFFINFO_MPG2 },
+ { AV_CODEC_ID_H263, mmioFOURCC('H', '2', '6', '3') },
+ { AV_CODEC_ID_H263P, mmioFOURCC('H', '2', '6', '3') },
+ { AV_CODEC_ID_H263I, mmioFOURCC('I', '2', '6', '3') },
+ { AV_CODEC_ID_H264, mmioFOURCC('H', '2', '6', '4') },
+ { AV_CODEC_ID_MSMPEG4V3, mmioFOURCC('D', 'I', 'V', '3') },
+ { AV_CODEC_ID_MPEG4, mmioFOURCC('D', 'I', 'V', 'X') },
+ { AV_CODEC_ID_MSMPEG4V2, mmioFOURCC('M', 'P', '4', '2') },
+ { AV_CODEC_ID_FLV1, mmioFOURCC('F', 'L', 'V', '1') },
+ { AV_CODEC_ID_MJPEG, mmioFOURCC('M', 'J', 'P', 'G') },
+ { AV_CODEC_ID_DTS, 0x10 },
+ { AV_CODEC_ID_MP2, 0x50 },
+ { AV_CODEC_ID_MP3, 0x55 },
+ { AV_CODEC_ID_AC3, WAVE_FORMAT_DVM },
+ { AV_CODEC_ID_AAC, 'M' | ('P' << 8) }, // MP4A
+ { AV_CODEC_ID_DVVIDEO, mmioFOURCC('D', 'V', 'S', 'D') },
+ { AV_CODEC_ID_DVAUDIO, ('D' << 8) | 'A' },
+ { AV_CODEC_ID_NONE }
};
//printf("TRANSLATE %d 0x%x\n", id, id);
for (const struct id2fcc* p = id2fcct; p->id; p++)
@@ -60,7 +60,7 @@
AVM_WRITE("FF stream", "Starttime:%" PRId64 " Duration:%fs\n", m_StartTime, m_dLength);
//printf("codec %d %.4s\n", avs->codec->codec_id, &avs->codec->codec_tag);
//printf("CODECRA %d %d %d\n", avs->codec->frame_rate, avs->codec->frame_rate_base, avs->r_frame_rate_base);
- if (0 && avs->codec->codec_id == CODEC_ID_MPEG1VIDEO)
+ if (0 && avs->codec->codec_id == AV_CODEC_ID_MPEG1VIDEO)
{
m_pAvContext = avcodec_alloc_context3(NULL);
//AVCodec* codec = avcodec_find_encoder(avs->codec->codec_id);
@@ -252,7 +252,7 @@
wfx.cbSize = (uint16_t)(wfx.cbSize + avs->codec->extradata_size);
}
- if (avs->codec->codec_id == CODEC_ID_AAC) {
+ if (avs->codec->codec_id == AV_CODEC_ID_AAC) {
// hmm currenly hack - ffmpeg seems to fail properly detect this stream
wfx.nChannels = 2;
wfx.nSamplesPerSec = 44100;
Index: avifile-0.7.48~20090503.ds/plugins/libffmpeg/FFAudioDecoder.cpp
===================================================================
--- avifile-0.7.48~20090503.ds.orig/plugins/libffmpeg/FFAudioDecoder.cpp 2014-03-01 07:53:20.000000000 +0000
+++ avifile-0.7.48~20090503.ds/plugins/libffmpeg/FFAudioDecoder.cpp 2014-03-02 08:03:38.747337206 +0000
@@ -17,6 +17,8 @@
avcodec_close(m_pAvContext);
free(m_pAvContext);
}
+ avresample_free(&avr);
+ av_frame_free(&frame);
}
int FFAudioDecoder::Convert(const void* in_data, size_t in_size,
@@ -53,25 +55,58 @@
m_pAvContext = 0;
return -1;
}
+ frame = av_frame_alloc();
+ if (!frame)
+ return -1;
}
//printf("%0lx %0lx %0lx %0lx\n", ((long*)in_data)[0], ((long*)in_data)[1], ((long*)in_data)[2], ((long*)in_data)[3]);
+
AVPacket avpkt;
av_init_packet(&avpkt);
avpkt.data = (uint8_t*)in_data;
avpkt.size = (int)in_size;
- int framesz = AVCODEC_MAX_AUDIO_FRAME_SIZE;
-#ifdef HAVE_AVCODEC_DECODE_AUDIO3
- int hr = avcodec_decode_audio3(m_pAvContext, (int16_t*)out_data, &framesz, &avpkt);
-#else
- int hr = avcodec_decode_audio2(m_pAvContext, (int16_t*)out_data, &framesz,
- avpkt.data, avpkt.size);
-#endif
- //printf("CONVERT ins: %d outs:%" PRIsz " fs:%d h:%d\n", avpkt.size, out_size, framesz, hr);
+
+ int got_output;
+ int hr = avcodec_decode_audio4(m_pAvContext, frame, &got_output, &avpkt);
+
if (size_read)
*size_read = (hr < 0) ? 1 : hr;
- if (size_written)
- *size_written = (hr < 0) ? 0 : framesz;
+ if (hr >= 0 && got_output) {
+ if (!avr || frame->format != resample_format ||
+ frame->sample_rate != resample_rate || frame->channel_layout != resample_layout) {
+ avresample_free(&avr);
+
+ avr = avresample_alloc_context();
+ if (!avr)
+ return -1;
+
+ av_opt_set_int(avr, "in_sample_fmt", frame->format, 0);
+ av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+ av_opt_set_int(avr, "in_channel_layout", frame->channel_layout, 0);
+ av_opt_set_int(avr, "out_channel_layout", frame->channel_layout, 0);
+ av_opt_set_int(avr, "in_sample_rate", frame->sample_rate, 0);
+ av_opt_set_int(avr, "out_sample_rate", frame->sample_rate, 0);
+
+ hr = avresample_open(avr);
+ if (hr < 0) {
+ avresample_free(&avr);
+ return -1;
+ }
+ resample_format = frame->format;
+ resample_rate = frame->sample_rate;
+ resample_layout = frame->channel_layout;
+ }
+
+ hr = avresample_convert(avr, (uint8_t**)&out_data, out_size, frame->nb_samples,
+ frame->extended_data, frame->linesize[0], frame->nb_samples);
+ if (hr < 0)
+ return -1;
+
+ if (size_written)
+ *size_written = hr * 2 * m_pAvContext->channels;
+ }
+ //printf("CONVERT ins: %d outs:%" PRIsz " fs:%d h:%d\n", avpkt.size, out_size, framesz, hr);
if (hr < 0)
{
@@ -100,7 +135,7 @@
r = 2;
}
//printf("minsize %d 0x%x\n", r, m_Info.fourcc);
- return (r < AVCODEC_MAX_AUDIO_FRAME_SIZE) ? AVCODEC_MAX_AUDIO_FRAME_SIZE : r;
+ return r;
}
size_t FFAudioDecoder::GetSrcSize(size_t dest_size) const
Index: avifile-0.7.48~20090503.ds/plugins/libffmpeg/FFAudioDecoder.h
===================================================================
--- avifile-0.7.48~20090503.ds.orig/plugins/libffmpeg/FFAudioDecoder.h 2014-03-01 07:53:20.000000000 +0000
+++ avifile-0.7.48~20090503.ds/plugins/libffmpeg/FFAudioDecoder.h 2014-03-02 08:06:27.015520441 +0000
@@ -5,6 +5,11 @@
#include "avm_avcodec.h"
#include "avm_avformat.h"
+extern "C" {
+#include <libavresample/avresample.h>
+#include <libavutil/opt.h>
+}
+
AVM_BEGIN_NAMESPACE;
class FFAudioDecoder: public IAudioDecoder
@@ -12,6 +17,11 @@
static const uint_t MIN_AC3_CHUNK_SIZE = 16384;
AVCodec *m_pAvCodec;
AVCodecContext* m_pAvContext;
+ AVFrame *frame;
+ AVAudioResampleContext *avr;
+ int resample_format;
+ int resample_rate;
+ uint64_t resample_layout;
public:
FFAudioDecoder(AVCodec*, const CodecInfo&, const WAVEFORMATEX*);
~FFAudioDecoder();
Index: avifile-0.7.48~20090503.ds/plugins/libffmpeg/FFVideoEncoder.cpp
===================================================================
--- avifile-0.7.48~20090503.ds.orig/plugins/libffmpeg/FFVideoEncoder.cpp 2014-03-01 07:53:20.000000000 +0000
+++ avifile-0.7.48~20090503.ds/plugins/libffmpeg/FFVideoEncoder.cpp 2014-03-02 08:10:06.367971216 +0000
@@ -223,11 +223,15 @@
//printf("ECDING FF %p %p %p sz:%d\n", f.data[0], f.data[1], f.data[2], GetOutputSize());
//printf("ECDING FF %d %d %d\n", f.linesize[0], f.linesize[1], f.linesize[2]);
- int rsize = avcodec_encode_video(m_pAvContext, (unsigned char*) dest,
- GetOutputSize(), &f);
+ AVPacket pkt;
+ pkt.data = (uint8_t*)dest;
+ pkt.size = GetOutputSize();
+
+ int got_output;
+ int ret = avcodec_encode_video2(m_pAvContext, &pkt, &f, &got_output);
//printf("ECDING FF size %d\n", rsize);
if (size)
- *size = rsize;
+ *size = pkt.size;
if (is_keyframe) {
*is_keyframe = m_pAvContext->coded_frame->key_frame ? 16 : 0;
//printf("KEYFRAME %d\n", *is_keyframe);
Index: avifile-0.7.48~20090503.ds/plugins/libffmpeg/Makefile.am
===================================================================
--- avifile-0.7.48~20090503.ds.orig/plugins/libffmpeg/Makefile.am 2014-03-02 08:14:49.215025974 +0000
+++ avifile-0.7.48~20090503.ds/plugins/libffmpeg/Makefile.am 2014-03-02 08:15:04.333403321 +0000
@@ -13,7 +13,7 @@
libffmpeg.cpp
FFMPEG_CFLAGS = -I$(top_srcdir)/ffmpeg
-ffmpeg_la_LIBADD = ../../lib/libaviplay.la -lavcodec -lavformat -lavutil
+ffmpeg_la_LIBADD = ../../lib/libaviplay.la -lavcodec -lavformat -lavresample -lavutil
ffmpeg_la_LDFLAGS = -module -avoid-version
AM_CPPFLAGS = $(LTNOPIC) $(INSTRUMENT) $(FFMPEG_CFLAGS)
Index: avifile-0.7.48~20090503.ds/plugins/libffmpeg/libffmpeg.cpp
===================================================================
--- avifile-0.7.48~20090503.ds.orig/plugins/libffmpeg/libffmpeg.cpp 2009-04-24 23:58:48.000000000 +0000
+++ avifile-0.7.48~20090503.ds/plugins/libffmpeg/libffmpeg.cpp 2014-03-02 08:10:37.443743213 +0000
@@ -161,7 +161,7 @@
{
AVM_WRITE("FFMPEG video decoder", "looking for %s %d\n", info.dll.c_str(), bh.biSizeImage);
AVCodec* av = (bh.biCompression == CodecInfo::FFMPEG)
- ? avcodec_find_decoder(CodecID(bh.biSizeImage)) : avcodec_find_decoder_by_name(info.dll.c_str());
+ ? avcodec_find_decoder(AVCodecID(bh.biSizeImage)) : avcodec_find_decoder_by_name(info.dll.c_str());
if (av)
return new FFVideoDecoder(av, info, bh, flip);
ffmpeg_error_set("video codec not found");
@@ -176,7 +176,7 @@
AVCodec* av = (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE
&& avm_get_le32(&ffwfe.wfex.SubFormat.f1) == CodecInfo::FFMPEG)
- ? avcodec_find_decoder(CodecID(avm_get_le32(&ffwfe.dwCodecID))) :
+ ? avcodec_find_decoder(AVCodecID(avm_get_le32(&ffwfe.dwCodecID))) :
avcodec_find_decoder_by_name(info.dll.c_str());
if (av)
return new FFAudioDecoder(av, info, fmt);