Revision: 22010
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22010
Author:   nexyon
Date:     2009-07-29 13:56:49 +0200 (Wed, 29 Jul 2009)

Log Message:
-----------
More accurate seeking with ffmpeg.

Modified Paths:
--------------
    branches/soundsystem/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
    branches/soundsystem/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h

Modified: branches/soundsystem/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
===================================================================
--- branches/soundsystem/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp   
2009-07-29 11:53:37 UTC (rev 22009)
+++ branches/soundsystem/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp   
2009-07-29 11:56:49 UTC (rev 22010)
@@ -23,6 +23,9 @@
  * ***** END LGPL LICENSE BLOCK *****
  */
 
+// needed for INT64_C
+#define __STDC_CONSTANT_MACROS
+
 #include "AUD_FFMPEGReader.h"
 #include "AUD_Buffer.h"
 
@@ -51,6 +54,53 @@
        }
 }
 
+int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
+{
+       // save packet parameters
+       uint8_t *audio_pkg_data = packet->data;
+       int audio_pkg_size = packet->size;
+
+       int buf_size = buffer->getSize();
+       int buf_pos = 0;
+
+       int read_length, data_size;
+
+       // as long as there is still data in the package
+       while(audio_pkg_size > 0)
+       {
+               // resize buffer if needed
+               if(buf_size - buf_pos < AVCODEC_MAX_AUDIO_FRAME_SIZE)
+               {
+                       buffer->resize(buf_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, 
true);
+                       buf_size += AVCODEC_MAX_AUDIO_FRAME_SIZE;
+               }
+
+               // read samples from the packet
+               data_size = buf_size - buf_pos;
+               /*read_length = avcodec_decode_audio3(m_codecCtx,
+                       (int16_t*)(buffer->getBuffer()+buf_pos),
+                       &data_size,
+                       packet);*/
+               read_length = avcodec_decode_audio2(m_codecCtx,
+                       (int16_t*)(buffer->getBuffer()+buf_pos),
+                       &data_size,
+                       audio_pkg_data,
+                       audio_pkg_size);
+
+               buf_pos += data_size;
+
+               // read error, next packet!
+               if(read_length < 0)
+                       break;
+
+               // move packet parameters
+               audio_pkg_data += read_length;
+               audio_pkg_size -= read_length;
+       }
+
+       return buf_pos;
+}
+
 AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
 {
        m_position = 0;
@@ -212,11 +262,41 @@
                {
                        avcodec_flush_buffers(m_codecCtx);
                        m_position = position;
-                       m_pkgbuf_left = 0;
+
+                       AVPacket packet;
+                       bool search = true;
+
+                       while(search && av_read_frame(m_formatCtx, &packet) >= 
0)
+                       {
+                               // is it a frame from the audio stream?
+                               if(packet.stream_index == m_stream)
+                               {
+                                       // decode the package
+                                       m_pkgbuf_left = decode(&packet, 
m_pkgbuf);
+                                       search = false;
+
+                                       // check position
+                                       if(packet.pts != AV_NOPTS_VALUE)
+                                       {
+                                               // calculate real position, and 
read to frame!
+                                               m_position = packet.pts *
+                                                       
av_q2d(m_formatCtx->streams[m_stream]->time_base) *
+                                                       m_specs.rate;
+
+                                               if(m_position < position)
+                                               {
+                                                       sample_t* buf;
+                                                       int length = position - 
m_position;
+                                                       read(length, buf);
+                                               }
+                                       }
+                               }
+                               av_free_packet(&packet);
+                       }
                }
                else
                {
-                       // XXX printf("Seeking failed!\n");
+                       // Seeking failed, do nothing.
                }
        }
 }
@@ -252,9 +332,6 @@
 {
        // read packages and decode them
        AVPacket packet;
-       int audio_pkg_size;
-       uint8_t *audio_pkg_data;
-       int read_length;
        int data_size = 0;
        int pkgbuf_size = m_pkgbuf->getSize();
        int pkgbuf_pos;
@@ -272,7 +349,7 @@
        // there may still be data in the buffer from the last call
        if(pkgbuf_pos > 0)
        {
-               data_size = AUD_MIN(pkgbuf_pos, left*sample_size);
+               data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
                memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
                buffer += data_size;
                left -= data_size/sample_size;
@@ -284,47 +361,11 @@
                // is it a frame from the audio stream?
                if(packet.stream_index == m_stream)
                {
-                       // save packet parameters
-                       audio_pkg_data = packet.data;
-                       audio_pkg_size = packet.size;
-                       pkgbuf_pos = 0;
+                       // decode the package
+                       pkgbuf_pos = decode(&packet, m_pkgbuf);
 
-                       // as long as there is still data in the package
-                       while(audio_pkg_size > 0)
-                       {
-                               // resize buffer if needed
-                               if(pkgbuf_size-pkgbuf_pos < 
AVCODEC_MAX_AUDIO_FRAME_SIZE)
-                               {
-                                       // XXX printf("resizing\n");
-                                       m_pkgbuf->resize(pkgbuf_size +
-                                                                        
AVCODEC_MAX_AUDIO_FRAME_SIZE, true);
-                                       pkgbuf_size += 
AVCODEC_MAX_AUDIO_FRAME_SIZE;
-                               }
-
-                               // read samples from the packet
-                               data_size = pkgbuf_size-pkgbuf_pos;
-                               /*read_length = 
avcodec_decode_audio3(m_codecCtx,
-                                       
(int16_t*)(m_pkgbuf->getBuffer()+pkgbuf_pos),
-                                       &data_size,
-                                       &packet);*/
-                               read_length = avcodec_decode_audio2(m_codecCtx,
-                                       
(int16_t*)(m_pkgbuf->getBuffer()+pkgbuf_pos),
-                                       &data_size,
-                                       audio_pkg_data,
-                                       audio_pkg_size);
-
-                               pkgbuf_pos += data_size;
-
-                               // read error, next packet!
-                               if(read_length < 0)
-                                       break;
-
-                               // move packet parameters
-                               audio_pkg_data += read_length;
-                               audio_pkg_size -= read_length;
-                       }
                        // copy to output buffer
-                       data_size = AUD_MIN(pkgbuf_pos, left*sample_size);
+                       data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
                        memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
                        buffer += data_size;
                        left -= data_size/sample_size;

Modified: branches/soundsystem/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
===================================================================
--- branches/soundsystem/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h     
2009-07-29 11:53:37 UTC (rev 22009)
+++ branches/soundsystem/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h     
2009-07-29 11:56:49 UTC (rev 22010)
@@ -89,6 +89,14 @@
         */
        int m_stream;
 
+       /**
+        * Decodes a packet into the given buffer.
+        * \param packet The AVPacket to decode.
+        * \param buffer The target buffer.
+        * \return The count of read bytes.
+        */
+       int decode(AVPacket* packet, AUD_Buffer* buffer);
+
 public:
        /**
         * Creates a new reader.


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to