ref: 5107a46aad77cdb9687f3b876794770a5185b638
parent: 92f05bd3e35cf3a0f94ae4e067500621586fcd06
author: menno <menno>
date: Fri Aug 8 05:24:08 EDT 2003
Case's modifications
--- 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.43 2003/08/07 19:06:11 menno Exp $
+** $Id: foo_mp4.cpp,v 1.44 2003/08/08 09:24:08 menno Exp $
**/
#include <mp4.h>
@@ -128,25 +128,27 @@
unsigned __int64 length = MP4GetTrackDuration(hFile, track);
__int64 msDuration = MP4ConvertFromTrackDuration(hFile, track,
length, MP4_MSECS_TIME_SCALE);
-
- ReadMP4Tag(info);
-
- if (m_samples > 0) {
- info->set_length((double)m_samples/(double)samplerate);
- } else {
- info->set_length((double)msDuration/1000.0);
- }
-
+ info->set_length((double)msDuration/1000.0);
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);
info->info_set_int("channels", (__int64)channels);
info->info_set_int("samplerate", (__int64)samplerate);
- if (mp4ASC.sbr_present_flag == 1)
+ if (mp4ASC.sbr_present_flag == 1) {
info->info_set("codec", "AAC+SBR");
- else
+ m_framesize = 2048;
+ } else {
info->info_set("codec", "AAC");
+ m_framesize = 1024;
+ }
+ ReadMP4Tag(info);
+
+ if (m_samples > 0) {
+ info->set_length((double)m_samples/(double)samplerate);
+ info->info_set_int("samples", (__int64)m_samples);
+ }
+
m_samplerate = samplerate;
return 1;
@@ -158,7 +160,7 @@
hDecoder = NULL;
m_samples = 0;
m_samplepos = 0;
- m_samplerate = 0;
+ m_seekskip = 0;
}
~input_mp4()
@@ -171,79 +173,86 @@
virtual int run(audio_chunk * chunk)
{
- faacDecFrameInfo frameInfo;
- unsigned char *buffer;
- unsigned __int32 buffer_size;
- audio_sample *sample_buffer;
+ do {
+ faacDecFrameInfo frameInfo;
+ unsigned char *buffer;
+ unsigned __int32 buffer_size;
+ audio_sample *sample_buffer;
- if (m_samples > 0 && m_samplepos >= m_samples) return 0; // gapless playback
+ if (m_samples > 0 && m_samplepos >= m_samples) return 0; // gapless playback
- if (sampleId == MP4_INVALID_SAMPLE_ID)
- {
- console::error("Invalid sampleId.");
- return 0;
- }
+ if (sampleId == MP4_INVALID_SAMPLE_ID)
+ {
+ console::error("Invalid sampleId.");
+ return 0;
+ }
- do {
- buffer = NULL;
- buffer_size = 0;
+ do {
+ buffer = NULL;
+ buffer_size = 0;
- MP4ReadSample(hFile, track, sampleId,
- (unsigned __int8**)&buffer, &buffer_size,
- NULL, NULL, NULL, NULL);
- sampleId++;
+ MP4ReadSample(hFile, track, sampleId,
+ (unsigned __int8**)&buffer, &buffer_size,
+ NULL, NULL, NULL, NULL);
+ sampleId++;
- sample_buffer = (audio_sample*)faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size);
+ sample_buffer = (audio_sample*)faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size);
- if (buffer) free(buffer);
+ if (buffer) free(buffer);
- } while ((frameInfo.error == 0) && (frameInfo.samples == 0));
+ } while ((frameInfo.error == 0) && (frameInfo.samples == 0));
- if (frameInfo.error)
- {
- console::warning(faacDecGetErrorMessage(frameInfo.error));
- console::warning("Skipping frame");
- }
- if (sampleId > numSamples)
- return 0;
+ if (frameInfo.error)
+ {
+ console::warning(faacDecGetErrorMessage(frameInfo.error));
+ console::warning("Skipping frame");
+ }
+ if (sampleId > numSamples)
+ return 0;
- if (frameInfo.channels == 6 && frameInfo.num_lfe_channels)
- {
- //channel order for 5.1: L/R/C/LF/BL/BR
- audio_sample r1, r2, r3, r4, r5, r6;
- for (int i = 0; i < frameInfo.samples; i += frameInfo.channels)
+ if (frameInfo.channels == 6 && frameInfo.num_lfe_channels)
{
- r1 = sample_buffer[i];
- r2 = sample_buffer[i+1];
- r3 = sample_buffer[i+2];
- r4 = sample_buffer[i+3];
- r5 = sample_buffer[i+4];
- r6 = sample_buffer[i+5];
- sample_buffer[i] = r2;
- sample_buffer[i+1] = r3;
- sample_buffer[i+2] = r1;
- sample_buffer[i+3] = r6;
- sample_buffer[i+4] = r4;
- sample_buffer[i+5] = r5;
+ //channel order for 5.1: L/R/C/LF/BL/BR
+ audio_sample r1, r2, r3, r4, r5, r6;
+ for (unsigned int i = 0; i < frameInfo.samples; i += frameInfo.channels)
+ {
+ r1 = sample_buffer[i];
+ r2 = sample_buffer[i+1];
+ r3 = sample_buffer[i+2];
+ r4 = sample_buffer[i+3];
+ r5 = sample_buffer[i+4];
+ r6 = sample_buffer[i+5];
+ sample_buffer[i] = r2;
+ sample_buffer[i+1] = r3;
+ sample_buffer[i+2] = r1;
+ sample_buffer[i+3] = r6;
+ sample_buffer[i+4] = r4;
+ sample_buffer[i+5] = r5;
+ }
}
- }
- if (frameInfo.channels == 0)
- {
- chunk->set_data(sample_buffer, 0, frameInfo.channels, frameInfo.samplerate);
- } else {
- if (m_samples > 0) { // gapless playback
+ if (frameInfo.channels == 0)
+ {
+ chunk->set_data(sample_buffer, 0, frameInfo.channels, frameInfo.samplerate);
+ } else {
unsigned int samples = frameInfo.samples/frameInfo.channels;
- if (m_samplepos + samples > m_samples) {
- samples = m_samples - m_samplepos;
+
+ if (m_samples > 0) { // gapless playback
+ if (m_samplepos + samples > m_samples) samples = m_samples - m_samplepos;
}
- chunk->set_data(sample_buffer, samples, frameInfo.channels, frameInfo.samplerate);
+
+ if (m_seekskip < samples) {
+ samples -= m_seekskip;
+ chunk->set_data((audio_sample*)sample_buffer + m_seekskip*frameInfo.channels,
+ samples, frameInfo.channels, frameInfo.samplerate);
+ m_seekskip = 0;
+ } else {
+ m_seekskip -= samples;
+ }
+
m_samplepos += samples;
- } else {
- chunk->set_data(sample_buffer, frameInfo.samples/frameInfo.channels,
- frameInfo.channels, frameInfo.samplerate);
}
- }
+ } while (m_seekskip > 0);
return 1;
}
@@ -274,14 +283,18 @@
if (p)
MP4SetMetadataFreeForm(hFile, "REPLAYGAIN_ALBUM_GAIN", (unsigned __int8*)p, strlen(p));
+ m_samples = 0;
+ p = info->info_get("samples");
+ if (p) m_samples = (unsigned int)_atoi64(p);
+
if (m_samples > 0)
{
unsigned __int8 length[4];
- length[0] = (unsigned __int8)(((unsigned int)m_samples >> 24) & 0xFF);
- length[1] = (unsigned __int8)(((unsigned int)m_samples >> 16) & 0xFF);
- length[2] = (unsigned __int8)(((unsigned int)m_samples >> 8) & 0xFF);
- length[3] = (unsigned __int8)(((unsigned int)m_samples ) & 0xFF);
+ length[0] = (unsigned __int8)((unsigned int)(m_samples >> 24) & 0xFF);
+ length[1] = (unsigned __int8)((unsigned int)(m_samples >> 16) & 0xFF);
+ length[2] = (unsigned __int8)((unsigned int)(m_samples >> 8) & 0xFF);
+ length[3] = (unsigned __int8)((unsigned int)(m_samples ) & 0xFF);
MP4SetMetadataFreeForm(hFile, "NDFL", length, 4);
}
@@ -342,12 +355,14 @@
{
MP4Duration duration;
+ double secs = (seconds >= 1) ? seconds-1 : seconds;
duration = MP4ConvertToTrackDuration(hFile,
- track, seconds, MP4_SECS_TIME_SCALE);
+ track, secs, MP4_SECS_TIME_SCALE);
sampleId = MP4GetSampleIdFromTime(hFile,
track, duration, 0);
- m_samplepos = (unsigned int)(seconds * m_samplerate + 0.5);
+ m_samplepos = (unsigned int)sampleId * m_framesize;
+ m_seekskip = (unsigned int)(seconds * m_samplerate + 0.5) - m_samplepos;
return true;
}
@@ -368,7 +383,9 @@
MP4TrackId track;
unsigned int m_samples;
unsigned int m_samplerate;
+ unsigned int m_framesize;
unsigned int m_samplepos;
+ unsigned int m_seekskip;
int ReadMP4Tag(file_info *info)
{
@@ -778,7 +795,7 @@
{
//channel order for 5.1: L/R/C/LF/BL/BR
audio_sample r1, r2, r3, r4, r5, r6;
- for (int i = 0; i < frameInfo.samples; i += frameInfo.channels)
+ for (unsigned int i = 0; i < frameInfo.samples; i += frameInfo.channels)
{
r1 = sample_buffer[i];
r2 = sample_buffer[i+1];