ref: 04891cb0c2928283d518c488222bf070277880bb
parent: fe8186b4736ec1d57828d5b1ad5e777b832322fb
author: menno <menno>
date: Thu Aug 14 14:40:08 EDT 2003
fixed decoding length for foobar plugin
--- a/plugins/foo_mp4/foo_mp4.cpp
+++ b/plugins/foo_mp4/foo_mp4.cpp
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: foo_mp4.cpp,v 1.46 2003/08/09 11:28:43 menno Exp $
+** $Id: foo_mp4.cpp,v 1.47 2003/08/14 18:40:08 menno Exp $
**/
#include <mp4.h>
@@ -46,7 +46,7 @@
#endif
DECLARE_COMPONENT_VERSION ("MPEG-4 AAC decoder",
- "1.38",
+ "1.46",
"Based on FAAD2 v" FAAD2_VERSION "\nCopyright (C) 2002-2003 http://www.audiocoding.com" );
class input_mp4 : public input
@@ -96,7 +96,7 @@
}
track = GetAACTrack(hFile);
- if (track < 1)
+ if (track < 0)
{
console::error("No valid AAC track found.");
return 0;
@@ -129,10 +129,14 @@
m_framesize = 1024;
if (mp4ASC.frameLengthFlag == 1) m_framesize = 960;
- unsigned __int64 length = MP4GetTrackDuration(hFile, track);
- __int64 msDuration = MP4ConvertFromTrackDuration(hFile, track,
- length, MP4_MSECS_TIME_SCALE);
- m_length = (double)msDuration/1000.0;
+ double secs = 0;
+ if (mp4ASC.sbr_present_flag == 1)
+ {
+ secs = (double)(MP4GetTrackNumberOfSamples(hFile, track)-1)*2048.0/(double)mp4ASC.samplingFrequency;
+ } else {
+ secs = (double)(MP4GetTrackNumberOfSamples(hFile, track)-1)*1024.0/(double)mp4ASC.samplingFrequency;
+ }
+ m_length = secs;
info->info_set_int("bitrate",(__int64)(1.0/1000.0 *
(double)(__int64)MP4GetTrackIntegerProperty(hFile,
track, "mdia.minf.stbl.stsd.mp4a.esds.decConfigDescr.avgBitrate")) + 0.5);
@@ -184,10 +188,12 @@
unsigned __int32 buffer_size;
audio_sample *sample_buffer;
+ if (sampleId > numSamples) return 0;
+
if (sampleId == MP4_INVALID_SAMPLE_ID)
{
console::error("Invalid sampleId.");
- return 0;
+ return -1;
}
do {
@@ -209,9 +215,8 @@
{
console::warning(faacDecGetErrorMessage(frameInfo.error));
console::warning("Skipping frame");
+ if (sampleId > numSamples) return -1;
}
- if (sampleId > numSamples)
- return 0;
if (frameInfo.channels == 6 && frameInfo.num_lfe_channels)
{
@@ -654,6 +659,7 @@
faacDecSetConfiguration(hDecoder, config);
tag_reader::g_run_multi(m_reader, info, "ape|id3v2|lyrics3|id3v1");
+
const char *p = info->meta_get("samples");
if (p) {
m_samples = (unsigned __int64)_atoi64(p);
@@ -752,8 +758,15 @@
m_framesize = 1024;
if (flags & OPEN_FLAG_GET_INFO) {
- run(0); // get correct framesize and samplerate
+ // decode first frame to get accurate info
+ faacDecFrameInfo frameInfo;
+ memset(&frameInfo, 0, sizeof(faacDecFrameInfo));
+ fill_buffer();
+ faacDecDecode(hDecoder, &frameInfo, m_aac_buffer, m_aac_bytes_into_buffer);
+ m_samplerate = frameInfo.samplerate;
+ m_framesize = (frameInfo.channels != 0) ? frameInfo.samples/frameInfo.channels : 0;
+
if (m_samples > 0) {
length = (double)(signed __int64)m_samples/(double)samplerate;
}
@@ -768,11 +781,25 @@
info->info_set("stream type", "ADTS");
else if (m_header_type == 2)
info->info_set("stream type", "ADIF");
- info->set_length(length);
info->info_set_int("bitrate", bitrate);
info->info_set_int("channels", (__int64)channels);
info->info_set_int("samplerate", (__int64)m_samplerate);
+
+ if (m_samples > 0) {
+ length = (double)(signed __int64)m_samples/(double)samplerate;
+ }
+
+ info->set_length(length);
+
+ if (flags & OPEN_FLAG_DECODE) {
+ if (hDecoder)
+ faacDecClose(hDecoder);
+ if (m_aac_buffer)
+ free(m_aac_buffer);
+ r->seek(0);
+ return open(r, info, flags & (~OPEN_FLAG_GET_INFO));
+ }
}
m_length = length;
@@ -816,8 +843,10 @@
do {
if (m_eof || (m_samples > 0 && m_samplepos >= m_samples)) return 0; // gapless playback
+ if (m_aac_bytes_into_buffer == 0) return 0;
+
faacDecFrameInfo frameInfo;
- audio_sample *sample_buffer;
+ audio_sample *sample_buffer = 0;
memset(&frameInfo, 0, sizeof(faacDecFrameInfo));
@@ -845,14 +874,11 @@
} while (!frameInfo.samples && !frameInfo.error);
- if (frameInfo.error || (m_aac_bytes_into_buffer == 0))
+ if (frameInfo.error || !sample_buffer)
{
- if (frameInfo.error)
- {
- const char *msg = faacDecGetErrorMessage(frameInfo.error);
- if (msg) console::warning(msg);
- }
- return 0;
+ const char *msg = faacDecGetErrorMessage(frameInfo.error);
+ if (msg) console::warning(msg);
+ return -1;
}
if (frameInfo.channels == 6 && frameInfo.num_lfe_channels)