Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2011-04-18 18:24:36 +0400
committerJoerg Mueller <nexyon@gmail.com>2011-04-18 18:24:36 +0400
commit5f08bfd46c31bb67780ee4081428be0d22f703ae (patch)
treee5097149e2e860a761292391184dd6946c3b979e /intern/audaspace/ffmpeg
parent54f31672701fae259dc28477e6b5ae323641c395 (diff)
Fix for [#26990] Loading file w packed audio crashes
FFMPEG was reallocating buffers it didn't own and wasn't allowed to. This workaround should work now flawlessly. Also fixing a bug regarding unpacking sounds, the UI stated unpacking to //audio/filename while it was unpacking to //sounds/filename
Diffstat (limited to 'intern/audaspace/ffmpeg')
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp50
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.h15
2 files changed, 58 insertions, 7 deletions
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index 0dc525b0e5a..ea6e0c549fa 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -172,7 +172,8 @@ static const char* fileopen_error = "AUD_FFMPEGReader: File couldn't be "
AUD_FFMPEGReader::AUD_FFMPEGReader(std::string filename) :
m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1),
- m_byteiocontext(NULL)
+ m_byteiocontext(NULL),
+ m_membuf(NULL)
{
// open file
if(av_open_input_file(&m_formatCtx, filename.c_str(), NULL, 0, NULL)!=0)
@@ -194,12 +195,15 @@ static const char* streamopen_error = "AUD_FFMPEGReader: Stream couldn't be "
AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer) :
m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1),
- m_membuffer(buffer)
+ m_membuffer(buffer),
+ m_membufferpos(0)
{
- m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
+ m_membuf = reinterpret_cast<data_t*>(av_malloc(FF_MIN_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE));
- if(init_put_byte(m_byteiocontext, (data_t*)buffer.get()->getBuffer(),
- buffer.get()->getSize(), 0, NULL, NULL, NULL, NULL) != 0)
+ m_byteiocontext = av_alloc_put_byte(m_membuf, FF_MIN_BUFFER_SIZE, 0, this,
+ read_packet, NULL, seek_packet);
+
+ if(!m_byteiocontext)
{
av_free(m_byteiocontext);
AUD_THROW(AUD_ERROR_FILE, fileopen_error);
@@ -207,7 +211,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer) :
AVProbeData probe_data;
probe_data.filename = "";
- probe_data.buf = (data_t*)buffer.get()->getBuffer();
+ probe_data.buf = reinterpret_cast<data_t*>(buffer.get()->getBuffer());
probe_data.buf_size = buffer.get()->getSize();
AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
@@ -243,6 +247,40 @@ AUD_FFMPEGReader::~AUD_FFMPEGReader()
av_close_input_file(m_formatCtx);
}
+int AUD_FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
+{
+ AUD_FFMPEGReader* reader = reinterpret_cast<AUD_FFMPEGReader*>(opaque);
+
+ int size = AUD_MIN(buf_size, reader->m_membuffer.get()->getSize() - reader->m_membufferpos);
+
+ if(size < 0)
+ return -1;
+
+ memcpy(buf, ((data_t*)reader->m_membuffer.get()->getBuffer()) + reader->m_membufferpos, size);
+ reader->m_membufferpos += size;
+
+ return size;
+}
+
+int64_t AUD_FFMPEGReader::seek_packet(void* opaque, int64_t offset, int whence)
+{
+ AUD_FFMPEGReader* reader = reinterpret_cast<AUD_FFMPEGReader*>(opaque);
+
+ switch(whence)
+ {
+ case SEEK_SET:
+ reader->m_membufferpos = 0;
+ break;
+ case SEEK_END:
+ reader->m_membufferpos = reader->m_membuffer.get()->getSize();
+ break;
+ case AVSEEK_SIZE:
+ return reader->m_membuffer.get()->getSize();
+ }
+
+ return (reader->m_membufferpos += offset);
+}
+
bool AUD_FFMPEGReader::isSeekable() const
{
return true;
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
index 4d8c5e4c462..26e66859451 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
@@ -106,11 +106,21 @@ private:
AUD_convert_f m_convert;
/**
- * The memory file to read from, only saved to keep the buffer alive.
+ * The memory file to read from.
*/
AUD_Reference<AUD_Buffer> m_membuffer;
/**
+ * The buffer to read with.
+ */
+ data_t* m_membuf;
+
+ /**
+ * Reading position of the buffer.
+ */
+ int64_t m_membufferpos;
+
+ /**
* Decodes a packet into the given buffer.
* \param packet The AVPacket to decode.
* \param buffer The target buffer.
@@ -149,6 +159,9 @@ public:
*/
virtual ~AUD_FFMPEGReader();
+ static int read_packet(void* opaque, uint8_t* buf, int buf_size);
+ static int64_t seek_packet(void* opaque, int64_t offset, int whence);
+
virtual bool isSeekable() const;
virtual void seek(int position);
virtual int getLength() const;