[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36213] trunk/blender: Fix for [#26990] Loading file w packed audio crashes

Joerg Mueller nexyon at gmail.com
Mon Apr 18 16:24:36 CEST 2011


Revision: 36213
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36213
Author:   nexyon
Date:     2011-04-18 14:24:36 +0000 (Mon, 18 Apr 2011)
Log Message:
-----------
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

Modified Paths:
--------------
    trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
    trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
    trunk/blender/source/blender/editors/sound/sound_ops.c

Modified: trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
===================================================================
--- trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp	2011-04-18 11:22:01 UTC (rev 36212)
+++ trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp	2011-04-18 14:24:36 UTC (rev 36213)
@@ -172,7 +172,8 @@
 
 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 @@
 
 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 @@
 
 	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 @@
 		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;

Modified: trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
===================================================================
--- trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h	2011-04-18 11:22:01 UTC (rev 36212)
+++ trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h	2011-04-18 14:24:36 UTC (rev 36213)
@@ -106,11 +106,21 @@
 	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 @@
 	 */
 	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;

Modified: trunk/blender/source/blender/editors/sound/sound_ops.c
===================================================================
--- trunk/blender/source/blender/editors/sound/sound_ops.c	2011-04-18 11:22:01 UTC (rev 36212)
+++ trunk/blender/source/blender/editors/sound/sound_ops.c	2011-04-18 14:24:36 UTC (rev 36213)
@@ -254,7 +254,7 @@
 	if(G.fileflags & G_AUTOPACK)
 		BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save.");
 
-	unpack_menu(C, "SOUND_OT_unpack", sound->id.name+2, sound->name, "audio", sound->packedfile);
+	unpack_menu(C, "SOUND_OT_unpack", sound->id.name+2, sound->name, "sounds", sound->packedfile);
 
 	return OPERATOR_FINISHED;
 }




More information about the Bf-blender-cvs mailing list