2.5: Sound branch merge!
[blender.git] / intern / audaspace / ffmpeg / AUD_FFMPEGReader.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN LGPL LICENSE BLOCK *****
5  *
6  * Copyright 2009 Jörg Hermann Müller
7  *
8  * This file is part of AudaSpace.
9  *
10  * AudaSpace is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * AudaSpace is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  * ***** END LGPL LICENSE BLOCK *****
24  */
25
26 // needed for INT64_C
27 #define __STDC_CONSTANT_MACROS
28
29 #include "AUD_FFMPEGReader.h"
30 #include "AUD_Buffer.h"
31
32 extern "C" {
33 #include <libavcodec/avcodec.h>
34 #include <libavformat/avformat.h>
35 }
36
37 // This function transforms a FFMPEG SampleFormat to or own sample format
38 static inline AUD_SampleFormat FFMPEG_TO_AUD(SampleFormat fmt)
39 {
40         switch(fmt)
41         {
42         case SAMPLE_FMT_U8:
43                 return AUD_FORMAT_U8;
44         case SAMPLE_FMT_S16:
45                 return AUD_FORMAT_S16;
46         case SAMPLE_FMT_S32:
47                 return AUD_FORMAT_S32;
48         case SAMPLE_FMT_FLT:
49                 return AUD_FORMAT_FLOAT32;
50         case SAMPLE_FMT_DBL:
51                 return AUD_FORMAT_FLOAT64;
52         default:
53                 return AUD_FORMAT_INVALID;
54         }
55 }
56
57 int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
58 {
59         // save packet parameters
60         uint8_t *audio_pkg_data = packet->data;
61         int audio_pkg_size = packet->size;
62
63         int buf_size = buffer->getSize();
64         int buf_pos = 0;
65
66         int read_length, data_size;
67
68         // as long as there is still data in the package
69         while(audio_pkg_size > 0)
70         {
71                 // resize buffer if needed
72                 if(buf_size - buf_pos < AVCODEC_MAX_AUDIO_FRAME_SIZE)
73                 {
74                         buffer->resize(buf_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, true);
75                         buf_size += AVCODEC_MAX_AUDIO_FRAME_SIZE;
76                 }
77
78                 // read samples from the packet
79                 data_size = buf_size - buf_pos;
80                 /*read_length = avcodec_decode_audio3(m_codecCtx,
81                         (int16_t*)(buffer->getBuffer()+buf_pos),
82                         &data_size,
83                         packet);*/
84                 read_length = avcodec_decode_audio2(m_codecCtx,
85                         (int16_t*)(buffer->getBuffer()+buf_pos),
86                         &data_size,
87                         audio_pkg_data,
88                         audio_pkg_size);
89
90                 buf_pos += data_size;
91
92                 // read error, next packet!
93                 if(read_length < 0)
94                         break;
95
96                 // move packet parameters
97                 audio_pkg_data += read_length;
98                 audio_pkg_size -= read_length;
99         }
100
101         return buf_pos;
102 }
103
104 AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
105 {
106         m_position = 0;
107         m_pkgbuf_left = 0;
108         m_byteiocontext = NULL;
109
110         // open file
111         if(av_open_input_file(&m_formatCtx, filename, NULL, 0, NULL)!=0)
112                 AUD_THROW(AUD_ERROR_FILE);
113
114         try
115         {
116                 if(av_find_stream_info(m_formatCtx)<0)
117                         AUD_THROW(AUD_ERROR_FFMPEG);
118
119                 // find audio stream and codec
120                 m_stream = -1;
121
122                 for(int i = 0; i < m_formatCtx->nb_streams; i++)
123                         if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
124                                 && (m_stream < 0))
125                         {
126                                 m_stream=i;
127                                 break;
128                         }
129                 if(m_stream == -1)
130                         AUD_THROW(AUD_ERROR_FFMPEG);
131
132                 m_codecCtx = m_formatCtx->streams[m_stream]->codec;
133
134                 // get a decoder and open it
135                 AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
136                 if(!aCodec)
137                         AUD_THROW(AUD_ERROR_FFMPEG);
138
139                 if(avcodec_open(m_codecCtx, aCodec)<0)
140                         AUD_THROW(AUD_ERROR_FFMPEG);
141
142                 // XXX this prints file information to stdout:
143                 //dump_format(m_formatCtx, 0, filename, 0);
144
145                 m_specs.channels = (AUD_Channels) m_codecCtx->channels;
146                 m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
147                 m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
148         }
149         catch(AUD_Exception e)
150         {
151                 av_close_input_file(m_formatCtx);
152                 throw;
153         }
154
155         // last but not least if there hasn't been any error, create the buffers
156         m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
157         m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
158         AUD_NEW("buffer")
159 }
160
161 AUD_FFMPEGReader::AUD_FFMPEGReader(unsigned char* buffer, int size)
162 {
163         m_position = 0;
164         m_pkgbuf_left = 0;
165         m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
166         AUD_NEW("byteiocontext")
167
168         if(init_put_byte(m_byteiocontext, buffer, size, 0,
169                                          NULL, NULL, NULL, NULL) != 0)
170                 AUD_THROW(AUD_ERROR_FILE);
171
172         AVProbeData probe_data;
173         probe_data.filename = "";
174         probe_data.buf = buffer;
175         probe_data.buf_size = size;
176         AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
177
178         // open stream
179         if(av_open_input_stream(&m_formatCtx, m_byteiocontext, "", fmt, NULL)!=0)
180                 AUD_THROW(AUD_ERROR_FILE);
181
182         try
183         {
184                 if(av_find_stream_info(m_formatCtx)<0)
185                         AUD_THROW(AUD_ERROR_FFMPEG);
186
187                 // find audio stream and codec
188                 m_stream = -1;
189
190                 for(int i = 0; i < m_formatCtx->nb_streams; i++)
191                         if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
192                                 && (m_stream < 0))
193                         {
194                                 m_stream=i;
195                                 break;
196                         }
197                 if(m_stream == -1)
198                         AUD_THROW(AUD_ERROR_FFMPEG);
199
200                 m_codecCtx = m_formatCtx->streams[m_stream]->codec;
201
202                 // get a decoder and open it
203                 AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
204                 if(!aCodec)
205                         AUD_THROW(AUD_ERROR_FFMPEG);
206
207                 if(avcodec_open(m_codecCtx, aCodec)<0)
208                         AUD_THROW(AUD_ERROR_FFMPEG);
209
210                 // XXX this prints stream information to stdout:
211                 //dump_format(m_formatCtx, 0, NULL, 0);
212
213                 m_specs.channels = (AUD_Channels) m_codecCtx->channels;
214                 m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
215                 m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
216         }
217         catch(AUD_Exception e)
218         {
219                 av_close_input_stream(m_formatCtx);
220                 av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
221                 throw;
222         }
223
224         // last but not least if there hasn't been any error, create the buffers
225         m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
226         m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
227         AUD_NEW("buffer")
228 }
229
230 AUD_FFMPEGReader::~AUD_FFMPEGReader()
231 {
232         avcodec_close(m_codecCtx);
233
234         if(m_byteiocontext)
235         {
236                 av_close_input_stream(m_formatCtx);
237                 av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
238         }
239         else
240                 av_close_input_file(m_formatCtx);
241
242         delete m_buffer; AUD_DELETE("buffer")
243         delete m_pkgbuf; AUD_DELETE("buffer")
244 }
245
246 bool AUD_FFMPEGReader::isSeekable()
247 {
248         return true;
249 }
250
251 void AUD_FFMPEGReader::seek(int position)
252 {
253         if(position >= 0)
254         {
255                 // a value < 0 tells us that seeking failed
256                 if(av_seek_frame(m_formatCtx,
257                                                  -1,
258                                                  (uint64_t)(((uint64_t)position *
259                                                                          (uint64_t)AV_TIME_BASE) /
260                                                                         (uint64_t)m_specs.rate),
261                                                  AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY) >= 0)
262                 {
263                         avcodec_flush_buffers(m_codecCtx);
264                         m_position = position;
265
266                         AVPacket packet;
267                         bool search = true;
268
269                         while(search && av_read_frame(m_formatCtx, &packet) >= 0)
270                         {
271                                 // is it a frame from the audio stream?
272                                 if(packet.stream_index == m_stream)
273                                 {
274                                         // decode the package
275                                         m_pkgbuf_left = decode(&packet, m_pkgbuf);
276                                         search = false;
277
278                                         // check position
279                                         if(packet.pts != AV_NOPTS_VALUE)
280                                         {
281                                                 // calculate real position, and read to frame!
282                                                 m_position = packet.pts *
283                                                         av_q2d(m_formatCtx->streams[m_stream]->time_base) *
284                                                         m_specs.rate;
285
286                                                 if(m_position < position)
287                                                 {
288                                                         sample_t* buf;
289                                                         int length = position - m_position;
290                                                         read(length, buf);
291                                                 }
292                                         }
293                                 }
294                                 av_free_packet(&packet);
295                         }
296                 }
297                 else
298                 {
299                         // Seeking failed, do nothing.
300                 }
301         }
302 }
303
304 int AUD_FFMPEGReader::getLength()
305 {
306         // return approximated remaning size
307         return (int)((m_formatCtx->duration * m_codecCtx->sample_rate)
308                                  / AV_TIME_BASE)-m_position;
309 }
310
311 int AUD_FFMPEGReader::getPosition()
312 {
313         return m_position;
314 }
315
316 AUD_Specs AUD_FFMPEGReader::getSpecs()
317 {
318         return m_specs;
319 }
320
321 AUD_ReaderType AUD_FFMPEGReader::getType()
322 {
323         return AUD_TYPE_STREAM;
324 }
325
326 bool AUD_FFMPEGReader::notify(AUD_Message &message)
327 {
328         return false;
329 }
330
331 void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
332 {
333         // read packages and decode them
334         AVPacket packet;
335         int data_size = 0;
336         int pkgbuf_size = m_pkgbuf->getSize();
337         int pkgbuf_pos;
338         int left = length;
339         int sample_size = AUD_SAMPLE_SIZE(m_specs);
340
341         // resize output buffer if necessary
342         if(m_buffer->getSize() < length*sample_size)
343                 m_buffer->resize(length*sample_size);
344
345         buffer = m_buffer->getBuffer();
346         pkgbuf_pos = m_pkgbuf_left;
347         m_pkgbuf_left = 0;
348
349         // there may still be data in the buffer from the last call
350         if(pkgbuf_pos > 0)
351         {
352                 data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
353                 memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
354                 buffer += data_size;
355                 left -= data_size/sample_size;
356         }
357
358         // for each frame read as long as there isn't enough data already
359         while((left > 0) && (av_read_frame(m_formatCtx, &packet) >= 0))
360         {
361                 // is it a frame from the audio stream?
362                 if(packet.stream_index == m_stream)
363                 {
364                         // decode the package
365                         pkgbuf_pos = decode(&packet, m_pkgbuf);
366
367                         // copy to output buffer
368                         data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
369                         memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
370                         buffer += data_size;
371                         left -= data_size/sample_size;
372                 }
373                 av_free_packet(&packet);
374         }
375         // read more data than necessary?
376         if(pkgbuf_pos > data_size)
377         {
378                 m_pkgbuf_left = pkgbuf_pos-data_size;
379                 memmove(m_pkgbuf->getBuffer(), m_pkgbuf->getBuffer()+data_size,
380                                 pkgbuf_pos-data_size);
381         }
382
383         buffer = m_buffer->getBuffer();
384
385         if(left > 0)
386                 length -= left;
387         m_position += length;
388 }