ref: 33656858ad9f69ed9ea1e7fe565f1ce28987205c
parent: 2ac355532dc6bd13696bb8b06be924ed1a097d23
author: menno <menno>
date: Mon Apr 28 15:07:57 EDT 2003
new QCD MP4 plugin
--- /dev/null
+++ b/plugins/QCDMp4/AAC2Mp4Enc.c
@@ -1,0 +1,270 @@
+//-----------------------------------------------------------------------------
+//
+// File: QCDEncodeDLL.cpp
+//
+// About: See QCDOutputDLL.h
+//
+// Authors: Written by Paul Quinn
+//
+// QCD multimedia player application Software Development Kit Release 1.0.
+//
+// Copyright (C) 1997-2002 Quinnware
+//
+// This code is free. If you redistribute it in any form, leave this notice
+// here.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//-----------------------------------------------------------------------------
+
+#include <windows.h>
+#include <shlobj.h>
+#include <mp4.h>
+
+#include "QCDInputDLL.h"
+#include "QCDConvertDLL.h"
+#include "resource.h"
+#include "utils.h"
+#include "config.h"
+#include "aac2mp4.h"
+
+HWND hwndConfigEnc;
+QCDModInitEnc *QCDCallbacks_Enc;
+
+BOOL CALLBACK config_convert_proc(HWND hwndDlg, UINT message,
+ WPARAM wParam, LPARAM lParam);
+
+static char m_output_folder[MAX_PATH];// our output folder
+
+void config_enc_read()
+{
+ char output_folder[MAX_PATH];
+ output_folder[0] = 0;
+
+ RS(output_folder);
+
+ lstrcpy(m_output_folder, output_folder);
+}
+
+void config_enc_write()
+{
+ char output_folder[MAX_PATH];
+ lstrcpy(output_folder, m_output_folder);
+
+ WS(output_folder);
+}
+
+BOOL isFolder(char *folder)
+{
+ if(lstrlen(folder) > 0 && folder[1] == ':')
+ return TRUE;
+ else
+ return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+
+PLUGIN_API BOOL ENCODEDLL_ENTRY_POINT(QCDModInitEnc *ModInit, QCDModInfo *ModInfo)
+{
+ ModInit->version = PLUGIN_API_VERSION;
+ ModInfo->moduleString = "AAC to Mp4 Converter v1.0";
+
+ ModInit->toModule.ShutDown = ShutDown_Enc;
+ ModInit->toModule.Open = Open_Enc;
+ ModInit->toModule.Write = Write_Enc;
+ ModInit->toModule.Stop = Stop_Enc;
+ ModInit->toModule.GetCurrentPosition = GetCurrentPosition_Enc;
+ ModInit->toModule.Configure = Configure_Enc;
+ ModInit->toModule.About = About_Enc;
+
+/* encoders can handle these calls if they wish,
+ * but they are generally not needed
+
+ ModInit->toModule.Flush = Flush;
+ ModInit->toModule.Pause = Pause;
+ ModInit->toModule.Drain = Drain;
+ ModInit->toModule.SetVolume = SetVolume;
+ ModInit->toModule.DrainCancel = DrainCancel;
+
+*/
+
+ QCDCallbacks_Enc = ModInit;
+
+ hwndPlayer = (HWND)QCDCallbacks_Enc->Service(opGetParentWnd, 0, 0, 0);
+
+ QCDCallbacks_Enc->Service(opGetPluginSettingsFile, INI_FILE, MAX_PATH, 0);
+
+ //
+ // TODO: all your plugin initialization here
+ //
+ config_enc_read();
+
+
+ // return TRUE for successful initialization
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+void ShutDown_Enc(int flags)
+{
+ Stop_Enc(STOPFLAG_FORCESTOP);
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL Open_Enc(LPCSTR medianame, WAVEFORMATEX *wf)
+{
+ char mp4FileName[256];
+
+ if(StringComp(strrchr(medianame, '.'), ".aac", 4))
+ {
+ MessageBox(hwndPlayer, "Only AAC files can be converted into Mp4 Files!", "File Type Error", MB_OK);
+ return FALSE;
+ }
+ else if(!isFolder(m_output_folder) && MessageBox(hwndPlayer, "You should select a output folder!", "Error", MB_OK) == IDOK )
+ {
+ if(!IsWindow(hwndConfigEnc))
+ hwndConfigEnc = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_CONFIG_CONVERT),
+ hwndPlayer, config_convert_proc);
+ ShowWindow(hwndConfigEnc, SW_SHOW);
+ return FALSE;
+ }
+ else
+ {
+ lstrcpy(mp4FileName, m_output_folder); // copy the folder path
+ lstrcat(mp4FileName, strrchr(medianame, '\\')); //copy the file name
+ lstrcpy(strrchr(mp4FileName, '.'), ".mp4"); // rename the file name to .mp4
+
+ if(covert_aac_to_mp4(medianame, mp4FileName))
+ {
+ MessageBox(hwndPlayer, "An error occured while converting AAC to MP4!", "An error occured!", MB_OK);
+ return FALSE;
+ }
+ else
+ {
+ QCDCallbacks_Enc->Service(opSetStatusMessage, "Converting OK", TEXT_TOOLTIP, 0);
+
+ return TRUE;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL Write_Enc(WriteDataStruct* writeData)
+{
+ //
+ // TODO : Use the raw wave audio data passed from the player.
+ //
+ // Return value - one of the follwing:
+ //
+ // TRUE - write succeeded
+ // FALSE - write failed
+ //
+ // Note: this call can block (eg: to wait for available space to write)
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL Stop_Enc(int flags)
+{
+ //
+ // TODO : Stop and close the output.
+ //
+ // Return TRUE for success, FALSE for failure
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL GetCurrentPosition_Enc(UINT *position, int flags)
+{
+ //
+ // TODO : set position to exact current playing position
+ // returned position needs to be latest marker sent to Write
+ // return TRUE for success
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL CALLBACK config_convert_proc(HWND hwndDlg, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ char str_buffer[MAX_PATH];
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ if(isFolder(m_output_folder))// is a driver folder
+ SetDlgItemText(hwndDlg, IDC_OUTPUTFOLDER, m_output_folder);
+ else
+ SetDlgItemText(hwndDlg, IDC_OUTPUTFOLDER, "Select Output Folder");
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_OUTPUTFOLDER:
+ {
+ char name[MAX_PATH];
+ BROWSEINFO bi;
+ ITEMIDLIST *idlist;
+ bi.hwndOwner = hwndDlg;
+ bi.pidlRoot = 0;
+ bi.pszDisplayName = name;
+ bi.lpszTitle = "Select a directory for saving mp4 files converted from aac files: ";
+ bi.ulFlags = BIF_RETURNONLYFSDIRS /*| BIF_USENEWUI*/;
+ bi.lpfn = NULL;
+ bi.lParam = 0;
+
+ idlist = SHBrowseForFolder( &bi );
+ if(idlist)
+ {
+ SHGetPathFromIDList( idlist, m_output_folder);
+ SetDlgItemText(hwndDlg, IDC_OUTPUTFOLDER, m_output_folder);
+ }
+ return TRUE;
+ }
+ case IDOK:
+ GetDlgItemText(hwndDlg, IDC_OUTPUTFOLDER, str_buffer, MAX_PATH);
+ if(isFolder(str_buffer)) // is a driver foder
+ lstrcpy(m_output_folder, str_buffer);
+ else
+ m_output_folder[0] = 0;
+
+ /* save config */
+ config_enc_write();
+ default:
+ /* close the dialogbox */
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void Configure_Enc(int flags)
+{
+ if(!IsWindow(hwndConfigEnc))
+ hwndConfigEnc = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_CONFIG_CONVERT),
+ hwndPlayer, config_convert_proc);
+ ShowWindow(hwndConfigEnc, SW_SHOWNORMAL);
+}
+
+//-----------------------------------------------------------------------------
+
+void About_Enc(int flags)
+{
+ if(!IsWindow(hwndAbout))
+ hwndAbout = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_ABOUT),
+ hwndPlayer, about_dialog_proc);
+ ShowWindow(hwndAbout, SW_SHOWNORMAL);
+}
--- /dev/null
+++ b/plugins/QCDMp4/QCDConvertDLL.h
@@ -1,0 +1,40 @@
+//-----------------------------------------------------------------------------
+//
+// File: QCDEncodeDLL.h
+//
+// About: QCD Player Output module DLL interface. For more documentation, see
+// QCDModOutput.h.
+//
+// Authors: Written by Paul Quinn
+//
+// QCD multimedia player application Software Development Kit Release 1.0.
+//
+// Copyright (C) 1997-2002 Quinnware
+//
+// This code is free. If you redistribute it in any form, leave this notice
+// here.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//-----------------------------------------------------------------------------
+
+#include "QCDModEncode.h"
+
+#ifndef QCDENCODEDLL_H
+#define QCDENCODEDLL_H
+
+extern QCDModInitEnc *QCDCallbacks_Enc;
+
+// Calls from the Player
+void ShutDown_Enc(int flags);
+BOOL Open_Enc(LPCSTR, WAVEFORMATEX *wf);
+BOOL Write_Enc(WriteDataStruct*);
+BOOL Stop_Enc(int flags);
+BOOL GetCurrentPosition_Enc(UINT *position, int flags);
+
+void Configure_Enc(int flags);
+void About_Enc(int flags);
+
+#endif //QCDOUTPUTDLL_H
\ No newline at end of file
--- /dev/null
+++ b/plugins/QCDMp4/QCDInputDLL.h
@@ -1,0 +1,52 @@
+//-----------------------------------------------------------------------------
+//
+// File: QCDInputDLL.h
+//
+// About: QCD Player Input module DLL interface. For more documentation, see
+// QCDModInput.h.
+//
+// Authors: Written by Paul Quinn and Richard Carlson.
+//
+// QCD multimedia player application Software Development Kit Release 1.0.
+//
+// Copyright (C) 1997-2002 Quinnware
+//
+// This code is free. If you redistribute it in any form, leave this notice
+// here.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef QCDInputDLL_H
+#define QCDInputDLL_H
+
+#include "QCDModInput.h"
+
+extern HINSTANCE hInstance;
+extern HWND hwndPlayer, hwndAbout;
+extern QCDModInitIn sQCDCallbacks, *QCDCallbacks;
+
+// Calls from the Player
+int GetMediaSupported(const char* medianame, MediaInfo *mediaInfo);
+int GetTrackExtents(const char* medianame, TrackExtents *ext, int flags);
+int GetCurrentPosition(const char* medianame, long *track, long *offset);
+
+void SetEQ(EQInfo*);
+void SetVolume(int levelleft, int levelright, int flags);
+
+int Play(const char* medianame, int framefrom, int frameto, int flags);
+int Pause(const char* medianame, int flags);
+int Stop(const char* medianame, int flags);
+int Eject(const char* medianame, int flags);
+
+int Initialize(QCDModInfo *ModInfo, int flags);
+void ShutDown(int flags);
+void Configure(int flags);
+void About(int flags);
+
+#endif //QCDInputDLL_H
+
+INT_PTR CALLBACK about_dialog_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
--- /dev/null
+++ b/plugins/QCDMp4/QCDModDefs.h
@@ -1,0 +1,355 @@
+//-----------------------------------------------------------------------------
+//
+// File: QCDModDefs.h
+//
+// About: Module definitions file. Miscellanious definitions used by different
+// module types. This file is published with the plugin SDKs.
+//
+// Authors: Written by Paul Quinn and Richard Carlson.
+//
+// Copyright:
+//
+// QCD multimedia player application Software Development Kit Release 1.0.
+//
+// Copyright (C) 1997-2002 Quinnware
+//
+// This code is free. If you redistribute it in any form, leave this notice
+// here.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef QCDMODDEFS_H
+#define QCDMODDEFS_H
+
+#include <windows.h>
+
+#ifdef __cplusplus
+#define PLUGIN_API extern "C" __declspec(dllexport)
+#else
+#define PLUGIN_API __declspec(dllexport)
+#endif
+
+// Current plugin version
+#define PLUGIN_API_VERSION 250
+
+//-----------------------------------------------------------------------------
+
+typedef struct {
+ char *moduleString;
+ char *moduleExtensions;
+
+} QCDModInfo;
+
+//-----------------------------------------------------------------------------
+// Services (ops) provided by the Player
+//-----------------------------------------------------------------------------
+typedef enum
+{ //*** below returns numeric info (*buffer not used)
+
+ opGetPlayerVersion = 0, // high-order word = major version (eg 3.01 is 3), low-order word = minor (eg 3.01 = 1)
+ opGetParentWnd = 1, // handle to player window
+ opGetPlayerInstance = 2, // HINSTANCE to player executable
+
+ opGetPlayerState = 9, // get current state of the player (returns: 1 = stopped, 2 = playing, 3 = paused, 0 = failed)
+ opGetNumTracks = 10, // number of tracks in playlist
+ opGetCurrentIndex = 11, // index of current track in playlist (0 based)
+ opGetNextIndex = 12, // get index of next track to play (0 based), param1 = index start index. -1 for after current
+ opGetTrackNum = 13, // get track number of index, param1 = index of track in playlist, -1 for current
+ // - 'track number' is the number of the track in it's respective album, as opposed to playlist number
+ // - the 'track number' for digital files will be 1, unless they are tagged with the CDDB identifier
+
+ opGetTrackLength = 14, // get track length, param1 = index of track in playlist, -1 for current
+ // param2 = 0 for seconds, 1 for milliseconds
+ opGetTime = 15, // get time on player, param1 = 0 for time displayed, 1 for track time, 2 for playlist time
+ // param2 = 0 for elapsed, 1 for remaining
+ opGetTrackState = 16, // get whether track is marked, param1 = index of track, -1 for current
+ opGetPlaylistNum = 17, // get playlist number of index, param1 = index of track in playlist, -1 for current
+ opGetMediaType = 18, // get media type of track, param1 = index if track in playlist, -1 for current
+ // - see MediaTypes below for return values
+
+ opGetAudioInfo = 19, // get format info about currently playing track
+ // - param1 = 0 for samplerate, 1 for bitrate, 2 for num channels
+
+ opGetOffline = 20, // true if client is in Offline Mode
+ opGetVisTarget = 21, // where is vis being drawn > 0 - internal to skin, 1 - external window, 2 - full screen
+ opGetAlwaysOnTop = 22, // true if player is set to 'Always on Top'
+ opGetRepeatState = 23, // returns: 0 - repeat off, 1 - repeat track, 2 - repeat all
+ opGetShuffleState = 27, // returns: 0 - shuffle off, 1 - shuffle enabled
+
+ opGetTimerState = 24, // low-order word: 0 - track ascend, 1 - playlist ascend, 2 - track descend, 3 - playlist descend
+ // hi-order word: 1 if 'show hours' is set, else 0
+
+ opGetVolume = 25, // get master volume level (0 - 100), param1: 0 = combined, 1 = left, 2 = right
+ opSetVolume = 26, // set master volume level, param1: vol level 0 - 100, param2: balance (-100 left, 0 center, 100 right)
+
+ opGetIndexFromPLNum = 28, // get index from playlist number, param1 = playlist number
+
+ opGetChildWnd = 30, // handle to the draggable window extension (only available on some skins)
+ opGetExtVisWnd = 31, // handle to the external visual window
+ opGetMusicBrowserWnd = 32, // handle to the music browser window
+ opGetSkinPreviewWnd = 33, // handle to the skin preview window
+ opGetPropertiesWnd = 34, // handle to the player properties window
+ opGetExtInfoWnd = 35, // handle to the extended information window
+ opGetAboutWnd = 36, // handle to the about window
+ opGetSegmentsWnd = 37, // handle to the segments window
+ opGetEQPresetsWnd = 38, // handle to the EQ presets window
+
+ opGetVisDimensions = 50, // gets the width and height of visual window (param1 = -1 current vis window, 0 internal vis, 1 external vis, 2 full screen)
+ // returns: HEIGHT in high word, WIDTH in low word
+
+ opGetQueriesComplete = 60, // get status on whether all tracks in playlist have been queryied for their info
+
+ // playlist manipulation
+ opDeleteIndex = 90, // delete index from playlist (param1 = index)
+ opSelectIndex = 91, // mark index as selected (param1 = index, param2 = 1 - set, 0 - unset)
+ opBlockIndex = 92, // mark index as blocked (param1 = index, param2 = 1 - set, 0 - unset)
+
+ opGetMediaInfo = 99, // get the CddbDisc object for the index specified, param1 = index of track, -1 for current
+ // param2 = pointer to integer that receives track value
+ // returns: pointer to CddbDisc object. Do not release or deallocate this pointer
+
+
+ //*** below returns string info in buffer, param1 = size of buffer
+ //*** returns 1 on success, 0 on failure
+
+ opGetTrackName = 100, // get track name, param2 = index of track in playlist, -1 for current
+ opGetArtistName = 101, // get artist name, param2 = index of track in playlist, -1 for current
+ opGetDiscName = 102, // get disc name, param2 = index of track in playlist, -1 for current
+
+ opGetTrackFile = 103, // file name of track in playlist, param2 = index of track in playlist, -1 for current
+ opGetSkinName = 104, // get current skin name
+
+ opGetPluginFolder = 105, // get current plugin folder
+ opGetPluginSettingsFile = 106, // get settings file (plugins.ini) that plugin should save settings to
+ opGetPluginCacheFile = 107, // get file that describes plugin validity, functions and names
+ opGetPlayerSettingsFile = 108, // get settings file (qcd.ini) that player saves it settings to (should use for read-only)
+
+ opGetMusicFolder = 110, // get current music folder
+ opGetPlaylistFolder = 111, // get current playlist folder
+ opGetSkinFolder = 112, // get current skin folder
+ opGetCDDBCacheFolder = 113, // get current folder for CDDB cached info
+
+ opGetCurrentPlaylist = 114, // get full pathname of playlist currently loaded
+
+ opGetMediaID = 115, // get media identifier, param2 = index of track in playlist, -1 for current
+ // - for CD's it's the TOC - for anything else, right now it's 0
+
+ opGetSupportedExtensions = 116, // get file extensions supported by the player, param2 = 0 - get all extensions, 1 - get registered extensions
+ // - returned extensions will be colon delimited
+
+
+ //*** below buffer points to struct or other object
+ //*** returns 1 on success, 0 on failure
+
+ opShowMainMenu = 120, // Display Main QCD Menu (buffer = POINT* - location to display menu)
+ opGetMainMenu = 121, // Returns copy of HMENU handle to QCD Menu (must use DestroyMenu on handle when complete)
+
+ opShowQuickTrack = 125, // Display QuickTrack Menu (buffer = POINT* - location to display menu)
+
+ opGetEQVals = 200, // get current EQ levels/on/off (buffer = EQInfo*)
+ opSetEQVals = 201, // set EQ levels/on/off (buffer = EQInfo*)
+
+ opGetProxyInfo = 202, // get proxy info (buffer = ProxyInfo*), returns 0 if proxy not in use
+
+
+ //*** below returns numeric info, buffer used
+
+ opGetIndexFromFilename = 210, // get the index of a file that exists in current playlist (buffer = full path of file),
+ // param1 = startindex (index to start searching on)
+ // returns -1 if file not in playlist
+
+
+ //*** below send information to player
+ //*** returns 1 on success, 0 on failure
+
+ opSetStatusMessage = 1000, // display message in status area (buffer = msg buffer (null term), param1 = text flags (see below))
+
+ opSetBrowserUrl = 1001, // set music browser URL (buffer = url (null term))
+ // null url buffer - closes browser
+ // param1 = 0 - normal, 1 - force open
+
+ opSetAudioInfo = 1002, // set the current music bitrate/khz (buffer = AudioInfo*, param1 = size of AudioInfo)
+
+ opSetTrackAlbum = 1003, // update track ablum name (buffer = album (null term), param1 = (string ptr)file name), param2 = MediaTypes
+ opSetTrackTitle = 1004, // update track title (buffer = title (null term), param1 = (string ptr)file name), param2 = MediaTypes
+ opSetTrackArtist = 1005, // update track artist name (buffer = artist (null term), param1 = (string ptr)file name), param2 = MediaTypes
+
+ opSetTrackExtents = 1007, // update track TrackExtents info (buffer = &TrackExtents), param1 = (string ptr)file name)
+ opSetTrackSeekable = 1008, // update track seekable flag (buffer = (string ptr)file name), param1 = TRUE/FALSE
+ opSetPlayNext = 1009, // set the next index to be played (buffer = NULL, param1 = index, index = -1 unsets playnext)
+ opSetIndexFilename = 1010, // updates the filename (or stream) that an index in the current playlist refers to, buffer = new filename, param1 = index
+
+ opSetPlaylist = 1006, // clear playlist, add files to playlist or reset playlist with new files
+ // buffer = file list (each file in quotes, string null terminated) Eg; buffer="\"file1.mp3\" \"file2.mp3\"\0" - NULL to clear playlist
+ // param1 = (string ptr)originating path (can be NULL if paths included with files)
+ // param2 = 1 - clear playlist flag, 2 - enqueue to top
+
+ opInsertPlaylist = 1011, // insert tracks into playlist
+ // buffer = file list (each file in quotes, string null terminated) Eg; buffer="\"file1.mp3\" \"file2.mp3\"\0"
+ // param1 = (string ptr)originating path (can be NULL if paths included with files)
+ // param2 = index location to insert tracks (-1 to insert at end)
+
+ opMovePlaylistTrack = 1012, // param1 = index of track to move, param2 = destination index (move shifts tracks between param1 and param2)
+ opSwapPlaylistTracks = 1013, // param1 = index of first track, param2 = index of second track (swap only switches indecies param1 and param2)
+
+
+
+ opSetSeekPosition = 1100, // seek to position during playback
+ // buffer = NULL, param1 = position
+ // param2 = 0 - position is in seconds, 1 - position is in milliseconds, 2 - position is in percent (use (float)param1))
+
+
+ //*** below configures custom plugin menu items for the 'plugin menu'
+ //*** Player will call plugin's configure routine with menu value when menu item selected
+ //*** returns 1 on success, 0 on failure
+
+ opSetPluginMenuItem = 2000, // buffer = HINSTANCE of plugin, param1 = item id, param2 = (string ptr)string to display
+ // - set param2 = 0 to remove item id from menu
+ // - set param1 = 0 and param2 = 0 to remove whole menu
+ opSetPluginMenuState = 2001, // buffer = HINSTANCE of plugin, param1 = item id, param2 = menu flags (same as windows menu flags - eg: MF_CHECKED)
+
+
+ //*** other services
+
+ opSafeWait = 10000 // plugin's can use this to wait on an object without worrying about deadlocking the player.
+ // this should only be called by the thread that enters the plugin, not by any plugin-created threads
+
+} PluginServiceOp;
+
+//-----------------------------------------------------------------------------
+// Info services api provided by the Player, called by Plugin.
+//-----------------------------------------------------------------------------
+typedef long (*PluginServiceFunc)(PluginServiceOp op, void *buffer, long param1, long param2);
+
+
+//-----------------------------------------------------------------------------
+typedef struct // for Output Plugin Write callback
+{
+ void *data; // pointer to valid data
+ int bytelen; // length of data pointed to by 'data' in bytes
+ UINT numsamples; // number of samples represented by 'data'
+ UINT bps; // bits per sample
+ UINT nch; // number of channels
+ UINT srate; // sample rate
+
+ UINT markerstart; // Marker position at start of data (marker is time value of data)
+ // (set to WAVE_VIS_DATA_ONLY to not have data sent to output plugins)
+ UINT markerend; // Marker position at end of data (not currently used, set to 0)
+} WriteDataStruct;
+
+//-----------------------------------------------------------------------------
+typedef struct // for GetTrackExtents Input Plugin callback
+{
+ UINT track; // for CD's, set the track number. Otherwise set to 1.
+ UINT start; // for CD's or media that doesn't start at the beginning
+ // of the file, set to start position. Otherwise set to 0.
+ UINT end; // set to end position of media.
+ UINT unitpersec; // whatever units are being used for this media, how many
+ // of them per second.
+ // (Note: ((end - start) / unitpersecond) = file length
+ UINT bytesize; // size of file in bytes (if applicable, otherwise 0).
+} TrackExtents;
+
+//-----------------------------------------------------------------------------
+typedef struct // for opSetAudioInfo service
+{
+ long struct_size; // sizeof(AudioInfo)
+ long level; // MPEG level (1 for MPEG1, 2 for MPEG2, 3 for MPEG2.5, 7 for MPEGpro)
+ long layer; // and layer (1, 2 or 3)
+ long bitrate; // audio bitrate in bits per second
+ long frequency; // audio freq in Hz
+ long mode; // 0 for stereo, 1 for joint-stereo, 2 for dual-channel, 3 for mono, 4 for multi-channel
+} AudioInfo;
+
+//-----------------------------------------------------------------------------
+// Equalizer Info
+//-----------------------------------------------------------------------------
+typedef struct // for coming QCD version
+{
+ long struct_size; // sizeof(EQInfo)
+ char enabled;
+ char preamp; // -128 to 127, 0 is even
+ char bands[10]; // -128 to 127, 0 is even
+} EQInfo;
+
+//-----------------------------------------------------------------------------
+typedef struct
+{
+ long struct_size; // sizeof(ProxyInfo)
+ char hostname[200];
+ long port;
+ char username[100];
+ char password[100];
+} ProxyInfo;
+
+//-----------------------------------------------------------------------------
+typedef enum // for MediaInfo.mediaType
+{
+ UNKNOWN_MEDIA = 0,
+ CD_AUDIO_MEDIA = 1,
+ DIGITAL_FILE_MEDIA = 2,
+ DIGITAL_STREAM_MEDIA = 3
+} MediaTypes;
+
+//-----------------------------------------------------------------------------
+#define MAX_TOC_LEN 2048
+typedef struct
+{
+ // media descriptors
+ CHAR mediaFile[MAX_PATH];
+ MediaTypes mediaType;
+
+ // cd audio media info
+ CHAR cd_mediaTOC[MAX_TOC_LEN];
+ int cd_numTracks;
+ int cd_hasAudio;
+
+ // operation info
+ int op_canSeek;
+
+ // not used
+ int reserved[4];
+
+} MediaInfo;
+
+
+//-----------------------------------------------------------------------------
+// When subclassing the parent window, a plugin can watch for these messages
+// to react to events going on between plugins and player
+// DO NOT SEND THESE MESSAGES - can only watch for them
+
+// Plugin to Player Notifiers
+#define WM_PN_POSITIONUPDATE (WM_USER + 100) // playback progress updated
+#define WM_PN_PLAYSTARTED (WM_USER + 101) // playback has started
+#define WM_PN_PLAYSTOPPED (WM_USER + 102) // playback has stopped by user
+#define WM_PN_PLAYPAUSED (WM_USER + 103) // playback has been paused
+#define WM_PN_PLAYDONE (WM_USER + 104) // playback has finished (track completed)
+#define WM_PN_MEDIAEJECTED (WM_USER + 105) // a CD was ejected (lParam = (LPCSTR)medianame)
+#define WM_PN_MEDIAINSERTED (WM_USER + 106) // a CD was inserted (lParam = (LPCSTR)medianame)
+#define WM_PN_INFOCHANGED (WM_USER + 107) // track information was updated (lParam = (LPCSTR)medianame)
+#define WM_PN_TRACKCHANGED (WM_USER + 109) // current track playing has changed (relevant from CD plugin) (lParam = (LPCSTR)medianame)
+
+// Player to Plugin Notifiers
+#define WM_PN_PLAYLISTCHANGED (WM_USER + 200) // playlist has changed in some way (add, delete, sort, shuffle, drag-n-drop, etc...)
+
+// For intercepting main menu display
+// (so you can get handle, modify, and display your own)
+#define WM_SHOWMAINMENU (WM_USER + 20)
+
+//-----------------------------------------------------------------------------
+// To shutdown player, send this command
+#define WM_SHUTDOWN (WM_USER + 5)
+
+//-----------------------------------------------------------------------------
+// opSetStatusMessage textflags
+#define TEXT_DEFAULT 0x0 // message scrolls by in status window
+#define TEXT_TOOLTIP 0x1 // message acts as tooltip in status window
+#define TEXT_URGENT 0x2 // forces message to appear even if no status window (using msg box)
+#define TEXT_HOLD 0x4 // tooltip message stays up (no fade out)
+
+
+#endif //QCDMODDEFS_H
\ No newline at end of file
--- /dev/null
+++ b/plugins/QCDMp4/QCDModEncode.h
@@ -1,0 +1,76 @@
+//-----------------------------------------------------------------------------
+//
+// File: QCDModEncode.h
+//
+// About: Encode plugin module interface. This file is published with the
+// Encode plugin SDK.
+//
+// Authors: Written by Paul Quinn
+//
+// Copyright:
+//
+// QCD multimedia player application Software Development Kit Release 1.0.
+//
+// Copyright (C) 1997-2002 Quinnware
+//
+// This code is free. If you redistribute it in any form, leave this notice
+// here.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef QCDMODENCODE_H
+#define QCDMODENCODE_H
+
+#include "QCDModDefs.h"
+
+// name of the DLL export for encode plugins
+#define ENCODEDLL_ENTRY_POINT QEncodeModule
+
+// Stop will receive one of these flags
+#define STOPFLAG_FORCESTOP 0
+#define STOPFLAG_PLAYDONE 1
+
+// pause flags
+#define PAUSE_DISABLED 0 // Pause() call is to unpause playback
+#define PAUSE_ENABLED 1 // Pause() call is to pause playback
+
+//-----------------------------------------------------------------------------
+
+typedef struct
+{
+ UINT size; // size of init structure
+ UINT version; // plugin structure version (set to PLUGIN_API_VERSION)
+ PluginServiceFunc Service; // player supplied services callback
+
+ struct
+ {
+ void *dummy;
+ void (*PositionUpdate)(UINT marker);
+ void *Reserved[2];
+ } toPlayer;
+
+ struct
+ {
+ BOOL (*Open)(LPCSTR, WAVEFORMATEX *wf);
+ BOOL (*Write)(WriteDataStruct*);
+ BOOL (*Flush)(UINT marker);
+ BOOL (*Stop)(int flags);
+ BOOL (*Pause)(int flags);
+ BOOL (*Drain)(int flags);
+ void (*ShutDown)(int flags);
+
+ void (*Configure)(int flags);
+ void (*About)(int flags);
+
+ BOOL (*SetVolume)(int levelleft, int levelright, int flags);
+ BOOL (*GetCurrentPosition)(UINT *position, int flags);
+ BOOL (*DrainCancel)(int flags);
+ void *Reserved[8];
+ } toModule;
+} QCDModInitEnc;
+
+#endif //QCDMODENCODE_H
\ No newline at end of file
--- /dev/null
+++ b/plugins/QCDMp4/QCDModInput.h
@@ -1,0 +1,117 @@
+//-----------------------------------------------------------------------------
+//
+// File: QCDModInput.h
+//
+// About: Input plugin module interface. This file is published with the
+// Input plugin SDK.
+//
+// Authors: Written by Paul Quinn and Richard Carlson.
+//
+// Copyright:
+//
+// QCD multimedia player application Software Development Kit Release 1.0.
+//
+// Copyright (C) 1997-2002 Quinnware
+//
+// This code is free. If you redistribute it in any form, leave this notice
+// here.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef QCDMODINPUT_H
+#define QCDMODINPUT_H
+
+#include "QCDModDefs.h"
+
+// name of the DLL export for input plugins
+#define INPUTDLL_ENTRY_POINT QInputModule2 // (updated plugin api version 240+)
+
+// media insert flags
+#define MEDIAINSERT_PLAY 0x1
+#define MEDIAINSERT_ADDTRACKS 0x2
+#define MEDIAINSERT_ADDSEGMENTS 0x4
+#define MEDIAINSERT_CLEARPLAYLIST 0x8
+
+// Stop will receive one of these flags (pass to output plugin's stop())
+#define STOPFLAG_FORCESTOP 0 // stop occuring due to user action or other event
+#define STOPFLAG_PLAYDONE 1 // stop occuring due to playlist completion
+
+// play flags
+#define PLAYFLAG_PLAYBACK 0x0
+#define PLAYFLAG_ENCODING 0x1
+#define PLAYFLAG_SEEKING 0x2
+
+// Wave Marker flags
+#define WAVE_VIS_DATA_ONLY -1 // set to WaveDataStruct.markerstart in OutputWrite() call have data only go to vis
+ // and not to output plugin
+// pause flags
+#define PAUSE_DISABLED 0 // Pause() call is to unpause playback
+#define PAUSE_ENABLED 1 // Pause() call is to pause playback
+
+//-----------------------------------------------------------------------------
+// Input Module
+//-----------------------------------------------------------------------------
+typedef struct
+{
+ unsigned int size; // size of init structure
+ unsigned int version; // plugin structure version (set to PLUGIN_API_VERSION)
+ PluginServiceFunc Service; // player supplied services callback
+
+ struct
+ {
+ void (*PositionUpdate)(unsigned int position);
+ void (*PlayStopped)(const char* medianame); // notify player of play stop
+ void (*PlayStarted)(const char* medianame); // notify player of play start
+ void (*PlayPaused)(const char* medianame, int flags); // notify player of play pause
+ void (*PlayDone)(const char* medianame); // notify player when play done
+ void (*PlayTrackChanged)(const char* medianame); // notify player when playing track changes (cd audio relevant only)
+ void (*MediaEjected)(const char* medianame); // notify player of media eject (cd audio relevant)
+ void (*MediaInserted)(const char* medianame, int flags); // notify player of media insert (cd audio relevant)
+
+ // output plugin calls
+ int (*OutputOpen)(const char* medianame, WAVEFORMATEX*); // open output for wave data
+ int (*OutputWrite)(WriteDataStruct*); // send PCM audio data to output
+ // (blocks until write completes, thus if output is paused can
+ // block until unpaused)
+ int (*OutputDrain)(int flags); // wait for all output to complete (blocking)
+ int (*OutputDrainCancel)(int flags); // break a drain in progress
+ int (*OutputFlush)(unsigned int marker); // flush output upto marker
+ int (*OutputStop)(int flags); // stop output
+ int (*OutputPause)(int flags); // pause output
+
+ int (*OutputSetVol)(int levelleft, int levelright, int flags);
+ int (*OutputGetCurrentPosition)(unsigned int *position, int flags);
+
+ void *Reserved[10];
+ } toPlayer;
+
+ struct
+ {
+ int (*Initialize)(QCDModInfo *modInfo, int flags); // initialize plugin
+ void (*ShutDown)(int flags); // shutdown plugin
+
+ int (*Play)(const char* medianame, int playfrom, int playto, int flags); // start playing playfrom->playto
+ int (*Stop)(const char* medianame, int flags); // stop playing
+ int (*Pause)(const char* medianame, int flags); // pause playback
+ int (*Eject)(const char* medianame, int flags); // eject media
+ void (*SetEQ)(EQInfo*); // update EQ settings
+
+ int (*GetMediaSupported)(const char* medianame, MediaInfo *mediaInfo); // does plugin support medianame (and provides info for media)
+ int (*GetTrackExtents)(const char* medianame, TrackExtents *ext, int flags); // get media start, end & units
+ int (*GetCurrentPosition)(const char* medianame, long *track, long *offset); // get playing media's position
+
+ void (*Configure)(int flags); // launch configuration
+ void (*About)(int flags); // launch about info
+
+ void (*SetVolume)(int levelleft, int levelright, int flags); // level 0 - 100
+
+ void *Reserved[10];
+ } toModule;
+
+} QCDModInitIn;
+
+#endif //QCDMODINPUT_H
--- /dev/null
+++ b/plugins/QCDMp4/QCDMp4.c
@@ -1,0 +1,1114 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: QCDMp4.c,v 1.1 2003/04/28 19:07:57 menno Exp $
+**/
+
+//#define DEBUG_OUTPUT
+#include "QCDInputDLL.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <commctrl.h>
+#include <commdlg.h>
+#include <shellapi.h>
+#include <stdlib.h>
+#include <math.h>
+#include <faad.h>
+#include <mp4.h>
+
+#include "resource.h"
+#include "utils.h"
+#include "config.h"
+#include "aacinfo.h"
+
+static long priority_table[] = {
+ 0,
+ THREAD_PRIORITY_HIGHEST,
+ THREAD_PRIORITY_ABOVE_NORMAL,
+ THREAD_PRIORITY_NORMAL,
+ THREAD_PRIORITY_BELOW_NORMAL,
+ THREAD_PRIORITY_LOWEST
+};
+static int res_id_table[] = {
+ IDC_16BITS,
+ IDC_24BITS,
+ IDC_32BITS,
+ 0,
+ IDC_16BITS_DITHERED
+};
+static int res_table[] = {
+ 16,
+ 24,
+ 32,
+ 0,
+ 16
+};
+
+typedef struct state
+{
+ /* general stuff */
+ faacDecHandle hDecoder;
+ int samplerate;
+ unsigned char channels;
+ int decode_pos_ms; // current decoding position, in milliseconds
+ int paused; // are we paused?
+ int seek_needed; // if != -1, it is the point that the decode thread should seek to, in ms.
+ char filename[_MAX_PATH];
+ int filetype; /* 0: MP4; 1: AAC */
+ int last_frame;
+
+ /* MP4 stuff */
+ MP4FileHandle mp4file;
+ int mp4track;
+ MP4SampleId numSamples;
+ MP4SampleId sampleId;
+
+ /* AAC stuff */
+ FILE *aacfile;
+ long filesize;
+ long bytes_read;
+ long bytes_into_buffer;
+ long bytes_consumed;
+ unsigned char *buffer;
+ long seconds;
+// faadAACInfo aacInfo;
+} state;
+
+static state mp4state;
+
+HINSTANCE hInstance;
+HWND hwndPlayer, hwndConfig, hwndAbout;
+QCDModInitIn sQCDCallbacks, *QCDCallbacks;
+BOOL oldAPIs = 0;
+
+static int killPlayThread;
+HANDLE play_thread_handle = INVALID_HANDLE_VALUE; // the handle to the decode thread
+
+/* Function definitions */
+DWORD WINAPI MP4PlayThread(void *b); // the decode thread procedure
+DWORD WINAPI AACPlayThread(void *b); // the decode thread procedure
+
+#ifdef DEBUG_OUTPUT
+void in_mp4_DebugOutput(char *message)
+{
+ char s[1024];
+
+ sprintf(s, "%s: %s", mp4state.filename, message);
+ MessageBox(NULL, s, "Debug Message", MB_OK);
+}
+#endif
+
+static void show_error(HWND hwnd, char *message, ...)
+{
+ if (m_show_errors)
+ MessageBox(hwnd, message, "Error", MB_OK);
+}
+
+void config_read()
+{
+ char priority[10];
+ char resolution[10];
+ char show_errors[10];
+ char use_for_aac[10];
+
+ strcpy(show_errors, "1");
+ strcpy(priority, "3");
+ strcpy(resolution, "0");
+ strcpy(use_for_aac, "1");
+
+ RS(priority);
+ RS(resolution);
+ RS(show_errors);
+ RS(use_for_aac);
+
+ m_priority = atoi(priority);
+ m_resolution = atoi(resolution);
+ m_show_errors = atoi(show_errors);
+ m_use_for_aac = atoi(use_for_aac);
+}
+
+void config_write()
+{
+ char priority[10];
+ char resolution[10];
+ char show_errors[10];
+ char use_for_aac[10];
+
+ itoa(m_priority, priority, 10);
+ itoa(m_resolution, resolution, 10);
+ itoa(m_show_errors, show_errors, 10);
+ itoa(m_use_for_aac, use_for_aac, 10);
+
+ WS(priority);
+ WS(resolution);
+ WS(show_errors);
+ WS(use_for_aac);
+}
+
+//-----------------------------------------------------------------------------
+
+int WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID pRes)
+{
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ hInstance = hInst;
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+//old entrypoint api
+PLUGIN_API BOOL QInputModule(QCDModInitIn *ModInit, QCDModInfo *ModInfo)
+{
+ ModInit->version = PLUGIN_API_VERSION;
+ ModInit->toModule.ShutDown = ShutDown;
+ ModInit->toModule.GetTrackExtents = GetTrackExtents;
+ ModInit->toModule.GetMediaSupported = GetMediaSupported;
+ ModInit->toModule.GetCurrentPosition= GetCurrentPosition;
+ ModInit->toModule.Play = Play;
+ ModInit->toModule.Pause = Pause;
+ ModInit->toModule.Stop = Stop;
+ ModInit->toModule.SetVolume = SetVolume;
+ ModInit->toModule.About = About;
+ ModInit->toModule.Configure = Configure;
+ QCDCallbacks = ModInit;
+
+ /* read config */
+ QCDCallbacks->Service(opGetPluginSettingsFile, INI_FILE, MAX_PATH, 0);
+ config_read();
+
+ ModInfo->moduleString = "MPEG-4 General Audio Plugin v1.0";
+ ModInfo->moduleExtensions = m_use_for_aac ? "MP4:AAC" : "MP4";
+
+ hwndPlayer = (HWND)ModInit->Service(opGetParentWnd, 0, 0, 0);
+ mp4state.filename[0] = 0;
+ mp4state.seek_needed = -1;
+ mp4state.paused = 0;
+ play_thread_handle = INVALID_HANDLE_VALUE;
+
+ oldAPIs = 1;
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+PLUGIN_API QCDModInitIn* INPUTDLL_ENTRY_POINT(QCDModInitIn *ModInit, QCDModInfo *ModInfo)
+{
+ sQCDCallbacks.version = PLUGIN_API_VERSION;
+ sQCDCallbacks.toModule.Initialize = Initialize;
+ sQCDCallbacks.toModule.ShutDown = ShutDown;
+ sQCDCallbacks.toModule.GetTrackExtents = GetTrackExtents;
+ sQCDCallbacks.toModule.GetMediaSupported = GetMediaSupported;
+ sQCDCallbacks.toModule.GetCurrentPosition = GetCurrentPosition;
+ sQCDCallbacks.toModule.Play = Play;
+ sQCDCallbacks.toModule.Pause = Pause;
+ sQCDCallbacks.toModule.Stop = Stop;
+ sQCDCallbacks.toModule.SetVolume = SetVolume;
+ sQCDCallbacks.toModule.About = About;
+ sQCDCallbacks.toModule.Configure = Configure;
+
+ QCDCallbacks = &sQCDCallbacks;
+ return &sQCDCallbacks;
+}
+
+//----------------------------------------------------------------------------
+
+int Initialize(QCDModInfo *ModInfo, int flags)
+{
+ hwndPlayer = (HWND)QCDCallbacks->Service(opGetParentWnd, 0, 0, 0);
+
+ mp4state.filename[0] = 0;
+ mp4state.seek_needed = -1;
+ mp4state.paused = 0;
+ play_thread_handle = INVALID_HANDLE_VALUE;
+
+ /* read config */
+ QCDCallbacks->Service(opGetPluginSettingsFile, INI_FILE, MAX_PATH, 0);
+ config_read();
+
+ ModInfo->moduleString = "MPEG-4 General Audio Plugin v1.0";
+ ModInfo->moduleExtensions = m_use_for_aac ? "MP4:AAC" : "MP4";
+
+ // insert menu item into plugin menu
+// QCDCallbacks->Service(opSetPluginMenuItem, hInstance, IDD_CONFIG, (long)"Mp4 Plug-in");
+
+ return TRUE;
+}
+
+//----------------------------------------------------------------------------
+
+void ShutDown(int flags)
+{
+ Stop(mp4state.filename, STOPFLAG_FORCESTOP);
+
+ // delete the inserted plugin menu
+// QCDCallbacks->Service(opSetPluginMenuItem, hInstance, 0, 0);
+}
+
+//-----------------------------------------------------------------------------
+
+int GetMediaSupported(const char* medianame, MediaInfo *mediaInfo)
+{
+ char *ch = strrchr(medianame, '.');
+
+ if (!medianame || !*medianame)
+ return FALSE;
+
+ if(!ch)
+ return (lstrlen(medianame) > 2); // no extension defaults to me (if not drive letter)
+
+ /* Finally fixed */
+ if(StringComp(ch, ".mp4", 4) == 0)
+ {
+ mediaInfo->mediaType = DIGITAL_FILE_MEDIA;
+ mediaInfo->op_canSeek = TRUE;
+ mp4state.filetype = 0;
+ return TRUE;
+ }
+ else if(StringComp(ch, ".aac", 4) ==0)
+ {
+ mediaInfo->mediaType = DIGITAL_FILE_MEDIA;
+ mediaInfo->op_canSeek = FALSE;
+ mp4state.filetype = 1;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+
+int getsonglength(char *fn)
+{
+ long msDuration = 0;
+
+ if(StringComp(fn + strlen(fn) - 3, "MP4", 3) == 0)
+ {
+ int track;
+ MP4Duration length;
+ MP4FileHandle file;
+
+ file = MP4Read(fn, 0);
+ if (!file)
+ return 0;
+
+ if ((track = GetAACTrack(file)) < 0)
+ {
+ MP4Close(file);
+ return -1;
+ }
+
+ length = MP4GetTrackDuration(file, track);
+
+ msDuration = MP4ConvertFromTrackDuration(file, track,
+ length, MP4_MSECS_TIME_SCALE);
+
+ MP4Close(file);
+
+ return msDuration;
+ }
+ else
+ {
+// faadAACInfo aacInfo;
+// get_AAC_format(fn, &aacInfo);
+
+// return aacInfo.length;
+ return 0;
+ }
+}
+
+int GetTrackExtents(const char* medianame, TrackExtents *ext, int flags)
+{
+ ext->track = 1;
+ ext->start = 0;
+ if( (ext->end = getsonglength(medianame)) < 0 )
+ return FALSE;
+ ext->bytesize = 0;
+ ext->unitpersec = 1000;
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL CALLBACK config_dialog_proc(HWND hwndDlg, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ int i;
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ SendMessage(GetDlgItem(hwndDlg, IDC_PRIORITY), TBM_SETRANGE, TRUE, MAKELONG(1,5));
+ SendMessage(GetDlgItem(hwndDlg, IDC_PRIORITY), TBM_SETPOS, TRUE, m_priority);
+ SendMessage(GetDlgItem(hwndDlg, res_id_table[m_resolution]), BM_SETCHECK, BST_CHECKED, 0);
+ if (m_show_errors)
+ SendMessage(GetDlgItem(hwndDlg, IDC_ERROR), BM_SETCHECK, BST_CHECKED, 0);
+ if (m_use_for_aac)
+ SendMessage(GetDlgItem(hwndDlg, IDC_USEFORAAC), BM_SETCHECK, BST_CHECKED, 0);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ m_show_errors = SendMessage(GetDlgItem(hwndDlg, IDC_ERROR), BM_GETCHECK, 0, 0);
+ m_use_for_aac = SendMessage(GetDlgItem(hwndDlg, IDC_USEFORAAC), BM_GETCHECK, 0, 0);
+ m_priority = SendMessage(GetDlgItem(hwndDlg, IDC_PRIORITY), TBM_GETPOS, 0, 0);
+ for (i = 0; i < 5; i++)
+ {
+ if (SendMessage(GetDlgItem(hwndDlg, res_id_table[i]), BM_GETCHECK, 0, 0))
+ {
+ m_resolution = i;
+ break;
+ }
+ }
+
+ /* save config */
+ config_write();
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void Configure(int flags)
+{
+ if(!IsWindow(hwndConfig))
+ hwndConfig = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_CONFIG_INPUT), hwndPlayer, config_dialog_proc);
+ ShowWindow(hwndConfig, SW_SHOWNORMAL);
+}
+
+//-----------------------------------------------------------------------------
+// proc of "About Dialog"
+INT_PTR CALLBACK about_dialog_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static RECT rcLOGO, rcMail1, rcMail2/*, rcMail3*/;
+ POINT ptMouse;
+ static char szPluginVer[] = "QCD MP4 Input Plug-in v1.0\nCompiled on " __TIME__ ", " __DATE__;
+ static char szFLACVer[] = "Using: FAAD2 v "FAAD2_VERSION" by";
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ case WM_MOVE:
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_LOGO), &rcLOGO);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_MAIL1), &rcMail1);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_MAIL2), &rcMail2);
+// GetWindowRect(GetDlgItem(hwndDlg, IDC_MAIL2), &rcMail3);
+
+ SetDlgItemText(hwndDlg, IDC_PLUGINVER, szPluginVer);
+ SetDlgItemText(hwndDlg, IDC_FAADVER, szFLACVer);
+
+ return TRUE;
+ case WM_MOUSEMOVE:
+ ptMouse.x = LOWORD(lParam);
+ ptMouse.y = HIWORD(lParam);
+ ClientToScreen(hwndDlg, &ptMouse);
+ if( (ptMouse.x >= rcLOGO.left && ptMouse.x <= rcLOGO.right &&
+ ptMouse.y >= rcLOGO.top && ptMouse.y<= rcLOGO.bottom)
+ ||
+ (ptMouse.x >= rcMail1.left && ptMouse.x <= rcMail1.right &&
+ ptMouse.y >= rcMail1.top && ptMouse.y<= rcMail1.bottom)
+ ||
+ (ptMouse.x >= rcMail2.left && ptMouse.x <= rcMail2.right &&
+ ptMouse.y >= rcMail2.top && ptMouse.y<= rcMail2.bottom)
+/* ||
+ (ptMouse.x >= rcMail3.left && ptMouse.x <= rcMail3.right &&
+ ptMouse.y >= rcMail3.top && ptMouse.y<= rcMail3.bottom)*/ )
+ SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(32649)));
+ else
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+
+ return TRUE;
+ case WM_LBUTTONDOWN:
+ ptMouse.x = LOWORD(lParam);
+ ptMouse.y = HIWORD(lParam);
+ ClientToScreen(hwndDlg, &ptMouse);
+ if(ptMouse.x >= rcLOGO.left && ptMouse.x <= rcLOGO.right &&
+ ptMouse.y >= rcLOGO.top && ptMouse.y<= rcLOGO.bottom)
+ ShellExecute(0, NULL, "http://www.audiocoding.com", NULL,NULL, SW_NORMAL);
+ else if(ptMouse.x >= rcMail1.left && ptMouse.x <= rcMail1.right &&
+ ptMouse.y >= rcMail1.top && ptMouse.y<= rcMail1.bottom)
+ ShellExecute(0, NULL, "mailto:shaohao@elong.com", NULL,NULL, SW_NORMAL);
+ else if(ptMouse.x >= rcMail2.left && ptMouse.x <= rcMail2.right &&
+ ptMouse.y >= rcMail2.top && ptMouse.y<= rcMail2.bottom)
+ ShellExecute(0, NULL, "mailto:menno@audiocoding.com", NULL,NULL, SW_NORMAL);
+/* else if(ptMouse.x >= rcMail3.left && ptMouse.x <= rcMail3.right &&
+ ptMouse.y >= rcMail3.top && ptMouse.y<= rcMail3.bottom)
+ ShellExecute(0, NULL, "I don't know", NULL,NULL, SW_NORMAL);
+*/
+ return TRUE;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ default:
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void About(int flags)
+{
+ if(!IsWindow(hwndAbout))
+ hwndAbout = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_ABOUT), hwndPlayer, about_dialog_proc);
+ ShowWindow(hwndAbout, SW_SHOWNORMAL);
+}
+
+//-----------------------------------------------------------------------------
+
+int Play(const char* medianame, int playfrom, int playto, int flags)
+{
+ static WAVEFORMATEX wf;
+
+ if(flags == PLAYFLAG_ENCODING)
+ {
+ if(QCDCallbacks->toPlayer.OutputOpen(medianame, &wf))
+ Stop(medianame, STOPFLAG_FORCESTOP);
+ return FALSE;
+ }
+
+ if(stricmp(mp4state.filename, medianame) != 0)
+ {
+ sQCDCallbacks.toPlayer.OutputStop(STOPFLAG_PLAYDONE);
+ Stop(mp4state.filename, STOPFLAG_PLAYDONE);
+ }
+
+ if(mp4state.paused)
+ {
+ // Update the player controls to reflect the new unpaused state
+ sQCDCallbacks.toPlayer.OutputPause(0);
+
+ Pause(medianame, PAUSE_DISABLED);
+
+ if (playfrom >= 0)
+ mp4state.seek_needed = playfrom;
+ }
+ else if(play_thread_handle != INVALID_HANDLE_VALUE)
+ {
+ mp4state.seek_needed = playfrom;
+ return TRUE;
+ }
+ else
+ {
+#ifdef DEBUG_OUTPUT
+ in_mp4_DebugOutput("play");
+#endif
+ int thread_id;
+ int avg_bitrate, br, sr;
+ unsigned char *buffer;
+ int buffer_size;
+ faacDecConfigurationPtr config;
+
+ mp4state.channels = 0;
+ mp4state.samplerate = 0;
+ mp4state.filetype = 0;
+
+ strcpy(mp4state.filename, medianame);
+
+ if(StringComp(medianame + strlen(medianame) - 3, "AAC", 3) == 0)
+ mp4state.filetype = 1;
+
+ mp4state.hDecoder = faacDecOpen();
+ if (!mp4state.hDecoder)
+ {
+ show_error(hwndPlayer, "Unable to open decoder library.");
+ return -1;
+ }
+
+ config = faacDecGetCurrentConfiguration(mp4state.hDecoder);
+ config->outputFormat = m_resolution + 1;
+ faacDecSetConfiguration(mp4state.hDecoder, config);
+
+ if (mp4state.filetype)
+ {
+ long pos, tmp, read, tagsize;
+
+ // get_AAC_format(mp4state.filename, &mp4state.aacInfo);
+
+ mp4state.aacfile = fopen(mp4state.filename, "rb");
+ if (!mp4state.aacfile)
+ {
+ show_error(hwndPlayer, "Unable to open file.");
+ faacDecClose(mp4state.hDecoder);
+ return -1;
+ }
+
+ pos = ftell(mp4state.aacfile);
+ fseek(mp4state.aacfile, 0, SEEK_END);
+ mp4state.filesize = ftell(mp4state.aacfile);
+ fseek(mp4state.aacfile, pos, SEEK_SET);
+
+ if (!(mp4state.buffer=(unsigned char*)malloc(768*48)))
+ {
+ show_error(hwndPlayer, "Memory allocation error.");
+ faacDecClose(mp4state.hDecoder);
+ fclose(mp4state.aacfile);
+ return -1;
+ }
+ memset(mp4state.buffer, 0, 768*48);
+
+ if (mp4state.filesize < 768*48)
+ tmp = mp4state.filesize;
+ else
+ tmp = 768*48;
+ read = fread(mp4state.buffer, 1, tmp, mp4state.aacfile);
+ if (read == tmp)
+ {
+ mp4state.bytes_read = read;
+ mp4state.bytes_into_buffer = read;
+ }
+ else
+ {
+ show_error(hwndPlayer, "Error reading from file.");
+ faacDecClose(mp4state.hDecoder);
+ fclose(mp4state.aacfile);
+ return -1;
+ }
+
+ if (StringComp(mp4state.buffer, "ID3", 3) == 0)
+ {
+ /* high bit is not used */
+ tagsize = (mp4state.buffer[6] << 21) | (mp4state.buffer[7] << 14) |
+ (mp4state.buffer[8] << 7) | (mp4state.buffer[9] << 0);
+
+ tagsize += 10;
+ }
+ else
+ {
+ tagsize = 0;
+ }
+
+ if ((mp4state.bytes_consumed = faacDecInit(mp4state.hDecoder,
+ mp4state.buffer+tagsize, mp4state.bytes_into_buffer,
+ &mp4state.samplerate, &mp4state.channels)) < 0)
+ {
+ show_error(hwndPlayer, "Can't initialize library.");
+ faacDecClose(mp4state.hDecoder);
+ fclose(mp4state.aacfile);
+ return -1;
+ }
+ mp4state.bytes_consumed += tagsize;
+ mp4state.bytes_into_buffer -= mp4state.bytes_consumed;
+
+ // avg_bitrate = mp4state.aacInfo.bitrate;
+ avg_bitrate = 0;
+
+// module.is_seekable = 0;
+ }
+ else
+ {
+ mp4state.mp4file = MP4Read(mp4state.filename, 0);
+ if (!mp4state.mp4file)
+ {
+ show_error(hwndPlayer, "Unable to open file.");
+ faacDecClose(mp4state.hDecoder);
+ return -1;
+ }
+
+ if ((mp4state.mp4track = GetAACTrack(mp4state.mp4file)) < 0)
+ {
+ show_error(hwndPlayer, "Unsupported Audio track type.");
+ faacDecClose(mp4state.hDecoder);
+ MP4Close(mp4state.mp4file);
+ return -1;
+ }
+
+ buffer = NULL;
+ buffer_size = 0;
+ MP4GetTrackESConfiguration(mp4state.mp4file, mp4state.mp4track,
+ &buffer, &buffer_size);
+ if (!buffer)
+ {
+ faacDecClose(mp4state.hDecoder);
+ MP4Close(mp4state.mp4file);
+ return -1;
+ }
+
+ if(faacDecInit2(mp4state.hDecoder, buffer, buffer_size,
+ &mp4state.samplerate, &mp4state.channels) < 0)
+ {
+ /* If some error initializing occured, skip the file */
+ faacDecClose(mp4state.hDecoder);
+ MP4Close(mp4state.mp4file);
+ return -1;
+ }
+ free(buffer);
+
+ avg_bitrate = MP4GetTrackIntegerProperty(mp4state.mp4file, mp4state.mp4track,
+ "mdia.minf.stbl.stsd.mp4a.esds.decConfigDescr.avgBitrate");
+
+ mp4state.numSamples = MP4GetTrackNumberOfSamples(mp4state.mp4file, mp4state.mp4track);
+ mp4state.sampleId = 1;
+
+// module.is_seekable = 1;
+ }
+
+ if (mp4state.channels == 0)
+ {
+ show_error(hwndPlayer, "Number of channels not supported for playback.");
+ faacDecClose(mp4state.hDecoder);
+ if (mp4state.filetype)
+ fclose(mp4state.aacfile);
+ else
+ MP4Close(mp4state.mp4file);
+ return -1;
+ }
+
+ // open outputdevice
+ wf.wFormatTag = WAVE_FORMAT_PCM;
+ wf.cbSize = 0;
+ wf.nChannels = mp4state.channels;
+ wf.wBitsPerSample = res_table[m_resolution];
+ wf.nSamplesPerSec = mp4state.samplerate;
+ wf.nBlockAlign = wf.nChannels * wf.wBitsPerSample / 8;
+ wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;
+ if (!QCDCallbacks->toPlayer.OutputOpen(mp4state.filename, &wf))
+ {
+ show_error(hwndPlayer, "Error: Failed openning output plugin!");
+ faacDecClose(mp4state.hDecoder);
+ if (mp4state.filetype)
+ fclose(mp4state.aacfile);
+ else
+ MP4Close(mp4state.mp4file);
+ return -1; // cannot open sound device
+ }
+
+ mp4state.paused = 0;
+ mp4state.decode_pos_ms = 0;
+ mp4state.seek_needed = playfrom > 0 ? playfrom : -1;
+
+ br = (int)floor(((float)avg_bitrate + 500.0)/1000.0);
+ sr = (int)floor((float)mp4state.samplerate/1000.0);
+ // show constant bitrate at first
+ {
+ AudioInfo cai;
+ cai.struct_size = sizeof(AudioInfo);
+ cai.frequency = sr * 1000;
+ cai.bitrate = br * 1000;
+ cai.mode = (mp4state.channels == 2) ? 0 : 3;
+ cai.layer = 0;
+ cai.level = 0;
+ QCDCallbacks->Service(opSetAudioInfo, &cai, sizeof(AudioInfo), 0);
+ }
+
+ killPlayThread = 0;
+
+ if (mp4state.filetype)
+ {
+ if ((play_thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AACPlayThread,
+ (void *)&killPlayThread, 0, &thread_id)) == NULL)
+ {
+ show_error(hwndPlayer, "Cannot create playback thread");
+ faacDecClose(mp4state.hDecoder);
+ fclose(mp4state.aacfile);
+ return -1;
+ }
+ }
+ else
+ {
+ if ((play_thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MP4PlayThread,
+ (void *)&killPlayThread, 0, &thread_id)) == NULL)
+ {
+ show_error(hwndPlayer, "Cannot create playback thread");
+ faacDecClose(mp4state.hDecoder);
+ MP4Close(mp4state.mp4file);
+ return -1;
+ }
+ }
+
+ SetThreadAffinityMask(play_thread_handle, 1);
+
+ if (m_priority != 3)
+ SetThreadPriority(play_thread_handle, priority_table[m_priority]);
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+int Pause(const char* medianame, int flags)
+{
+#ifdef DEBUG_OUTPUT
+ in_mp4_DebugOutput("pause");
+#endif
+ if(QCDCallbacks->toPlayer.OutputPause(flags))
+ {
+ // send back pause/unpause notification
+ QCDCallbacks->toPlayer.PlayPaused(medianame, flags);
+ mp4state.paused = flags;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+
+void SetVolume(int levelleft, int levelright, int flags)
+{
+ QCDCallbacks->toPlayer.OutputSetVol(levelleft, levelright, flags);
+}
+
+//-----------------------------------------------------------------------------
+
+int GetCurrentPosition(const char* medianame, long *track, long *offset)
+{
+ return QCDCallbacks->toPlayer.OutputGetCurrentPosition((UINT*)offset, 0);
+}
+
+//-----------------------------------------------------------------------------
+
+int Stop(const char* medianame, int flags)
+{
+#ifdef DEBUG_OUTPUT
+ in_mp4_DebugOutput("stop");
+#endif
+ if(medianame && *medianame && stricmp(mp4state.filename, medianame) == 0)
+ {
+ sQCDCallbacks.toPlayer.OutputStop(flags);
+
+ killPlayThread = 1;
+ if(play_thread_handle != INVALID_HANDLE_VALUE)
+ {
+ if (WaitForSingleObject(play_thread_handle, INFINITE) == WAIT_TIMEOUT)
+ {
+// MessageBox(hwndPlayer, "MP4 thread kill timeout", "debug", 0);
+ TerminateThread(play_thread_handle,0);
+ }
+ CloseHandle(play_thread_handle);
+ play_thread_handle = INVALID_HANDLE_VALUE;
+ }
+
+ if (oldAPIs)
+ QCDCallbacks->toPlayer.PlayStopped(mp4state.filename);
+
+ mp4state.filename[0] = 0;
+ if(mp4state.hDecoder)
+ faacDecClose(mp4state.hDecoder);
+ if (mp4state.filetype)
+ fclose(mp4state.aacfile);
+ else
+ MP4Close(mp4state.mp4file);
+ }
+
+ return TRUE;
+}
+
+DWORD WINAPI MP4PlayThread(void *b)
+{
+ BOOL done = FALSE, updatePos = FALSE;
+ int l;
+
+ void *sample_buffer;
+ unsigned char *buffer;
+ int buffer_size, ms;
+ faacDecFrameInfo frameInfo;
+
+#ifdef DEBUG_OUTPUT
+ in_mp4_DebugOutput("MP4PlayThread");
+#endif
+
+ mp4state.last_frame = 0;
+
+ while (!*((int *)b))
+ {
+ /* seeking */
+ if (!done && mp4state.seek_needed != -1)
+ {
+ MP4Duration duration;
+
+ QCDCallbacks->toPlayer.OutputFlush(mp4state.decode_pos_ms);
+ duration = MP4ConvertToTrackDuration(mp4state.mp4file,
+ mp4state.mp4track, mp4state.seek_needed, MP4_MSECS_TIME_SCALE);
+ mp4state.sampleId = MP4GetSampleIdFromTime(mp4state.mp4file,
+ mp4state.mp4track, duration, 0);
+
+ mp4state.decode_pos_ms = mp4state.seek_needed;
+ mp4state.seek_needed = -1;
+ updatePos = TRUE;
+ }
+ /* quit */
+ if (done)
+ {
+ if (QCDCallbacks->toPlayer.OutputDrain(0) && !(mp4state.seek_needed >= 0))
+ {
+ play_thread_handle = INVALID_HANDLE_VALUE;
+ QCDCallbacks->toPlayer.OutputStop(STOPFLAG_PLAYDONE);
+ QCDCallbacks->toPlayer.PlayDone(mp4state.filename);
+ }
+ else if (mp4state.seek_needed >= 0)
+ {
+ done = FALSE;
+ continue;
+ }
+ break;
+ }
+ /* decoding */
+ else
+ {
+
+ if (mp4state.last_frame)
+ {
+ done = TRUE;
+ }
+ else
+ {
+ int rc;
+
+ /* get acces unit from MP4 file */
+ buffer = NULL;
+ buffer_size = 0;
+
+ rc = MP4ReadSample(mp4state.mp4file, mp4state.mp4track,
+ mp4state.sampleId++, &buffer, &buffer_size,
+ NULL, NULL, NULL, NULL);
+ if (rc == 0 || buffer == NULL)
+ {
+ mp4state.last_frame = 1;
+ sample_buffer = NULL;
+ frameInfo.samples = 0;
+ }
+ else
+ {
+ sample_buffer = faacDecDecode(mp4state.hDecoder, &frameInfo,
+ buffer, buffer_size);
+ }
+ if (frameInfo.error > 0)
+ {
+ show_error(hwndPlayer, faacDecGetErrorMessage(frameInfo.error));
+ mp4state.last_frame = 1;
+ }
+ if (mp4state.sampleId >= mp4state.numSamples)
+ mp4state.last_frame = 1;
+
+ if (buffer) free(buffer);
+
+ if (!killPlayThread && (frameInfo.samples > 0))
+ {
+ if (res_table[m_resolution] == 24)
+ {
+ /* convert libfaad output (3 bytes packed in 4) */
+ char *temp_buffer = convert3in4to3in3(sample_buffer, frameInfo.samples);
+ memcpy((void*)sample_buffer, (void*)temp_buffer, frameInfo.samples*3);
+ free(temp_buffer);
+ }
+
+ ms = (int)floor(((float)frameInfo.samples*1000.0) /
+ ((float)mp4state.samplerate*(float)frameInfo.channels));
+ mp4state.decode_pos_ms += ms;
+
+ l = frameInfo.samples * res_table[m_resolution] / 8;
+
+ if (updatePos)
+ {
+ QCDCallbacks->toPlayer.PositionUpdate(mp4state.decode_pos_ms);
+ updatePos = FALSE;
+ }
+ {
+ WriteDataStruct wd;
+
+ wd.bytelen = l;
+ wd.data = sample_buffer;
+ wd.markerend = 0;
+ wd.markerstart = mp4state.decode_pos_ms;
+ wd.bps = res_table[m_resolution];
+ wd.nch = frameInfo.channels;
+ wd.numsamples = frameInfo.samples/frameInfo.channels;
+ wd.srate = mp4state.samplerate;
+
+ if (!QCDCallbacks->toPlayer.OutputWrite(&wd))
+ done = TRUE;
+ }
+ }
+ }
+ }
+ Sleep(10);
+ }
+
+ // close up
+ play_thread_handle = INVALID_HANDLE_VALUE;
+
+ return 0;
+}
+
+DWORD WINAPI AACPlayThread(void *b)
+{
+ BOOL done = FALSE, updatePos = FALSE;
+ int l, ms;
+
+ void *sample_buffer;
+ faacDecFrameInfo frameInfo;
+
+#ifdef DEBUG_OUTPUT
+ in_mp4_DebugOutput("AACPlayThread");
+#endif
+
+ mp4state.last_frame = 0;
+
+ while (!*((int *)b))
+ {
+#if 0
+ /* seeking */
+ if (!done && mp4state.seek_needed != -1)
+ {
+ int ms;
+
+ /* Round off to a second */
+ ms = mp4state.seek_needed - (mp4state.seek_needed%1000);
+ QCDCallbacks->toPlayer.OutputFlush(mp4state.decode_pos_ms);
+ aac_seek(ms);
+ mp4state.decode_pos_ms = ms;
+ mp4state.seek_needed = -1;
+ updatePos = TRUE;
+ }
+#endif
+ /* quit */
+ if (done)
+ {
+ if (QCDCallbacks->toPlayer.OutputDrain(0) && !(mp4state.seek_needed >= 0))
+ {
+ QCDCallbacks->toPlayer.OutputStop(STOPFLAG_PLAYDONE);
+ QCDCallbacks->toPlayer.PlayDone(mp4state.filename);
+ }
+ else if (mp4state.seek_needed >= 0)
+ {
+ done = FALSE;
+ continue;
+ }
+ break;
+ }
+
+ /* decoding */
+ else
+ {
+ if (mp4state.last_frame)
+ {
+ done = TRUE;
+ }
+ else
+ {
+ long tmp, read;
+ unsigned char *buffer = mp4state.buffer;
+
+ do
+ {
+ if (mp4state.bytes_consumed > 0)
+ {
+ if (mp4state.bytes_into_buffer)
+ {
+ memcpy(buffer, buffer+mp4state.bytes_consumed,
+ mp4state.bytes_into_buffer);
+ }
+
+ if (mp4state.bytes_read < mp4state.filesize)
+ {
+ if (mp4state.bytes_read + mp4state.bytes_consumed < mp4state.filesize)
+ tmp = mp4state.bytes_consumed;
+ else
+ tmp = mp4state.filesize - mp4state.bytes_read;
+ read = fread(buffer + mp4state.bytes_into_buffer, 1, tmp, mp4state.aacfile);
+ if (read == tmp)
+ {
+ mp4state.bytes_read += read;
+ mp4state.bytes_into_buffer += read;
+ }
+ }
+ else
+ {
+ if (mp4state.bytes_into_buffer)
+ {
+ memset(buffer + mp4state.bytes_into_buffer, 0,
+ mp4state.bytes_consumed);
+ }
+ }
+
+ mp4state.bytes_consumed = 0;
+ }
+
+ if (mp4state.bytes_into_buffer < 1)
+ {
+ if (mp4state.bytes_read < mp4state.filesize)
+ {
+ show_error(hwndPlayer, faacDecGetErrorMessage(frameInfo.error));
+ mp4state.last_frame = 1;
+ }
+ else
+ {
+ mp4state.last_frame = 1;
+ }
+ }
+
+ sample_buffer = faacDecDecode(mp4state.hDecoder, &frameInfo,
+ buffer, mp4state.bytes_into_buffer);
+
+ mp4state.bytes_consumed += frameInfo.bytesconsumed;
+ mp4state.bytes_into_buffer -= mp4state.bytes_consumed;
+ } while (!frameInfo.samples && !frameInfo.error);
+
+ if (!killPlayThread && (frameInfo.samples > 0))
+ {
+ if (res_table[m_resolution] == 24)
+ {
+ /* convert libfaad output (3 bytes packed in 4 bytes) */
+ char *temp_buffer = convert3in4to3in3(sample_buffer, frameInfo.samples);
+ memcpy((void*)sample_buffer, (void*)temp_buffer, frameInfo.samples*3);
+ free(temp_buffer);
+ }
+
+ ms = (int)floor(((float)frameInfo.samples*1000.0) /
+ ((float)mp4state.samplerate*(float)frameInfo.channels));
+ mp4state.decode_pos_ms += ms;
+
+ l = frameInfo.samples * res_table[m_resolution] / 8;
+
+ if (updatePos)
+ {
+ QCDCallbacks->toPlayer.PositionUpdate(mp4state.decode_pos_ms);
+ updatePos = FALSE;
+ }
+ {
+ WriteDataStruct wd;
+
+ wd.bytelen = l;
+ wd.data = sample_buffer;
+ wd.markerend = 0;
+ wd.markerstart = mp4state.decode_pos_ms;
+ wd.bps = res_table[m_resolution];
+ wd.nch = frameInfo.channels;
+ wd.numsamples = frameInfo.samples/frameInfo.channels;
+ wd.srate = mp4state.samplerate;
+
+ if (!QCDCallbacks->toPlayer.OutputWrite(&wd))
+ done = TRUE;
+ }
+ }
+ }
+ }
+ Sleep(10);
+ }
+
+ // close up
+ play_thread_handle = INVALID_HANDLE_VALUE;
+
+ return 0;
+}
--- /dev/null
+++ b/plugins/QCDMp4/QCDMp4.dsp
@@ -1,0 +1,183 @@
+# Microsoft Developer Studio Project File - Name="QCDMp4" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=QCDMp4 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "QCDMp4.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "QCDMp4.mak" CFG="QCDMp4 - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "QCDMp4 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "QCDMp4 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "QCDMp4 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /I "..\..\common\mp4v2" /I "..\..\common\mp4av" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x413 /d "NDEBUG"
+# ADD RSC /l 0x413 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+
+!ELSEIF "$(CFG)" == "QCDMp4 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "..\..\common\mp4v2" /I "..\..\common\mp4av" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x413 /d "_DEBUG"
+# ADD RSC /l 0x413 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "QCDMp4 - Win32 Release"
+# Name "QCDMp4 - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\aac2mp4.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AAC2Mp4Enc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\aacinfo.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\config.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDMp4.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\utils.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\aac2mp4.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\aacinfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\config.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\faad.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbs.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDConvertDLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDInputDLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDModDefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDModEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDModInput.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\utils.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\logo.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\QCDMp4.rc
+# End Source File
+# End Group
+# End Target
+# End Project
--- /dev/null
+++ b/plugins/QCDMp4/QCDMp4.dsw
@@ -1,0 +1,74 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "QCDMp4"=".\QCDMp4.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name libfaad
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name libmp4av_st
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name libmp4v2_st
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "libfaad"="..\..\libfaad\libfaad.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "libmp4av_st"="..\..\common\mp4av\libmp4av_st.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "libmp4v2_st"="..\..\common\mp4v2\libmp4v2_st60.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+++ b/plugins/QCDMp4/QCDMp4.rc
@@ -1,0 +1,170 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Dutch (Netherlands) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NLD)
+#ifdef _WIN32
+LANGUAGE LANG_DUTCH, SUBLANG_DUTCH
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_CONFIG_INPUT DIALOG DISCARDABLE 0, 0, 151, 108
+STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Configuration"
+FONT 8, "MS Sans Serif"
+BEGIN
+ CONTROL "Slider1",IDC_PRIORITY,"msctls_trackbar32",TBS_VERT |
+ TBS_NOTICKS | WS_TABSTOP,13,15,18,46
+ CONTROL "16 bits",IDC_16BITS,"Button",BS_AUTORADIOBUTTON,77,18,
+ 37,10
+ CONTROL "16 bits dithered",IDC_16BITS_DITHERED,"Button",
+ BS_AUTORADIOBUTTON,77,29,64,10
+ CONTROL "24 bits",IDC_24BITS,"Button",BS_AUTORADIOBUTTON,77,40,
+ 37,10
+ CONTROL "32 bits",IDC_32BITS,"Button",BS_AUTORADIOBUTTON,77,51,
+ 37,10
+ CONTROL "Show errors",IDC_ERROR,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,7,70,53,10
+ CONTROL "Use for AAC",IDC_USEFORAAC,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,78,70,55,10
+ PUSHBUTTON "Cancel",IDCANCEL,7,87,50,14
+ DEFPUSHBUTTON "OK",IDOK,94,87,50,14
+ GROUPBOX "Priority",IDC_STATIC,7,7,57,58
+ LTEXT "Highest",IDC_STATIC,34,18,25,8
+ LTEXT "Normal",IDC_STATIC,34,35,23,8
+ LTEXT "Lowest",IDC_STATIC,34,52,24,8
+ GROUPBOX "Resolution",IDC_STATIC,71,7,73,58
+END
+
+IDD_CONFIG_CONVERT DIALOG DISCARDABLE 0, 0, 306, 143
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "AAC to Mp4 Converter Setting"
+FONT 8, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "&OK",IDOK,127,122,50,14
+ PUSHBUTTON "Select Oupput Folder",IDC_OUTPUTFOLDER,16,19,277,20
+ GROUPBOX "Ouput Folder",IDC_STATIC,7,7,292,39
+ CONTROL "You can convert AAC files to Mp4 files if you like.\n\nThis does not involve re-encoding, only the container format is changed.\n\nAdvantage Mp4 files are playable by a lot more players\nand they will have a lot of support in the future. ",
+ IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,7,62,
+ 292,51
+END
+
+IDD_ABOUT DIALOG DISCARDABLE 0, 0, 191, 190
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About MPEG-4 Plug-in"
+FONT 8, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,69,168,50,14
+ CTEXT "",IDC_PLUGINVER,29,94,133,16
+ CTEXT "",IDC_FAADVER,39,144,111,8
+ LTEXT "QCD Input Plug-in by",IDC_STATIC,61,118,67,8
+ CONTROL 105,IDC_LOGO,"Static",SS_BITMAP | SS_CENTERIMAGE |
+ SS_REALSIZEIMAGE,7,0,177,68
+ LTEXT "Shao Hao",IDC_MAIL1,78,132,33,8
+ LTEXT "M. Bakker",IDC_MAIL3,58,155,34,8
+ LTEXT "menno",IDC_MAIL2,108,155,22,8
+ LTEXT "&&",IDC_STATIC,96,155,8,8
+ CTEXT "AudioCoding.com MPEG-4 General Audio player\nCopyright 2002 AudioCoding.com",
+ IDC_STATIC,7,72,177,18
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO MOVEABLE PURE
+BEGIN
+ IDD_CONFIG_INPUT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 144
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 101
+ END
+
+ IDD_CONFIG_CONVERT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 299
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 136
+ END
+
+ IDD_ABOUT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 184
+ BOTTOMMARGIN, 183
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_LOGO BITMAP DISCARDABLE "logo.bmp"
+#endif // Dutch (Netherlands) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
--- /dev/null
+++ b/plugins/QCDMp4/QCDMp4.sln
@@ -1,0 +1,42 @@
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "in_mp4", "in_mp4.vcproj", "{2D8F479D-A591-4502-9456-398425D5F834}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaad", "..\..\libfaad\libfaad.vcproj", "{82CAD808-21AF-40A6-92EC-AE01AA67B413}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmp4v2_st", "..\..\common\mp4v2\libmp4v2_st60.vcproj", "{2398BB2F-FFF9-490B-B4CC-863F2D21AE46}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmp4av_st", "..\..\common\mp4av\libmp4av_st.vcproj", "{8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}"
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ ConfigName.0 = Debug
+ ConfigName.1 = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ {2D8F479D-A591-4502-9456-398425D5F834}.0 = {82CAD808-21AF-40A6-92EC-AE01AA67B413}
+ {2D8F479D-A591-4502-9456-398425D5F834}.1 = {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}
+ {2D8F479D-A591-4502-9456-398425D5F834}.2 = {2398BB2F-FFF9-490B-B4CC-863F2D21AE46}
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {2D8F479D-A591-4502-9456-398425D5F834}.Debug.ActiveCfg = Debug|Win32
+ {2D8F479D-A591-4502-9456-398425D5F834}.Debug.Build.0 = Debug|Win32
+ {2D8F479D-A591-4502-9456-398425D5F834}.Release.ActiveCfg = Release|Win32
+ {2D8F479D-A591-4502-9456-398425D5F834}.Release.Build.0 = Release|Win32
+ {82CAD808-21AF-40A6-92EC-AE01AA67B413}.Debug.ActiveCfg = Debug|Win32
+ {82CAD808-21AF-40A6-92EC-AE01AA67B413}.Debug.Build.0 = Debug|Win32
+ {82CAD808-21AF-40A6-92EC-AE01AA67B413}.Release.ActiveCfg = Release|Win32
+ {82CAD808-21AF-40A6-92EC-AE01AA67B413}.Release.Build.0 = Release|Win32
+ {2398BB2F-FFF9-490B-B4CC-863F2D21AE46}.Debug.ActiveCfg = Debug|Win32
+ {2398BB2F-FFF9-490B-B4CC-863F2D21AE46}.Debug.Build.0 = Debug|Win32
+ {2398BB2F-FFF9-490B-B4CC-863F2D21AE46}.Release.ActiveCfg = Release|Win32
+ {2398BB2F-FFF9-490B-B4CC-863F2D21AE46}.Release.Build.0 = Release|Win32
+ {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}.Debug.ActiveCfg = Debug|Win32
+ {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}.Debug.Build.0 = Debug|Win32
+ {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}.Release.ActiveCfg = Release|Win32
+ {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
--- /dev/null
+++ b/plugins/QCDMp4/QCDMp4.vcproj
@@ -1,0 +1,200 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.00"
+ Name="in_mp4"
+ SccProjectName=""
+ SccLocalPath="">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include,..\..\common\mp4v2,..\..\common\mp4av"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Debug/in_mp4.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0">
+ <IntelOptions
+ Optimization="0"
+ MinimalRebuild="1"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="1"
+ AllOptions="/c /I "..\..\include" /I "..\..\common\mp4v2" /I "..\..\common\mp4av" /ZI /nologo /W3 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_WINDLL" /Gm /EHsc /MTd /YX"StdAfx.h" /Fp".\Debug/in_mp4.pch" /Fo".\Debug/" /Fd".\Debug/" /Gd"/>
+ </Tool>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="ws2_32.lib odbc32.lib odbccp32.lib"
+ OutputFile=".\Debug/in_mp4.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="TRUE"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile=".\Debug/in_mp4.pdb"
+ SubSystem="2"
+ ImportLibrary=".\Debug/in_mp4.lib">
+ <IntelOptions
+ AllOptions="/NOLOGO /DLL /OUT:".\Debug/in_mp4.dll" /INCREMENTAL ws2_32.lib odbc32.lib odbccp32.lib /DEBUG /PDB:".\Debug/in_mp4.pdb" /SUBSYSTEM:WINDOWS /TLBID:1 /IMPLIB:".\Debug/in_mp4.lib" /MACHINE:I386 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"/>
+ </Tool>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/in_mp4.tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1043"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="1"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories="..\..\include,..\..\common\mp4v2,..\..\common\mp4av"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Release/in_mp4.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="0">
+ <IntelOptions
+ Optimization="2"
+ GlobalOptimizations="1"
+ InlineFuncExpansion="1"
+ OmitFramePtrs="1"
+ StringPooling="1"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="1"
+ FunctionLevelLinking="1"
+ AllOptions="/c /I "..\..\include" /I "..\..\common\mp4v2" /I "..\..\common\mp4av" /nologo /W3 /O2 /Og /Ob1 /Oy /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /GF /FD /EHsc /MT /GS /Gy /YX"StdAfx.h" /Fp".\Release/in_mp4.pch" /Fo".\Release/" /Fd".\Release/" /Gd"/>
+ </Tool>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile=".\Release/in_mp4.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ ProgramDatabaseFile=".\Release/in_mp4.pdb"
+ SubSystem="2"
+ ImportLibrary=".\Release/in_mp4.lib">
+ <IntelOptions
+ AllOptions="/NOLOGO /DLL /OUT:".\Release/in_mp4.dll" /INCREMENTAL:NO ws2_32.lib /PDB:".\Release/in_mp4.pdb" /SUBSYSTEM:WINDOWS /TLBID:1 /IMPLIB:".\Release/in_mp4.lib" /MACHINE:I386 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"/>
+ </Tool>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/in_mp4.tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1043"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ <File
+ RelativePath="aac2mp4.cpp"/>
+ <File
+ RelativePath="aacinfo.c"/>
+ <File
+ RelativePath=".\config.c"/>
+ <File
+ RelativePath=".\in_mp4.c"/>
+ <File
+ RelativePath=".\utils.c"/>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl">
+ <File
+ RelativePath="aac2mp4.h"/>
+ <File
+ RelativePath="aacinfo.h"/>
+ <File
+ RelativePath=".\config.h"/>
+ <File
+ RelativePath="..\..\include\faad.h"/>
+ <File
+ RelativePath=".\in2.h"/>
+ <File
+ RelativePath=".\out.h"/>
+ <File
+ RelativePath="resource.h"/>
+ <File
+ RelativePath=".\utils.h"/>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ <File
+ RelativePath=".\in_mp4.rc"/>
+ </Filter>
+ </Files>
+ <Globals/>
+</VisualStudioProject>
--- /dev/null
+++ b/plugins/QCDMp4/aac2mp4.cpp
@@ -1,0 +1,313 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: aac2mp4.cpp,v 1.1 2003/04/28 19:07:57 menno Exp $
+**/
+
+#include <mpeg4ip.h>
+#include <mp4.h>
+#include <mp4av.h>
+
+#include "aac2mp4.h"
+
+int covert_aac_to_mp4(char *inputFileName, char *mp4FileName)
+{
+ int Mp4TimeScale = 90000;
+ int allMpeg4Streams = 0;
+ MP4FileHandle mp4File;
+ FILE* inFile;
+ const char *type;
+ MP4TrackId createdTrackId = MP4_INVALID_TRACK_ID;
+
+ mp4File = MP4Create(mp4FileName, 0, 0, 0);
+ if (mp4File)
+ {
+ MP4SetTimeScale(mp4File, Mp4TimeScale);
+ } else {
+ return 1;
+ }
+
+ inFile = fopen(inputFileName, "rb");
+
+ if (inFile == NULL)
+ {
+ MP4Close(mp4File);
+ return 2;
+ }
+
+ createdTrackId = AacCreator(mp4File, inFile);
+
+ if (createdTrackId == MP4_INVALID_TRACK_ID)
+ {
+ fclose(inFile);
+ MP4Close(mp4File);
+ return 3;
+ }
+
+ type = MP4GetTrackType(mp4File, createdTrackId);
+
+ if (!strcmp(type, MP4_AUDIO_TRACK_TYPE))
+ {
+ allMpeg4Streams &=
+ (MP4GetTrackAudioType(mp4File, createdTrackId)
+ == MP4_MPEG4_AUDIO_TYPE);
+ }
+
+ if (inFile)
+ {
+ fclose(inFile);
+ }
+
+ MP4Close(mp4File);
+ MP4MakeIsmaCompliant(mp4FileName, 0, allMpeg4Streams);
+
+ return 0;
+}
+
+#define ADTS_HEADER_MAX_SIZE 10 /* bytes */
+
+static u_int8_t firstHeader[ADTS_HEADER_MAX_SIZE];
+
+/*
+ * hdr must point to at least ADTS_HEADER_MAX_SIZE bytes of memory
+ */
+static bool LoadNextAdtsHeader(FILE* inFile, u_int8_t* hdr)
+{
+ u_int state = 0;
+ u_int dropped = 0;
+ u_int hdrByteSize = ADTS_HEADER_MAX_SIZE;
+
+ while (1) {
+ /* read a byte */
+ u_int8_t b;
+
+ if (fread(&b, 1, 1, inFile) == 0) {
+ return false;
+ }
+
+ /* header is complete, return it */
+ if (state == hdrByteSize - 1) {
+ hdr[state] = b;
+ if (dropped > 0) {
+ fprintf(stderr, "Warning: dropped %u input bytes\n", dropped);
+ }
+ return true;
+ }
+
+ /* collect requisite number of bytes, no constraints on data */
+ if (state >= 2) {
+ hdr[state++] = b;
+ } else {
+ /* have first byte, check if we have 1111X00X */
+ if (state == 1) {
+ if ((b & 0xF6) == 0xF0) {
+ hdr[state] = b;
+ state = 2;
+ /* compute desired header size */
+ hdrByteSize = MP4AV_AdtsGetHeaderByteSize(hdr);
+ } else {
+ state = 0;
+ }
+ }
+ /* initial state, looking for 11111111 */
+ if (state == 0) {
+ if (b == 0xFF) {
+ hdr[state] = b;
+ state = 1;
+ } else {
+ /* else drop it */
+ dropped++;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Load the next frame from the file
+ * into the supplied buffer, which better be large enough!
+ *
+ * Note: Frames are padded to byte boundaries
+ */
+static bool LoadNextAacFrame(FILE* inFile, u_int8_t* pBuf, u_int32_t* pBufSize, bool stripAdts)
+{
+ u_int16_t frameSize;
+ u_int16_t hdrBitSize, hdrByteSize;
+ u_int8_t hdrBuf[ADTS_HEADER_MAX_SIZE];
+
+ /* get the next AAC frame header, more or less */
+ if (!LoadNextAdtsHeader(inFile, hdrBuf)) {
+ return false;
+ }
+
+ /* get frame size from header */
+ frameSize = MP4AV_AdtsGetFrameSize(hdrBuf);
+
+ /* get header size in bits and bytes from header */
+ hdrBitSize = MP4AV_AdtsGetHeaderBitSize(hdrBuf);
+ hdrByteSize = MP4AV_AdtsGetHeaderByteSize(hdrBuf);
+
+ /* adjust the frame size to what remains to be read */
+ frameSize -= hdrByteSize;
+
+ if (stripAdts) {
+ if ((hdrBitSize % 8) == 0) {
+ /* header is byte aligned, i.e. MPEG-2 ADTS */
+ /* read the frame data into the buffer */
+ if (fread(pBuf, 1, frameSize, inFile) != frameSize) {
+ return false;
+ }
+ (*pBufSize) = frameSize;
+ } else {
+ /* header is not byte aligned, i.e. MPEG-4 ADTS */
+ int i;
+ u_int8_t newByte;
+ int upShift = hdrBitSize % 8;
+ int downShift = 8 - upShift;
+
+ pBuf[0] = hdrBuf[hdrBitSize / 8] << upShift;
+
+ for (i = 0; i < frameSize; i++) {
+ if (fread(&newByte, 1, 1, inFile) != 1) {
+ return false;
+ }
+ pBuf[i] |= (newByte >> downShift);
+ pBuf[i+1] = (newByte << upShift);
+ }
+ (*pBufSize) = frameSize + 1;
+ }
+ } else { /* don't strip ADTS headers */
+ memcpy(pBuf, hdrBuf, hdrByteSize);
+ if (fread(&pBuf[hdrByteSize], 1, frameSize, inFile) != frameSize) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool GetFirstHeader(FILE* inFile)
+{
+ /* read file until we find an audio frame */
+ fpos_t curPos;
+
+ /* already read first header */
+ if (firstHeader[0] == 0xff) {
+ return true;
+ }
+
+ /* remember where we are */
+ fgetpos(inFile, &curPos);
+
+ /* go back to start of file */
+ rewind(inFile);
+
+ if (!LoadNextAdtsHeader(inFile, firstHeader)) {
+ return false;
+ }
+
+ /* reposition the file to where we were */
+ fsetpos(inFile, &curPos);
+
+ return true;
+}
+
+MP4TrackId AacCreator(MP4FileHandle mp4File, FILE* inFile)
+{
+ // collect all the necessary meta information
+ u_int32_t samplesPerSecond;
+ u_int8_t mpegVersion;
+ u_int8_t profile;
+ u_int8_t channelConfig;
+
+ if (!GetFirstHeader(inFile)) {
+ return MP4_INVALID_TRACK_ID;
+ }
+
+ samplesPerSecond = MP4AV_AdtsGetSamplingRate(firstHeader);
+ mpegVersion = MP4AV_AdtsGetVersion(firstHeader);
+ profile = MP4AV_AdtsGetProfile(firstHeader);
+ channelConfig = MP4AV_AdtsGetChannels(firstHeader);
+
+ u_int8_t audioType = MP4_INVALID_AUDIO_TYPE;
+ switch (mpegVersion) {
+ case 0:
+ audioType = MP4_MPEG4_AUDIO_TYPE;
+ break;
+ case 1:
+ switch (profile) {
+ case 0:
+ audioType = MP4_MPEG2_AAC_MAIN_AUDIO_TYPE;
+ break;
+ case 1:
+ audioType = MP4_MPEG2_AAC_LC_AUDIO_TYPE;
+ break;
+ case 2:
+ audioType = MP4_MPEG2_AAC_SSR_AUDIO_TYPE;
+ break;
+ case 3:
+ return MP4_INVALID_TRACK_ID;
+ }
+ break;
+ }
+
+ // add the new audio track
+ MP4TrackId trackId =
+ MP4AddAudioTrack(mp4File,
+ samplesPerSecond, 1024, audioType);
+
+ if (trackId == MP4_INVALID_TRACK_ID) {
+ return MP4_INVALID_TRACK_ID;
+ }
+
+ if (MP4GetNumberOfTracks(mp4File, MP4_AUDIO_TRACK_TYPE) == 1) {
+ MP4SetAudioProfileLevel(mp4File, 0x0F);
+ }
+
+ u_int8_t* pConfig = NULL;
+ u_int32_t configLength = 0;
+
+ MP4AV_AacGetConfiguration(
+ &pConfig,
+ &configLength,
+ profile,
+ samplesPerSecond,
+ channelConfig);
+
+ if (!MP4SetTrackESConfiguration(mp4File, trackId,
+ pConfig, configLength)) {
+ MP4DeleteTrack(mp4File, trackId);
+ return MP4_INVALID_TRACK_ID;
+ }
+
+ // parse the ADTS frames, and write the MP4 samples
+ u_int8_t sampleBuffer[8 * 1024];
+ u_int32_t sampleSize = sizeof(sampleBuffer);
+ MP4SampleId sampleId = 1;
+
+ while (LoadNextAacFrame(inFile, sampleBuffer, &sampleSize, true)) {
+ if (!MP4WriteSample(mp4File, trackId, sampleBuffer, sampleSize)) {
+ MP4DeleteTrack(mp4File, trackId);
+ return MP4_INVALID_TRACK_ID;
+ }
+ sampleId++;
+ sampleSize = sizeof(sampleBuffer);
+ }
+
+ return trackId;
+}
--- /dev/null
+++ b/plugins/QCDMp4/aac2mp4.h
@@ -1,0 +1,36 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: aac2mp4.h,v 1.1 2003/04/28 19:07:57 menno Exp $
+**/
+
+#ifndef AAC2MP4_H__
+#define AAC2MP4_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int covert_aac_to_mp4(char *inputFileName, char *mp4FileName);
+MP4TrackId AacCreator(MP4FileHandle mp4File, FILE* inFile);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+++ b/plugins/QCDMp4/aacinfo.c
@@ -1,0 +1,220 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: aacinfo.c,v 1.1 2003/04/28 19:07:57 menno Exp $
+**/
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "aacinfo.h"
+#include "utils.h"
+
+#define ADIF_MAX_SIZE 30 /* Should be enough */
+#define ADTS_MAX_SIZE 10 /* Should be enough */
+
+static int sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};
+
+static int read_ADIF_header(FILE *file, faadAACInfo *info)
+{
+ int bitstream;
+ unsigned char buffer[ADIF_MAX_SIZE];
+ int skip_size = 0;
+ int sf_idx;
+
+ /* Get ADIF header data */
+ info->headertype = 1;
+
+ if (fread(buffer, 1, ADIF_MAX_SIZE, file) != ADIF_MAX_SIZE)
+ return -1;
+
+ /* copyright string */
+ if(buffer[0] & 0x80)
+ skip_size += 9; /* skip 9 bytes */
+
+ bitstream = buffer[0 + skip_size] & 0x10;
+ info->bitrate = ((unsigned int)(buffer[0 + skip_size] & 0x0F)<<19)|
+ ((unsigned int)buffer[1 + skip_size]<<11)|
+ ((unsigned int)buffer[2 + skip_size]<<3)|
+ ((unsigned int)buffer[3 + skip_size] & 0xE0);
+
+ if (bitstream == 0)
+ {
+ info->object_type = ((buffer[6 + skip_size]&0x01)<<1)|((buffer[7 + skip_size]&0x80)>>7);
+ sf_idx = (buffer[7 + skip_size]&0x78)>>3;
+ } else {
+ info->object_type = (buffer[4 + skip_size] & 0x18)>>3;
+ sf_idx = ((buffer[4 + skip_size] & 0x07)<<1)|((buffer[5 + skip_size] & 0x80)>>7);
+ }
+ info->sampling_rate = sample_rates[sf_idx];
+
+ return 0;
+}
+
+static int read_ADTS_header(FILE *file, faadAACInfo *info)
+{
+ /* Get ADTS header data */
+ unsigned char buffer[ADTS_MAX_SIZE];
+ int frames, t_framelength = 0, frame_length, sr_idx = 0, ID;
+ int second = 0, pos;
+ float frames_per_sec = 0;
+ unsigned long bytes;
+ unsigned long *tmp_seek_table = NULL;
+
+ info->headertype = 2;
+
+ /* Read all frames to ensure correct time and bitrate */
+ for (frames = 0; /* */; frames++)
+ {
+ bytes = fread(buffer, 1, ADTS_MAX_SIZE, file);
+
+ if (bytes != ADTS_MAX_SIZE)
+ break;
+
+ /* check syncword */
+ if (!((buffer[0] == 0xFF)&&((buffer[1] & 0xF6) == 0xF0)))
+ break;
+
+ if (!frames)
+ {
+ /* fixed ADTS header is the same for every frame, so we read it only once */
+ /* Syncword found, proceed to read in the fixed ADTS header */
+ ID = buffer[1] & 0x08;
+ info->object_type = (buffer[2]&0xC0)>>6;
+ sr_idx = (buffer[2]&0x3C)>>2;
+ info->channels = ((buffer[2]&0x01)<<2)|((buffer[3]&0xC0)>>6);
+
+ frames_per_sec = sample_rates[sr_idx] / 1024.f;
+ }
+
+ /* ...and the variable ADTS header */
+ if (ID == 0)
+ {
+ info->version = 4;
+ frame_length = (((unsigned int)buffer[4]) << 5) |
+ ((unsigned int)buffer[5] >> 3);
+ } else { /* MPEG-2 */
+ info->version = 2;
+ frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11)
+ | (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5);
+ }
+
+ t_framelength += frame_length;
+
+ pos = ftell(file) - ADTS_MAX_SIZE;
+
+ fseek(file, frame_length - ADTS_MAX_SIZE, SEEK_CUR);
+ }
+
+ if (frames > 0)
+ {
+ float sec_per_frame, bytes_per_frame;
+ info->sampling_rate = sample_rates[sr_idx];
+ sec_per_frame = (float)info->sampling_rate/1024.0;
+ bytes_per_frame = (float)t_framelength / (float)frames;
+ info->bitrate = 8 * (int)floor(bytes_per_frame * sec_per_frame);
+ info->length = (int)floor((float)frames/frames_per_sec)*1000;
+ } else {
+ info->sampling_rate = 4;
+ info->bitrate = 128000;
+ info->length = 0;
+ info->channels = 0;
+ }
+
+ return 0;
+}
+
+int get_AAC_format(char *filename, faadAACInfo *info)
+{
+ unsigned long tagsize;
+ FILE *file;
+ char buffer[10];
+ unsigned long file_len;
+ unsigned char adxx_id[5];
+ unsigned long tmp;
+
+ memset(info, 0, sizeof(faadAACInfo));
+
+ file = fopen(filename, "rb");
+
+ if(file == NULL)
+ return -1;
+
+ fseek(file, 0, SEEK_END);
+ file_len = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /* Skip the tag, if it's there */
+ tmp = fread(buffer, 10, 1, file);
+
+ if (StringComp(buffer, "ID3", 3) == 0)
+ {
+ /* high bit is not used */
+ tagsize = (buffer[6] << 21) | (buffer[7] << 14) |
+ (buffer[8] << 7) | (buffer[9] << 0);
+
+ fseek(file, tagsize, SEEK_CUR);
+ tagsize += 10;
+ } else {
+ tagsize = 0;
+ fseek(file, 0, SEEK_SET);
+ }
+
+ if (file_len)
+ file_len -= tagsize;
+
+ tmp = fread(adxx_id, 2, 1, file);
+ adxx_id[5-1] = 0;
+ info->length = 0;
+
+ /* Determine the header type of the file, check the first two bytes */
+ if (StringComp(adxx_id, "AD", 2) == 0)
+ {
+ /* We think its an ADIF header, but check the rest just to make sure */
+ tmp = fread(adxx_id + 2, 2, 1, file);
+
+ if (StringComp(adxx_id, "ADIF", 4) == 0)
+ {
+ read_ADIF_header(file, info);
+
+ info->length = (int)((float)file_len*8000.0/((float)info->bitrate));
+ }
+ } else {
+ /* No ADIF, check for ADTS header */
+ if ((adxx_id[0] == 0xFF)&&((adxx_id[1] & 0xF6) == 0xF0))
+ {
+ /* ADTS header located */
+ fseek(file, tagsize, SEEK_SET);
+ read_ADTS_header(file, info);
+ } else {
+ /* Unknown/headerless AAC file, assume format: */
+ info->version = 2;
+ info->bitrate = 128000;
+ info->sampling_rate = 44100;
+ info->channels = 2;
+ info->headertype = 0;
+ info->object_type = 1;
+ }
+ }
+
+ fclose(file);
+
+ return 0;
+}
--- /dev/null
+++ b/plugins/QCDMp4/aacinfo.h
@@ -1,0 +1,40 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: aacinfo.h,v 1.1 2003/04/28 19:07:57 menno Exp $
+**/
+
+#ifndef AACINFO_INCLUDED
+#define AACINFO_INCLUDED
+
+typedef struct {
+ int version;
+ int channels;
+ int sampling_rate;
+ int bitrate;
+ int length;
+ int object_type;
+ int headertype;
+} faadAACInfo;
+
+int get_AAC_format(char *filename, faadAACInfo *info);
+
+static int read_ADIF_header(FILE *file, faadAACInfo *info);
+static int read_ADTS_header(FILE *file, faadAACInfo *info);
+
+#endif
--- /dev/null
+++ b/plugins/QCDMp4/config.c
@@ -1,0 +1,39 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: config.c,v 1.1 2003/04/28 19:07:57 menno Exp $
+**/
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include "config.h"
+
+char app_name[] = "QCDMp4";
+char INI_FILE[MAX_PATH];
+int m_priority = 3;
+int m_resolution = 0;
+int m_show_errors = 1;
+int m_use_for_aac = 1;
+
+void _r_s(char *name,char *data, int mlen)
+{
+ char buf[10];
+ strcpy(buf,data);
+ GetPrivateProfileString(app_name,name,buf,data,mlen,INI_FILE);
+}
+
--- /dev/null
+++ b/plugins/QCDMp4/config.h
@@ -1,0 +1,33 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: config.h,v 1.1 2003/04/28 19:07:57 menno Exp $
+**/
+
+extern char app_name[];
+extern char INI_FILE[];
+int m_priority;
+int m_resolution;
+int m_show_errors;
+int m_use_for_aac;
+
+#define RS(x) (_r_s(#x,x,sizeof(x)))
+#define WS(x) (WritePrivateProfileString(app_name,#x,x,INI_FILE))
+
+extern void _r_s(char *name,char *data, int mlen);
+
binary files /dev/null b/plugins/QCDMp4/logo.bmp differ
--- /dev/null
+++ b/plugins/QCDMp4/mbs.h
@@ -1,0 +1,81 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is MPEG4IP.
+ *
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2001-2002. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Dave Mackie dmackie@cisco.com
+ */
+
+#ifndef __MBS_INCLUDED__
+#define __MBS_INCLUDED__
+
+class CMemoryBitstream {
+public:
+ CMemoryBitstream() {
+ m_pBuf = NULL;
+ m_bitPos = 0;
+ m_numBits = 0;
+ }
+
+ void AllocBytes(u_int32_t numBytes);
+
+ void SetBytes(u_int8_t* pBytes, u_int32_t numBytes);
+
+ void PutBytes(u_int8_t* pBytes, u_int32_t numBytes);
+
+ void PutBits(u_int32_t bits, u_int32_t numBits);
+
+ u_int32_t GetBits(u_int32_t numBits);
+
+ void SkipBytes(u_int32_t numBytes) {
+ SkipBits(numBytes << 3);
+ }
+
+ void SkipBits(u_int32_t numBits) {
+ SetBitPosition(GetBitPosition() + numBits);
+ }
+
+ u_int32_t GetBitPosition() {
+ return m_bitPos;
+ }
+
+ void SetBitPosition(u_int32_t bitPos) {
+ if (bitPos > m_numBits) {
+ throw;
+ }
+ m_bitPos = bitPos;
+ }
+
+ u_int8_t* GetBuffer() {
+ return m_pBuf;
+ }
+
+ u_int32_t GetNumberOfBytes() {
+ return (GetNumberOfBits() + 7) / 8;
+ }
+
+ u_int32_t GetNumberOfBits() {
+ return m_numBits;
+ }
+
+protected:
+ u_int8_t* m_pBuf;
+ u_int32_t m_bitPos;
+ u_int32_t m_numBits;
+};
+
+#endif /* __MBS_INCLUDED__ */
+
--- /dev/null
+++ b/plugins/QCDMp4/resource.h
@@ -1,0 +1,51 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by QCDMp4.rc
+//
+#define IDD_INFO 101
+#define IDD_CONFIG 102
+#define IDD_CONFIG_INPUT 102
+#define IDD_ABOUT 103
+#define IDD_CONFIG_CONVERT 104
+#define IDB_LOGO 105
+#define IDC_TYPE 1000
+#define IDC_INFOTEXT 1000
+#define IDC_DURATION 1001
+#define IDC_BITRATE 1002
+#define IDC_SAMPLERATE 1003
+#define IDC_VTYPE 1004
+#define IDC_PRIORITY 1004
+#define IDC_VBITRATE 1005
+#define IDC_ERROR 1005
+#define IDC_VDURATION 1006
+#define IDC_16BITS 1006
+#define IDC_VSIZE 1007
+#define IDC_24BITS 1007
+#define IDC_CONVERT 1007
+#define IDC_VFPS 1008
+#define IDC_32BITS 1008
+#define IDC_CONVERT2 1008
+#define IDC_CHANNELS 1009
+#define IDC_24BITS2 1009
+#define IDC_16BITS_DITHERED 1009
+#define IDC_CONVERT1 1009
+#define IDC_USERDATA 1010
+#define IDC_USEFORAAC 1011
+#define IDC_OUTPUTFOLDER 1014
+#define IDC_LOGO 1019
+#define IDC_PLUGINVER 1050
+#define IDC_FAADVER 1051
+#define IDC_MAIL1 1052
+#define IDC_MAIL2 1053
+#define IDC_MAIL3 1054
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 106
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1020
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
--- /dev/null
+++ b/plugins/QCDMp4/utils.c
@@ -1,0 +1,147 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: utils.c,v 1.1 2003/04/28 19:07:57 menno Exp $
+**/
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <mp4.h>
+#include <faad.h>
+#include "utils.h"
+
+int StringComp(char const *str1, char const *str2, unsigned long len)
+{
+ signed int c1 = 0, c2 = 0;
+
+ while (len--)
+ {
+ c1 = tolower(*str1++);
+ c2 = tolower(*str2++);
+
+ if (c1 == 0 || c1 != c2)
+ break;
+ }
+
+ return c1 - c2;
+}
+
+int GetAACTrack(MP4FileHandle infile)
+{
+ /* find AAC track */
+ int i, rc;
+ int numTracks = MP4GetNumberOfTracks(infile, NULL, 0);
+
+ for (i = 0; i < numTracks; i++)
+ {
+ MP4TrackId trackId = MP4FindTrackId(infile, i, NULL, 0);
+ const char* trackType = MP4GetTrackType(infile, trackId);
+
+ if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE))
+ {
+ unsigned char *buff = NULL;
+ int buff_size = 0;
+ mp4AudioSpecificConfig mp4ASC;
+
+ MP4GetTrackESConfiguration(infile, trackId, &buff, &buff_size);
+
+ if (buff)
+ {
+ rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
+ free(buff);
+
+ if (rc < 0)
+ return -1;
+ return trackId;
+ }
+ }
+ }
+
+ /* can't decode this */
+ return -1;
+}
+
+int GetAudioTrack(MP4FileHandle infile)
+{
+ /* find AAC track */
+ int i;
+ int numTracks = MP4GetNumberOfTracks(infile, NULL, 0);
+
+ for (i = 0; i < numTracks; i++)
+ {
+ MP4TrackId trackId = MP4FindTrackId(infile, i, NULL, 0);
+ const char* trackType = MP4GetTrackType(infile, trackId);
+
+ if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE))
+ {
+ return trackId;
+ }
+ }
+
+ /* can't decode this */
+ return -1;
+}
+
+int GetVideoTrack(MP4FileHandle infile)
+{
+ /* find AAC track */
+ int i;
+ int numTracks = MP4GetNumberOfTracks(infile, NULL, 0);
+
+ for (i = 0; i < numTracks; i++)
+ {
+ MP4TrackId trackId = MP4FindTrackId(infile, i, NULL, 0);
+ const char* trackType = MP4GetTrackType(infile, trackId);
+
+ if (!strcmp(trackType, MP4_VIDEO_TRACK_TYPE))
+ {
+ return trackId;
+ }
+ }
+
+ /* can't decode this */
+ return -1;
+}
+
+LPTSTR PathFindFileName(LPCTSTR pPath)
+{
+ LPCTSTR pT;
+
+ for (pT = pPath; *pPath; pPath = CharNext(pPath)) {
+ if ((pPath[0] == TEXT('\\') || pPath[0] == TEXT(':')) && pPath[1] && (pPath[1] != TEXT('\\')))
+ pT = pPath + 1;
+ }
+
+ return (LPTSTR)pT; // const -> non const
+}
+
+char *convert3in4to3in3(void *sample_buffer, int samples)
+{
+ int i;
+ long *sample_buffer24 = (long*)sample_buffer;
+ char *data = malloc(samples*3*sizeof(char));
+
+ for (i = 0; i < samples; i++)
+ {
+ data[i*3] = sample_buffer24[i] & 0xFF;
+ data[i*3+1] = (sample_buffer24[i] >> 8) & 0xFF;
+ data[i*3+2] = (sample_buffer24[i] >> 16) & 0xFF;
+ }
+
+ return data;
+}
--- /dev/null
+++ b/plugins/QCDMp4/utils.h
@@ -1,0 +1,34 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: utils.h,v 1.1 2003/04/28 19:07:57 menno Exp $
+**/
+
+#ifndef UTILS_INCLUDED
+#define UTILS_INCLUDED
+
+#include <mp4.h>
+
+LPTSTR PathFindFileName(LPCTSTR pPath);
+int GetVideoTrack(MP4FileHandle infile);
+int GetAudioTrack(MP4FileHandle infile);
+int GetAACTrack(MP4FileHandle infile);
+int StringComp(char const *str1, char const *str2, unsigned long len);
+char *convert3in4to3in3(void *sample_buffer, int samples);
+
+#endif
\ No newline at end of file