ref: e9b4be45b8eb828ddd32a5a1c0b1e1f7f921c624
parent: 9cb5698f51570f4512fe74471d558a0502b289b4
author: menno <menno>
date: Sun Nov 16 14:52:41 EST 2003
new QCD plugin code by shaohao
--- a/plugins/QCDMp4/AAC2Mp4Enc.c
+++ /dev/null
@@ -1,270 +1,0 @@
-//-----------------------------------------------------------------------------
-//
-// 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);
-}
--- a/plugins/QCDMp4/QCDConvertDLL.h
+++ /dev/null
@@ -1,40 +1,0 @@
-//-----------------------------------------------------------------------------
-//
-// 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
--- a/plugins/QCDMp4/QCDInputDLL.h
+++ b/plugins/QCDMp4/QCDInputDLL.h
@@ -25,10 +25,6 @@
#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);
@@ -47,6 +43,4 @@
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);
+#endif //QCDInputDLL_H
\ No newline at end of file
--- a/plugins/QCDMp4/QCDModDefs.h
+++ b/plugins/QCDMp4/QCDModDefs.h
@@ -25,6 +25,7 @@
#ifndef QCDMODDEFS_H
#define QCDMODDEFS_H
+#include <mmreg.h>
#include <windows.h>
#ifdef __cplusplus
@@ -34,14 +35,20 @@
#endif
// Current plugin version
-#define PLUGIN_API_VERSION 250
+// use this version for old style API calls (all returned text in native encoding)
+#define PLUGIN_API_VERSION 250
+
+// use this version for new style API calls (all returned text in UTF8 encoding on WinNT/2K/XP (native encoding on Win9x))
+#define PLUGIN_API_VERSION_WANTUTF8 ((PLUGIN_API_WANTUTF8<<16)|PLUGIN_API_VERSION)
+#define PLUGIN_API_WANTUTF8 100
+
//-----------------------------------------------------------------------------
-typedef struct {
+typedef struct
+{
char *moduleString;
char *moduleExtensions;
-
} QCDModInfo;
//-----------------------------------------------------------------------------
@@ -60,7 +67,7 @@
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
+ // - the 'track number' for digital files will be 1 if the tag is not set or the file is not identified
opGetTrackLength = 14, // get track length, param1 = index of track in playlist, -1 for current
// param2 = 0 for seconds, 1 for milliseconds
@@ -88,7 +95,7 @@
opGetIndexFromPLNum = 28, // get index from playlist number, param1 = playlist number
- opGetChildWnd = 30, // handle to the draggable window extension (only available on some skins)
+ opGetExtensionWnd = 30, // handle to the draggable window extension (only available on some skins), param1 = extension number (0 - 9)
opGetExtVisWnd = 31, // handle to the external visual window
opGetMusicBrowserWnd = 32, // handle to the music browser window
opGetSkinPreviewWnd = 33, // handle to the skin preview window
@@ -97,10 +104,13 @@
opGetAboutWnd = 36, // handle to the about window
opGetSegmentsWnd = 37, // handle to the segments window
opGetEQPresetsWnd = 38, // handle to the EQ presets window
+ opGetVideoWnd = 39, // handle to the video 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
+ opShowVideoWindow = 55, // Show or Close video window (param1 = 1 for create, 2 for create and show, 0 for close)
+
opGetQueriesComplete = 60, // get status on whether all tracks in playlist have been queryied for their info
// playlist manipulation
@@ -108,9 +118,9 @@
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
+ opGetMediaInfo = 99, // get the ICddbDisc 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
+ // returns: pointer to ICddbDisc object. Do not release or deallocate this pointer
//*** below returns string info in buffer, param1 = size of buffer
@@ -141,6 +151,7 @@
opGetSupportedExtensions = 116, // get file extensions supported by the player, param2 = 0 - get all extensions, 1 - get registered extensions
// - returned extensions will be colon delimited
+ opGetPlaylistString = 117, // get string for index as it appears in playlist, param2 = index
//*** below buffer points to struct or other object
//*** returns 1 on success, 0 on failure
@@ -149,6 +160,8 @@
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)
+ opGetQuickTrack = 126, // Returns copy of HMENU handle to QuickTrack menu (must use DestroyMenu on handle when complete)
+ // To use if QuickTrack item selected: PostMessage(hwndPlayer, WM_COMMAND, menu_id, 0);
opGetEQVals = 200, // get current EQ levels/on/off (buffer = EQInfo*)
opSetEQVals = 201, // set EQ levels/on/off (buffer = EQInfo*)
@@ -196,13 +209,17 @@
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)
+ opCreateDiscInfo = 1020, // returns: pointer to ICddbDisc object. Do not release or deallocate this pointer
+ opSetDiscInfo = 1021, // buffer = ICddbDisc*, param1 = MediaInfo*, param2 = track number
-
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))
+ opSetRepeatState = 1110, // set playlist repeat state, buffer = NULL, param1 = 0 - off, 1 - repeat track, 2 - repeat playlist
+ opSetShuffleState = 1111, // set playlist shuffle state, buffer = NULL, param1 = 0 - off, 1 - on
+
//*** 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
@@ -213,8 +230,18 @@
opSetPluginMenuState = 2001, // buffer = HINSTANCE of plugin, param1 = item id, param2 = menu flags (same as windows menu flags - eg: MF_CHECKED)
+ //*** below are services for using the player's filename template editor
+ //*** returns 1 on success, 0 on failure
+
+ opShowTemplateEditor = 2100, // displays template editor dialog, param1 = (HWND)parent window, param2 = modal flag
+ opLoadTemplate = 2101, // loads saved templates, buffer = (char*)string buf, param1 = bufsize, param2 = index of template (index < 0 for default formats, index >= 0 for user made formats)
+ opRenderTemplate = 2102, // create string based on template, buffer = (char*)template, param1 = FormatMetaInfo*, param2 = (char*)string buffer (min 260 bytes)
+
//*** other services
+ opUTF8toUCS2 = 9000, // convert UTF8 string to UCS2 (Unicode) string, buffer = null terminated utf8 string, param1 = (WCHAR*)result string buffer, param2 = size of result buffer
+ opUCS2toUTF8 = 9001, // convert UCS2 (Unicode) string to UTF8 string, buffer = null terminated ucs2 string, param1 = (char*)result string buffer, param2 = size of result buffer
+
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
@@ -225,6 +252,10 @@
//-----------------------------------------------------------------------------
typedef long (*PluginServiceFunc)(PluginServiceOp op, void *buffer, long param1, long param2);
+// Use to retrieve service func for DSP plugins (or other inproc process that doesn't have access to PluginServiceFunc)
+// Eg: PluginServiceFunc Service = (PluginServiceFunc)SendMessage(hwndPlayer, WM_GETSERVICEFUNC, 0, 0);
+// Set WPARAM = PLUGIN_API_WANTUTF8 for UTF8 string parameters
+#define WM_GETSERVICEFUNC (WM_USER + 1)
//-----------------------------------------------------------------------------
typedef struct // for Output Plugin Write callback
@@ -263,6 +294,7 @@
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
+ char text[8]; // up to eight characters to identify format (will override level and layer settings)
} AudioInfo;
//-----------------------------------------------------------------------------
@@ -316,7 +348,22 @@
} MediaInfo;
+//-----------------------------------------------------------------------------
+typedef struct
+{
+ long struct_size;
+ LPCWSTR title;
+ LPCWSTR artalb;
+ LPCWSTR album;
+ LPCWSTR genre;
+ LPCWSTR year;
+ LPCWSTR tracknum;
+ LPCWSTR filename;
+ LPCWSTR arttrk;
+ long reserved;
+} FormatMetaInfo;
+
//-----------------------------------------------------------------------------
// When subclassing the parent window, a plugin can watch for these messages
// to react to events going on between plugins and player
@@ -328,8 +375,8 @@
#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_MEDIAEJECTED (WM_USER + 105) // a CD was ejected (CDRom drive letter= 'A' + lParam)
+#define WM_PN_MEDIAINSERTED (WM_USER + 106) // a CD was inserted (CDRom drive letter= 'A' + lParam)
#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)
@@ -340,6 +387,17 @@
// (so you can get handle, modify, and display your own)
#define WM_SHOWMAINMENU (WM_USER + 20)
+// For intercepting skinned border window commands
+#define WM_BORDERWINDOW (WM_USER + 26)
+// WM_BORDERWINDOW wParam's
+#define BORDERWINDOW_NORMALSIZE 0x100000
+#define BORDERWINDOW_DOUBLESIZE 0x200000
+#define BORDERWINDOW_FULLSCREEN 0x400000
+
+// send to border window to cause resize
+// wParam = LPPOINT lpp; // point x-y is CLIENT area size of window
+#define WM_SIZEBORDERWINDOW (WM_USER + 1)
+
//-----------------------------------------------------------------------------
// To shutdown player, send this command
#define WM_SHUTDOWN (WM_USER + 5)
@@ -350,6 +408,6 @@
#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)
-
+#define TEXT_UNICODE 0x10 // buffer contains a unicode string (multibyte string otherwise)
#endif //QCDMODDEFS_H
\ No newline at end of file
--- a/plugins/QCDMp4/QCDModEncode.h
+++ /dev/null
@@ -1,76 +1,0 @@
-//-----------------------------------------------------------------------------
-//
-// 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/QCDModTagEditor.h
@@ -1,0 +1,84 @@
+//-----------------------------------------------------------------------------
+//
+// File: QCDModTagEditor
+//
+// About: Tag Editing plugin module interface. This file is published with the
+// QCD plugin SDK.
+//
+// Authors: Written by Paul Quinn
+//
+// Copyright:
+//
+// QCD multimedia player application Software Development Kit Release 1.0.
+//
+// Copyright (C) 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 QCDMODTAGEDITOR_H
+#define QCDMODTAGEDITOR_H
+
+#include "QCDModDefs.h"
+
+// name of the DLL export for output plugins
+#define TAGEDITORDLL_ENTRY_POINT QTagEditorModule
+
+// Tag field ids
+typedef enum
+{
+ TAGFIELD_FIRSTFIELD = 0,
+
+ TAGFIELD_TITLE = 0,
+ TAGFIELD_ARTIST,
+ TAGFIELD_ALBUM,
+ TAGFIELD_GENRE,
+ TAGFIELD_YEAR,
+ TAGFIELD_TRACK,
+ TAGFIELD_COMMENT,
+
+ TAGFIELD_COMPOSER,
+ TAGFIELD_CONDUCTOR,
+ TAGFIELD_ORCHESTRA,
+ TAGFIELD_YEARCOMPOSED,
+
+ TAGFIELD_ORIGARTIST,
+ TAGFIELD_LABEL,
+ TAGFIELD_COPYRIGHT,
+ TAGFIELD_ENCODER,
+ TAGFIELD_CDDBTAGID,
+
+ TAGFIELD_FIELDCOUNT
+};
+
+//-----------------------------------------------------------------------------
+
+typedef struct
+{
+ UINT size; // size of init structure
+ UINT version; // plugin structure version (set to PLUGIN_API_VERSION)
+
+ LPCSTR description;
+ LPCSTR defaultexts;
+
+ bool (*Read)(LPCSTR filename, void* tagHandle);
+ bool (*Write)(LPCSTR filename, void* tagHandle);
+ bool (*Strip)(LPCSTR filename);
+
+ void (*ShutDown)(int flags);
+
+ void (*SetFieldA)(void* tagHandle, int fieldId, LPCSTR szNewText);
+ void (*SetFieldW)(void* tagHandle, int fieldId, LPCWSTR szNewText);
+
+ LPCSTR (*GetFieldA)(void* tagHandle, int fieldId);
+ LPCWSTR (*GetFieldW)(void* tagHandle, int fieldId);
+
+} QCDModInitTag;
+
+#endif //QCDMODTAGEDITOR_H
\ No newline at end of file
--- a/plugins/QCDMp4/QCDMp4.c
+++ b/plugins/QCDMp4/QCDMp4.c
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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
@@ -16,17 +16,21 @@
** 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.2 2003/05/07 18:30:49 menno Exp $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through [email protected].
+**
+** $Id: QCDMp4.c,v 1.3 2003/11/16 19:52:41 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>
@@ -33,10 +37,15 @@
#include <mp4.h>
#include "resource.h"
+#include "QCDInputDLL.h"
#include "utils.h"
#include "config.h"
#include "aacinfo.h"
-
+//#include "aac2mp4.h"
+//
+//const char *long_ext_list = "MP4\0MPEG-4 Files (*.MP4)\0M4A\0MPEG-4 Files (*.M4A)\0AAC\0AAC Files (*.AAC)\0";
+//const char *short_ext_list = "MP4\0MPEG-4 Files (*.MP4)\0M4A\0MPEG-4 Files (*.M4A)\0";
+
static long priority_table[] = {
0,
THREAD_PRIORITY_HIGHEST,
@@ -50,7 +59,8 @@
IDC_24BITS,
IDC_32BITS,
0,
- IDC_16BITS_DITHERED
+ 0,
+ /*IDC_16BITS_DITHERED*/ IDC_16BITS /* temp hack */
};
static int res_table[] = {
16,
@@ -57,9 +67,20 @@
24,
32,
0,
+ 0,
16
};
+//static char info_fn[_MAX_PATH];
+// post this to the main window at end of file (after playback has stopped)
+//#define WM_WA_AAC_EOF WM_USER+2
+
+struct seek_list
+{
+ struct seek_list *next;
+ __int64 offset;
+};
+
typedef struct state
{
/* general stuff */
@@ -66,12 +87,13 @@
faacDecHandle hDecoder;
int samplerate;
unsigned char channels;
- int decode_pos_ms; // current decoding position, in milliseconds
+ double 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;
+ __int64 last_offset;
/* MP4 stuff */
MP4FileHandle mp4file;
@@ -81,39 +103,65 @@
/* AAC stuff */
FILE *aacfile;
- long filesize;
- long bytes_read;
- long bytes_into_buffer;
- long bytes_consumed;
- unsigned char *buffer;
- long seconds;
-// faadAACInfo aacInfo;
+ long m_aac_bytes_into_buffer;
+ long m_aac_bytes_consumed;
+ __int64 m_file_offset;
+ unsigned char *m_aac_buffer;
+ int m_at_eof;
+ double cur_pos_sec;
+ int m_header_type;
+ struct seek_list *m_head;
+ struct seek_list *m_tail;
+ unsigned long m_length;
+
+ /* for gapless decoding */
+ unsigned int useAacLength;
+ unsigned int framesize;
+ unsigned int initial;
+ unsigned long timescale;
} state;
static state mp4state;
-HINSTANCE hInstance;
-HWND hwndPlayer, hwndConfig, hwndAbout;
-QCDModInitIn sQCDCallbacks, *QCDCallbacks;
-BOOL oldAPIs = 0;
+//static In_Module module; // the output module (declared near the bottom of this file)
+struct {
+ HINSTANCE hInstance;
+ HWND hMainWindow;
+ QCDModInitIn QCDCallbacks;
+} module;
+AudioInfo ai;
static int killPlayThread;
+static int PlayThreadAlive = 0; // 1=play thread still running
HANDLE play_thread_handle = INVALID_HANDLE_VALUE; // the handle to the decode thread
/* Function definitions */
+void *decode_aac_frame(state *st, faacDecFrameInfo *frameInfo);
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);
+ sprintf(s, "in_mp4: %s: %s", mp4state.filename, message);
+ OutputDebugString(s);
}
#endif
+int file_length(FILE *f)
+{
+ long end = 0;
+ long cur = ftell(f);
+ fseek(f, 0, SEEK_END);
+ end = ftell(f);
+ fseek(f, cur, SEEK_SET);
+
+ return end;
+}
+
static void show_error(HWND hwnd, char *message, ...)
{
if (m_show_errors)
@@ -120,6 +168,16 @@
MessageBox(hwnd, message, "Error", MB_OK);
}
+static void config_init()
+{
+ //char *p=INI_FILE;
+ //GetModuleFileName(NULL,INI_FILE,_MAX_PATH);
+ //while (*p) p++;
+ //while (p >= INI_FILE && *p != '.') p--;
+ //strcpy(p+1,"ini");
+ module.QCDCallbacks.Service(opGetPluginSettingsFile, INI_FILE, MAX_PATH, 0);
+}
+
void config_read()
{
char priority[10];
@@ -126,21 +184,33 @@
char resolution[10];
char show_errors[10];
char use_for_aac[10];
+ char downmix[10];
+ char vbr_display[10];
+ config_init();
+
strcpy(show_errors, "1");
strcpy(priority, "3");
strcpy(resolution, "0");
strcpy(use_for_aac, "1");
+ strcpy(downmix, "0");
+ strcpy(vbr_display, "1");
+ //strcpy(titleformat, "%7");
RS(priority);
- RS(resolution);
- RS(show_errors);
+ RS(resolution);
+ RS(show_errors);
RS(use_for_aac);
+ RS(downmix);
+ RS(vbr_display);
+ //RS(titleformat);
m_priority = atoi(priority);
m_resolution = atoi(resolution);
m_show_errors = atoi(show_errors);
m_use_for_aac = atoi(use_for_aac);
+ m_downmix = atoi(downmix);
+ m_vbr_display = atoi(vbr_display);
}
void config_write()
@@ -149,105 +219,38 @@
char resolution[10];
char show_errors[10];
char use_for_aac[10];
+ char downmix[10];
+ char vbr_display[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);
+ itoa(m_downmix, downmix, 10);
+ itoa(m_vbr_display, vbr_display, 10);
WS(priority);
- WS(resolution);
- WS(show_errors);
- WS(use_for_aac);
+ WS(resolution);
+ WS(show_errors);
+ WS(use_for_aac);
+ WS(downmix);
+ WS(vbr_display);
+ //WS(titleformat);
}
-//-----------------------------------------------------------------------------
-
-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:M4A:AAC" : "MP4:M4A";
-
- 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);
+ ModInfo->moduleString = "MP4 Plug-in v" FAAD2_VERSION;
- mp4state.filename[0] = 0;
- mp4state.seek_needed = -1;
- mp4state.paused = 0;
- play_thread_handle = INVALID_HANDLE_VALUE;
+ module.hMainWindow = (HWND)module.QCDCallbacks.Service(opGetParentWnd, 0, 0, 0);
- /* read config */
- QCDCallbacks->Service(opGetPluginSettingsFile, INI_FILE, MAX_PATH, 0);
+ // read config from config file
config_read();
- ModInfo->moduleString = "MPEG-4 General Audio Plugin v1.0";
- ModInfo->moduleExtensions = m_use_for_aac ? "MP4:M4A:AAC" : "MP4:M4A";
+ ModInfo->moduleExtensions = !m_use_for_aac ? "MP4:M4A" : "MP4:M4A:AAC";
- // insert menu item into plugin menu
-// QCDCallbacks->Service(opSetPluginMenuItem, hInstance, IDD_CONFIG, (long)"Mp4 Plug-in");
-
- return TRUE;
+ // return TRUE for successful initialization
+ return 1;
}
//----------------------------------------------------------------------------
@@ -255,122 +258,689 @@
void ShutDown(int flags)
{
Stop(mp4state.filename, STOPFLAG_FORCESTOP);
-
- // delete the inserted plugin menu
-// QCDCallbacks->Service(opSetPluginMenuItem, hInstance, 0, 0);
}
-//-----------------------------------------------------------------------------
+///* Convert UNICODE to UTF-8
+// Return number of bytes written */
+//int unicodeToUtf8 ( const WCHAR* lpWideCharStr, char* lpMultiByteStr, int cwcChars )
+//{
+// const unsigned short* pwc = (unsigned short *)lpWideCharStr;
+// unsigned char* pmb = (unsigned char *)lpMultiByteStr;
+// const unsigned short* pwce;
+// size_t cBytes = 0;
+//
+// if ( cwcChars >= 0 ) {
+// pwce = pwc + cwcChars;
+// } else {
+// pwce = (unsigned short *)((size_t)-1);
+// }
+//
+// while ( pwc < pwce ) {
+// unsigned short wc = *pwc++;
+//
+// if ( wc < 0x00000080 ) {
+// *pmb++ = (char)wc;
+// cBytes++;
+// } else
+// if ( wc < 0x00000800 ) {
+// *pmb++ = (char)(0xC0 | ((wc >> 6) & 0x1F));
+// cBytes++;
+// *pmb++ = (char)(0x80 | (wc & 0x3F));
+// cBytes++;
+// } else
+// if ( wc < 0x00010000 ) {
+// *pmb++ = (char)(0xE0 | ((wc >> 12) & 0x0F));
+// cBytes++;
+// *pmb++ = (char)(0x80 | ((wc >> 6) & 0x3F));
+// cBytes++;
+// *pmb++ = (char)(0x80 | (wc & 0x3F));
+// cBytes++;
+// }
+// if ( wc == L'\0' )
+// return cBytes;
+// }
+//
+// return cBytes;
+//}
+//
+///* Convert UTF-8 coded string to UNICODE
+// Return number of characters converted */
+//int utf8ToUnicode ( const char* lpMultiByteStr, WCHAR* lpWideCharStr, int cmbChars )
+//{
+// const unsigned char* pmb = (unsigned char *)lpMultiByteStr;
+// unsigned short* pwc = (unsigned short *)lpWideCharStr;
+// const unsigned char* pmbe;
+// size_t cwChars = 0;
+//
+// if ( cmbChars >= 0 ) {
+// pmbe = pmb + cmbChars;
+// } else {
+// pmbe = (unsigned char *)((size_t)-1);
+// }
+//
+// while ( pmb < pmbe ) {
+// char mb = *pmb++;
+// unsigned int cc = 0;
+// unsigned int wc;
+//
+// while ( (cc < 7) && (mb & (1 << (7 - cc)))) {
+// cc++;
+// }
+//
+// if ( cc == 1 || cc > 6 ) // illegal character combination for UTF-8
+// continue;
+//
+// if ( cc == 0 ) {
+// wc = mb;
+// } else {
+// wc = (mb & ((1 << (7 - cc)) - 1)) << ((cc - 1) * 6);
+// while ( --cc > 0 ) {
+// if ( pmb == pmbe ) // reached end of the buffer
+// return cwChars;
+// mb = *pmb++;
+// if ( ((mb >> 6) & 0x03) != 2 ) // not part of multibyte character
+// return cwChars;
+// wc |= (mb & 0x3F) << ((cc - 1) * 6);
+// }
+// }
+//
+// if ( wc & 0xFFFF0000 )
+// wc = L'?';
+// *pwc++ = wc;
+// cwChars++;
+// if ( wc == L'\0' )
+// return cwChars;
+// }
+//
+// return cwChars;
+//}
+//
+///* convert Windows ANSI to UTF-8 */
+//int ConvertANSIToUTF8 ( const char* ansi, char* utf8 )
+//{
+// WCHAR* wszValue; // Unicode value
+// size_t ansi_len;
+// size_t len;
+//
+// *utf8 = '\0';
+// if ( ansi == NULL )
+// return 0;
+//
+// ansi_len = strlen ( ansi );
+//
+// if ( (wszValue = (WCHAR *)malloc ( (ansi_len + 1) * 2 )) == NULL )
+// return 0;
+//
+// /* Convert ANSI value to Unicode */
+// if ( (len = MultiByteToWideChar ( CP_ACP, 0, ansi, ansi_len + 1, wszValue, (ansi_len + 1) * 2 )) == 0 ) {
+// free ( wszValue );
+// return 0;
+// }
+//
+// /* Convert Unicode value to UTF-8 */
+// if ( (len = unicodeToUtf8 ( wszValue, utf8, -1 )) == 0 ) {
+// free ( wszValue );
+// return 0;
+// }
+//
+// free ( wszValue );
+//
+// return len-1;
+//}
+//
+///* convert UTF-8 to Windows ANSI */
+//int ConvertUTF8ToANSI ( const char* utf8, char* ansi )
+//{
+// WCHAR* wszValue; // Unicode value
+// size_t utf8_len;
+// size_t len;
+//
+// *ansi = '\0';
+// if ( utf8 == NULL )
+// return 0;
+//
+// utf8_len = strlen ( utf8 );
+//
+// if ( (wszValue = (WCHAR *)malloc ( (utf8_len + 1) * 2 )) == NULL )
+// return 0;
+//
+// /* Convert UTF-8 value to Unicode */
+// if ( (len = utf8ToUnicode ( utf8, wszValue, utf8_len + 1 )) == 0 ) {
+// free ( wszValue );
+// return 0;
+// }
+//
+// /* Convert Unicode value to ANSI */
+// if ( (len = WideCharToMultiByte ( CP_ACP, 0, wszValue, -1, ansi, (utf8_len + 1) * 2, NULL, NULL )) == 0 ) {
+// free ( wszValue );
+// return 0;
+// }
+//
+// free ( wszValue );
+//
+// return len-1;
+//}
+//
+//BOOL uSetDlgItemText(HWND hwnd, int id, const char *str)
+//{
+// char *temp;
+// size_t len;
+// int r;
+//
+// if (!str) return FALSE;
+// len = strlen(str);
+// temp = malloc(len+1);
+// if (!temp) return FALSE;
+// r = ConvertUTF8ToANSI(str, temp);
+// if (r > 0)
+// SetDlgItemText(hwnd, id, temp);
+// free(temp);
+//
+// return r>0 ? TRUE : FALSE;
+//}
+//
+//UINT uGetDlgItemText(HWND hwnd, int id, char *str, int max)
+//{
+// char *temp, *utf8;
+// int len;
+// HWND w;
+//
+// if (!str) return 0;
+// w = GetDlgItem(hwnd, id);
+// len = GetWindowTextLength(w);
+// temp = malloc(len+1);
+// if (!temp) return 0;
+// utf8 = malloc((len+1)*4);
+// if (!utf8)
+// {
+// free(temp);
+// return 0;
+// }
+//
+// len = GetWindowText(w, temp, len+1);
+// if (len > 0)
+// {
+// len = ConvertANSIToUTF8(temp, utf8);
+// if (len > max-1)
+// {
+// len = max-1;
+// utf8[max] = '\0';
+// }
+// memcpy(str, utf8, len+1);
+// }
+//
+// free(temp);
+// free(utf8);
+//
+// return len;
+//}
+//
+//BOOL CALLBACK mp4_info_dialog_proc(HWND hwndDlg, UINT message,
+// WPARAM wParam, LPARAM lParam)
+//{
+// char *file_info;
+// MP4FileHandle file;
+// char *pVal, dummy1[1024], dummy3;
+// short dummy, dummy2;
+//
+//#ifdef DEBUG_OUTPUT
+// in_mp4_DebugOutput("mp4_info_dialog_proc");
+//#endif
+//
+// switch (message) {
+// case WM_INITDIALOG:
+// EnableWindow(GetDlgItem(hwndDlg,IDC_CONVERT), FALSE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_CONVERT), SW_HIDE);
+// EnableWindow(GetDlgItem(hwndDlg,IDC_CONVERT1), FALSE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_CONVERT1), SW_HIDE);
+// EnableWindow(GetDlgItem(hwndDlg,IDC_CONVERT2), FALSE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_CONVERT2), SW_HIDE);
+//
+//
+// file = MP4Read(info_fn, 0);
+//
+// if (file == MP4_INVALID_FILE_HANDLE)
+// return FALSE;
+//
+// file_info = MP4Info(file, MP4_INVALID_TRACK_ID);
+// SetDlgItemText(hwndDlg, IDC_INFOTEXT, file_info);
+// free(file_info);
+//
+// /* get Metadata */
+//
+// pVal = NULL;
+// MP4GetMetadataName(file, &pVal);
+// uSetDlgItemText(hwndDlg,IDC_METANAME, pVal);
+//
+// pVal = NULL;
+// MP4GetMetadataArtist(file, &pVal);
+// uSetDlgItemText(hwndDlg,IDC_METAARTIST, pVal);
+//
+// pVal = NULL;
+// MP4GetMetadataWriter(file, &pVal);
+// uSetDlgItemText(hwndDlg,IDC_METAWRITER, pVal);
+//
+// pVal = NULL;
+// MP4GetMetadataComment(file, &pVal);
+// uSetDlgItemText(hwndDlg,IDC_METACOMMENTS, pVal);
+//
+// pVal = NULL;
+// MP4GetMetadataAlbum(file, &pVal);
+// uSetDlgItemText(hwndDlg,IDC_METAALBUM, pVal);
+//
+// pVal = NULL;
+// MP4GetMetadataGenre(file, &pVal);
+// uSetDlgItemText(hwndDlg,IDC_METAGENRE, pVal);
+//
+// dummy = 0;
+// MP4GetMetadataTempo(file, &dummy);
+// wsprintf(dummy1, "%d", dummy);
+// SetDlgItemText(hwndDlg,IDC_METATEMPO, dummy1);
+//
+// dummy = 0; dummy2 = 0;
+// MP4GetMetadataTrack(file, &dummy, &dummy2);
+// wsprintf(dummy1, "%d", dummy);
+// SetDlgItemText(hwndDlg,IDC_METATRACK1, dummy1);
+// wsprintf(dummy1, "%d", dummy2);
+// SetDlgItemText(hwndDlg,IDC_METATRACK2, dummy1);
+//
+// dummy = 0; dummy2 = 0;
+// MP4GetMetadataDisk(file, &dummy, &dummy2);
+// wsprintf(dummy1, "%d", dummy);
+// SetDlgItemText(hwndDlg,IDC_METADISK1, dummy1);
+// wsprintf(dummy1, "%d", dummy2);
+// SetDlgItemText(hwndDlg,IDC_METADISK2, dummy1);
+//
+// pVal = NULL;
+// MP4GetMetadataYear(file, &pVal);
+// uSetDlgItemText(hwndDlg,IDC_METAYEAR, pVal);
+//
+// dummy3 = 0;
+// MP4GetMetadataCompilation(file, &dummy3);
+// if (dummy3)
+// SendMessage(GetDlgItem(hwndDlg, IDC_METACOMPILATION), BM_SETCHECK, BST_CHECKED, 0);
+//
+// /* ! Metadata */
+//
+// MP4Close(file);
+//
+// return TRUE;
+//
+// case WM_COMMAND:
+// switch (LOWORD(wParam)) {
+// case IDCANCEL:
+// EndDialog(hwndDlg, wParam);
+// return TRUE;
+// case IDOK:
+//
+// /* save Metadata changes */
+//
+// file = MP4Modify(info_fn, 0, 0);
+// if (file == MP4_INVALID_FILE_HANDLE)
+// {
+// EndDialog(hwndDlg, wParam);
+// return FALSE;
+// }
+//
+// uGetDlgItemText(hwndDlg, IDC_METANAME, dummy1, 1024);
+// MP4SetMetadataName(file, dummy1);
+//
+// uGetDlgItemText(hwndDlg, IDC_METAWRITER, dummy1, 1024);
+// MP4SetMetadataWriter(file, dummy1);
+//
+// uGetDlgItemText(hwndDlg, IDC_METAARTIST, dummy1, 1024);
+// MP4SetMetadataArtist(file, dummy1);
+//
+// uGetDlgItemText(hwndDlg, IDC_METAALBUM, dummy1, 1024);
+// MP4SetMetadataAlbum(file, dummy1);
+//
+// uGetDlgItemText(hwndDlg, IDC_METACOMMENTS, dummy1, 1024);
+// MP4SetMetadataComment(file, dummy1);
+//
+// uGetDlgItemText(hwndDlg, IDC_METAGENRE, dummy1, 1024);
+// MP4SetMetadataGenre(file, dummy1);
+//
+// uGetDlgItemText(hwndDlg, IDC_METAYEAR, dummy1, 1024);
+// MP4SetMetadataYear(file, dummy1);
+//
+// GetDlgItemText(hwndDlg, IDC_METATRACK1, dummy1, 1024);
+// dummy = atoi(dummy1);
+// GetDlgItemText(hwndDlg, IDC_METATRACK2, dummy1, 1024);
+// dummy2 = atoi(dummy1);
+// MP4SetMetadataTrack(file, dummy, dummy2);
+//
+// GetDlgItemText(hwndDlg, IDC_METADISK1, dummy1, 1024);
+// dummy = atoi(dummy1);
+// GetDlgItemText(hwndDlg, IDC_METADISK2, dummy1, 1024);
+// dummy2 = atoi(dummy1);
+// MP4SetMetadataDisk(file, dummy, dummy2);
+//
+// GetDlgItemText(hwndDlg, IDC_METATEMPO, dummy1, 1024);
+// dummy = atoi(dummy1);
+// MP4SetMetadataTempo(file, dummy);
+//
+// dummy3 = SendMessage(GetDlgItem(hwndDlg, IDC_METACOMPILATION), BM_GETCHECK, 0, 0);
+// MP4SetMetadataCompilation(file, dummy3);
+//
+// MP4Close(file);
+//
+// MP4Optimize(info_fn, NULL, 0);
+// /* ! */
+//
+// EndDialog(hwndDlg, wParam);
+// return TRUE;
+// }
+// }
+// return FALSE;
+//}
+//
+///* returns the name of the object type */
+//char *get_ot_string(int ot)
+//{
+// switch (ot)
+// {
+// case 0:
+// return "Main";
+// case 1:
+// return "LC";
+// case 2:
+// return "SSR";
+// case 3:
+// return "LTP";
+// }
+// return NULL;
+//}
+//
+//BOOL CALLBACK aac_info_dialog_proc(HWND hwndDlg, UINT message,
+// WPARAM wParam, LPARAM lParam)
+//{
+// faadAACInfo aacInfo;
+// char *info_text, *header_string;
+//
+//#ifdef DEBUG_OUTPUT
+// in_mp4_DebugOutput("aac_info_dialog_proc");
+//#endif
+//
+// switch (message) {
+// case WM_INITDIALOG:
+// EnableWindow(GetDlgItem(hwndDlg,IDC_USERDATA), FALSE) ;
+// ShowWindow(GetDlgItem(hwndDlg,IDC_USERDATA), SW_HIDE);
+//
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC1), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC2), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC3), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC4), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC5), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC6), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC7), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC8), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC9), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC10), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC11), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC12), SW_HIDE);
+//
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METANAME), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METAARTIST), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METAWRITER), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METACOMMENTS), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METAALBUM), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METAGENRE), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METATEMPO), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METATRACK1), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METATRACK2), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METADISK1), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METADISK2), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METAYEAR), SW_HIDE);
+// ShowWindow(GetDlgItem(hwndDlg,IDC_METACOMPILATION), SW_HIDE);
+//
+// info_text = malloc(1024*sizeof(char));
+//
+// get_AAC_format(info_fn, &aacInfo);
+//
+// switch (aacInfo.headertype)
+// {
+// case 0: /* RAW */
+// header_string = " RAW";
+// break;
+// case 1: /* ADIF */
+// header_string = " ADIF";
+// break;
+// case 2: /* ADTS */
+// header_string = " ADTS";
+// break;
+// }
+//
+// sprintf(info_text, "%s AAC %s%s, %d sec, %d kbps, %d Hz",
+// (aacInfo.version==2)?"MPEG-2":"MPEG-4", get_ot_string(aacInfo.object_type),
+// header_string,
+// (int)((float)aacInfo.length/1000.0), (int)((float)aacInfo.bitrate/1000.0+0.5),
+// aacInfo.sampling_rate);
+//
+// SetDlgItemText(hwndDlg, IDC_INFOTEXT, info_text);
+//
+// free(info_text);
+//
+// return TRUE;
+//
+// case WM_COMMAND:
+// switch (LOWORD(wParam))
+// {
+// case IDC_CONVERT:
+// {
+// char mp4FileName[256];
+// char *extension;
+// OPENFILENAME ofn;
+//
+// lstrcpy(mp4FileName, info_fn);
+// extension = strrchr(mp4FileName, '.');
+// lstrcpy(extension, ".mp4");
+//
+// memset(&ofn, 0, sizeof(OPENFILENAME));
+// ofn.lStructSize = sizeof(OPENFILENAME);
+// ofn.hwndOwner = hwndDlg;
+// ofn.hInstance = module.hDllInstance;
+// ofn.nMaxFileTitle = 31;
+// ofn.lpstrFile = (LPSTR)mp4FileName;
+// ofn.nMaxFile = _MAX_PATH;
+// ofn.lpstrFilter = "MP4 Files (*.mp4)\0*.mp4\0";
+// ofn.lpstrDefExt = "mp4";
+// ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
+// ofn.lpstrTitle = "Select Output File";
+//
+// if (GetSaveFileName(&ofn))
+// {
+// if (covert_aac_to_mp4(info_fn, mp4FileName))
+// {
+// MessageBox(hwndDlg, "An error occured while converting AAC to MP4!", "An error occured!", MB_OK);
+// return FALSE;
+// }
+// }
+// return TRUE;
+// }
+// case IDCANCEL:
+// case IDOK:
+// EndDialog(hwndDlg, wParam);
+// return TRUE;
+// }
+// }
+// return FALSE;
+//}
+//
+//int infoDlg(char *fn, HWND hwndParent)
+//{
+// if(!stricmp(fn + strlen(fn) - 3,"AAC"))
+// {
+// lstrcpy(info_fn, fn);
+//
+// DialogBox(module.hDllInstance, MAKEINTRESOURCE(IDD_INFO),
+// hwndParent, aac_info_dialog_proc);
+// } else {
+// lstrcpy(info_fn, fn);
+//
+// DialogBox(module.hDllInstance, MAKEINTRESOURCE(IDD_INFO),
+// hwndParent, mp4_info_dialog_proc);
+// }
+//
+// return 0;
+//}
+//
+///* Get the title from the file */
+//void ConstructTitle(MP4FileHandle file, char *filename, char *title, char *format)
+//{
+// char temp[4096];
+// int some_info = 0;
+// char *in = format;
+// char *out = temp;//title;
+// char *bound = out + sizeof(temp) - 256; //out + (MAX_PATH - 10 - 1);
+// char *pVal, dummy1[1024];
+// short dummy, dummy2;
+//
+//
+// while (*in && out < bound)
+// {
+// switch (*in)
+// {
+// case '%':
+// ++in;
+// break;
+//
+// default:
+// *out++ = *in++;
+// continue;
+// }
+//
+// /* handle % escape sequence */
+// switch (*in++)
+// {
+// case '0':
+// dummy = 0; dummy2 = 0;
+// if (MP4GetMetadataTrack(file, &dummy, &dummy2))
+// {
+// out += wsprintf(out, "%d", (int)dummy);
+// some_info = 1;
+// }
+// break;
+//
+// case '1':
+// pVal = NULL;
+// if (MP4GetMetadataArtist(file, &pVal))
+// {
+// out += wsprintf(out, "%s", pVal);
+// some_info = 1;
+// }
+// break;
+//
+// case '2':
+// pVal = NULL;
+// if (MP4GetMetadataName(file, &pVal))
+// {
+// out += wsprintf(out, "%s", pVal);
+// some_info = 1;
+// }
+// break;
+//
+// case '3':
+// pVal = NULL;
+// if (MP4GetMetadataAlbum(file, &pVal))
+// {
+// out += wsprintf(out, "%s", pVal);
+// some_info = 1;
+// }
+// break;
+//
+// case '4':
+// pVal = NULL;
+// if (MP4GetMetadataYear(file, &pVal))
+// {
+// out += wsprintf(out, "%s", pVal);
+// some_info = 1;
+// }
+// break;
+//
+// case '5':
+// pVal = NULL;
+// if (MP4GetMetadataComment(file, &pVal))
+// {
+// out += wsprintf(out, "%s", pVal);
+// some_info = 1;
+// }
+// break;
+//
+// case '6':
+// pVal = NULL;
+// if (MP4GetMetadataGenre(file, &pVal))
+// {
+// out += wsprintf(out, "%s", pVal);
+// some_info = 1;
+// }
+// break;
+//
+// case '7':
+// {
+// const char *p=strrchr(filename,'\\');
+// if (!p) p=filename; else p++;
+// out += ConvertANSIToUTF8(p, out);
+// some_info = 1;
+// break;
+// }
+//
+// default:
+// break;
+// }
+// }
+//
+// *out = '\0';
+//
+// if (!some_info)
+// {
+// char *p=filename+lstrlen(filename);
+// while (*p != '\\' && p >= filename) p--;
+// lstrcpy(title,++p);
+// }
+// else
+// {
+// int len = ConvertUTF8ToANSI(temp, dummy1);
+// if (len > (MAX_PATH - 10 - 1)) len = (MAX_PATH - 10 - 1);
+// memcpy(title, dummy1, len);
+// title[len] = '\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)
- {
+ 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, 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);
+ if (m_downmix)
+ SendMessage(GetDlgItem(hwndDlg, IDC_DOWNMIX), BM_SETCHECK, BST_CHECKED, 0);
+ if (m_vbr_display)
+ SendMessage(GetDlgItem(hwndDlg, IDC_VBR), BM_SETCHECK, BST_CHECKED, 0);
+ SetDlgItemText(hwndDlg, IDC_TITLEFORMAT, titleformat);
return TRUE;
case WM_COMMAND:
- switch (LOWORD(wParam))
- {
+ switch (LOWORD(wParam)) {
+ case IDCANCEL:
+ EndDialog(hwndDlg, wParam);
+ return TRUE;
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_downmix = SendMessage(GetDlgItem(hwndDlg, IDC_DOWNMIX), BM_GETCHECK, 0, 0);
+ m_vbr_display = SendMessage(GetDlgItem(hwndDlg, IDC_VBR), BM_GETCHECK, 0, 0);
+ GetDlgItemText(hwndDlg, IDC_TITLEFORMAT, titleformat, MAX_PATH);
+
m_priority = SendMessage(GetDlgItem(hwndDlg, IDC_PRIORITY), TBM_GETPOS, 0, 0);
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 6; i++)
{
if (SendMessage(GetDlgItem(hwndDlg, res_id_table[i]), BM_GETCHECK, 0, 0))
{
@@ -381,8 +951,15 @@
/* save config */
config_write();
- case IDCANCEL:
- DestroyWindow(hwndDlg);
+
+ //if (!m_use_for_aac)
+ //{
+ // module.FileExtensions = short_ext_list;
+ //} else {
+ // module.FileExtensions = long_ext_list;
+ //}
+
+ EndDialog(hwndDlg, wParam);
return TRUE;
}
}
@@ -391,358 +968,572 @@
void Configure(int flags)
{
- if(!IsWindow(hwndConfig))
- hwndConfig = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_CONFIG_INPUT), hwndPlayer, config_dialog_proc);
- ShowWindow(hwndConfig, SW_SHOWNORMAL);
+ DialogBox(module.hInstance, MAKEINTRESOURCE(IDD_CONFIG),
+ module.hMainWindow, config_dialog_proc);
}
//-----------------------------------------------------------------------------
-// proc of "About Dialog"
-INT_PTR CALLBACK about_dialog_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+
+void About(int flags)
{
- 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";
+ MessageBox(module.hMainWindow,
+ "AudioCoding.com MPEG-4 General Audio player " FAAD2_VERSION " compiled on " __DATE__ ".\n"
+ "Visit the website for more info.\n"
+ "Ported to QCD by Shao Hao.\n"
+ "Copyright 2002-2003 AudioCoding.com",
+ "About",
+ MB_OK);
+}
- 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));
+int fill_buffer(state *st)
+{
+ int bread;
- 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:[email protected]", 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:[email protected]", 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;
+ if (st->m_aac_bytes_consumed > 0)
+ {
+ if (st->m_aac_bytes_into_buffer)
+ {
+ memmove((void*)st->m_aac_buffer, (void*)(st->m_aac_buffer + st->m_aac_bytes_consumed),
+ st->m_aac_bytes_into_buffer*sizeof(unsigned char));
+ }
+
+ if (!st->m_at_eof)
+ {
+ bread = fread((void*)(st->m_aac_buffer + st->m_aac_bytes_into_buffer),
+ 1, st->m_aac_bytes_consumed, st->aacfile);
+
+ if (bread != st->m_aac_bytes_consumed)
+ st->m_at_eof = 1;
+
+ st->m_aac_bytes_into_buffer += bread;
+ }
+
+ st->m_aac_bytes_consumed = 0;
+
+ if (st->m_aac_bytes_into_buffer > 3)
+ {
+ if (memcmp(st->m_aac_buffer, "TAG", 3) == 0)
+ st->m_aac_bytes_into_buffer = 0;
+ }
+ if (st->m_aac_bytes_into_buffer > 11)
+ {
+ if (memcmp(st->m_aac_buffer, "LYRICSBEGIN", 11) == 0)
+ st->m_aac_bytes_into_buffer = 0;
+ }
+ if (st->m_aac_bytes_into_buffer > 8)
+ {
+ if (memcmp(st->m_aac_buffer, "APETAGEX", 8) == 0)
+ st->m_aac_bytes_into_buffer = 0;
+ }
+ }
+
+ return 1;
}
-void About(int flags)
+void advance_buffer(state *st, int bytes)
{
- if(!IsWindow(hwndAbout))
- hwndAbout = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_ABOUT), hwndPlayer, about_dialog_proc);
- ShowWindow(hwndAbout, SW_SHOWNORMAL);
+ st->m_file_offset += bytes;
+ st->m_aac_bytes_consumed = bytes;
+ st->m_aac_bytes_into_buffer -= bytes;
}
-//-----------------------------------------------------------------------------
+int adts_parse(state *st, __int64 *bitrate, double *length)
+{
+ static int sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};
+ int frames, frame_length;
+ int t_framelength = 0;
+ int samplerate;
+ double frames_per_sec, bytes_per_frame;
-int Play(const char* medianame, int playfrom, int playto, int flags)
+ /* Read all frames to ensure correct time and bitrate */
+ for (frames = 0; /* */; frames++)
+ {
+ fill_buffer(st);
+
+ if (st->m_aac_bytes_into_buffer > 7)
+ {
+ /* check syncword */
+ if (!((st->m_aac_buffer[0] == 0xFF)&&((st->m_aac_buffer[1] & 0xF6) == 0xF0)))
+ break;
+
+ st->m_tail->offset = st->m_file_offset;
+ st->m_tail->next = (struct seek_list*)malloc(sizeof(struct seek_list));
+ st->m_tail = st->m_tail->next;
+ st->m_tail->next = NULL;
+
+ if (frames == 0)
+ samplerate = sample_rates[(st->m_aac_buffer[2]&0x3c)>>2];
+
+ frame_length = ((((unsigned int)st->m_aac_buffer[3] & 0x3)) << 11)
+ | (((unsigned int)st->m_aac_buffer[4]) << 3) | (st->m_aac_buffer[5] >> 5);
+
+ t_framelength += frame_length;
+
+ if (frame_length > st->m_aac_bytes_into_buffer)
+ break;
+
+ advance_buffer(st, frame_length);
+ } else {
+ break;
+ }
+ }
+
+ frames_per_sec = (double)samplerate/1024.0;
+ if (frames != 0)
+ bytes_per_frame = (double)t_framelength/(double)(frames*1000);
+ else
+ bytes_per_frame = 0;
+ *bitrate = (__int64)(8. * bytes_per_frame * frames_per_sec + 0.5);
+ if (frames_per_sec != 0)
+ *length = (double)frames/frames_per_sec;
+ else
+ *length = 1;
+
+ return 1;
+}
+
+int skip_id3v2_tag()
{
- static WAVEFORMATEX wf;
+ unsigned char buf[10];
+ int bread, tagsize = 0;
- if(flags == PLAYFLAG_ENCODING)
+ bread = fread(buf, 1, 10, mp4state.aacfile);
+ if (bread != 10) return -1;
+
+ if (!memcmp(buf, "ID3", 3))
+ {
+ /* high bit is not used */
+ tagsize = (buf[6] << 21) | (buf[7] << 14) | (buf[8] << 7) | (buf[9] << 0);
+
+ tagsize += 10;
+ fseek(mp4state.aacfile, tagsize, SEEK_SET);
+ } else {
+ fseek(mp4state.aacfile, 0, SEEK_SET);
+ }
+
+ return tagsize;
+}
+
+int GetMediaSupported(const char* medianame, MediaInfo *mediaInfo)
+{
+ int tagsize = 0, init;
+
+ if (!medianame || !*medianame)
+ return 0;
+
+ if (!stricmp(medianame + strlen(medianame) - 3,"MP4") || !stricmp(medianame + strlen(medianame) - 3,"M4A"))
+ {
+ if (mediaInfo)
+ {
+ mediaInfo->mediaType = DIGITAL_FILE_MEDIA;
+ mediaInfo->op_canSeek = 1;
+ }
+ return 1;
+ }
+ else if (m_use_for_aac && !stricmp(medianame + strlen(medianame) - 3,"AAC"))
{
- if(QCDCallbacks->toPlayer.OutputOpen(medianame, &wf))
- Stop(medianame, STOPFLAG_FORCESTOP);
- return FALSE;
+ if (mediaInfo)
+ {
+ mediaInfo->mediaType = DIGITAL_FILE_MEDIA;
+ mediaInfo->op_canSeek = 1;
+
+ memset(&mp4state, 0, sizeof(state));
+ lstrcpy(mp4state.filename, medianame);
+
+ if (!(mp4state.aacfile = fopen(mp4state.filename, "rb")))
+ {
+ // error
+ return 0;
+ }
+
+ tagsize = skip_id3v2_tag();
+ if (tagsize<0) return 0;
+
+ if (!(mp4state.m_aac_buffer = (unsigned char*)malloc(768*6)))
+ {
+ show_error(module.hMainWindow, "Memory allocation error.");
+ return 0;
+ }
+
+ for (init=0; init<2; init++)
+ {
+ memset(mp4state.m_aac_buffer, 0, 768*6);
+ fread(mp4state.m_aac_buffer, 1, 768*6, mp4state.aacfile);
+
+ if (init==0)
+ fseek(mp4state.aacfile, tagsize, SEEK_SET);
+ }
+
+ if (memcmp(mp4state.m_aac_buffer, "ADIF", 4) == 0)
+ mediaInfo->op_canSeek = (double)file_length(mp4state.aacfile) == -1 ? 0 : 1;
+
+ free(mp4state.m_aac_buffer);
+
+ fclose(mp4state.aacfile);
+ }
+ return 1;
}
- if(stricmp(mp4state.filename, medianame) != 0)
- {
- sQCDCallbacks.toPlayer.OutputStop(STOPFLAG_PLAYDONE);
+ return 0;
+}
+
+int Play(const char* medianame, int playfrom, int playto, int flags)
+{
+ WAVEFORMATEX wf;
+ //int maxlatency;
+ int thread_id;
+ int avg_bitrate, br, sr;
+ unsigned char *buffer;
+ int buffer_size;
+ faacDecConfigurationPtr config;
+
+#ifdef DEBUG_OUTPUT
+ in_mp4_DebugOutput("play");
+#endif
+
+ if (stricmp(mp4state.filename, medianame) != 0)
Stop(mp4state.filename, STOPFLAG_PLAYDONE);
- }
- if(mp4state.paused)
+ if (mp4state.paused)
{
// Update the player controls to reflect the new unpaused state
- sQCDCallbacks.toPlayer.OutputPause(0);
-
- Pause(medianame, PAUSE_DISABLED);
-
+ module.QCDCallbacks.toPlayer.OutputPause(0);
+
+ Pause(medianame, 0);
+
if (playfrom >= 0)
mp4state.seek_needed = playfrom;
}
- else if(play_thread_handle != INVALID_HANDLE_VALUE)
+ else if (PlayThreadAlive) // is playing
{
mp4state.seek_needed = playfrom;
- return TRUE;
+ return 1;
}
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;
+ memset(&mp4state, 0, sizeof(state));
- strcpy(mp4state.filename, medianame);
+ lstrcpy(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]);
+ if (!(mp4state.mp4file = MP4Read(mp4state.filename, 0)))
+ {
+ mp4state.filetype = 1;
+ } else {
+ MP4Close(mp4state.mp4file);
+ mp4state.filetype = 0;
+ }
+
+ if (mp4state.filetype)
+ {
+ int tagsize = 0, tmp = 0, init;
+ int bread = 0;
+ double length = 0.;
+ __int64 bitrate = 128;
+ faacDecFrameInfo frameInfo;
+
+ //module.is_seekable = 1;
+
+ if (!(mp4state.aacfile = fopen(mp4state.filename, "rb")))
+ {
+ // error
+ return -1;
+ }
+
+ tagsize = skip_id3v2_tag();
+ if (tagsize<0) return 0;
+
+ if (!(mp4state.m_aac_buffer = (unsigned char*)malloc(768*6)))
+ {
+ show_error(module.hMainWindow, "Memory allocation error.");
+ return -1;
+ }
+
+ for (init=0; init<2; init++)
+ {
+ mp4state.hDecoder = faacDecOpen();
+ if (!mp4state.hDecoder)
+ {
+ show_error(module.hMainWindow, "Unable to open decoder library.");
+ return -1;
+ }
+
+ config = faacDecGetCurrentConfiguration(mp4state.hDecoder);
+ config->outputFormat = m_resolution + 1;
+ config->downMatrix = m_downmix;
+ faacDecSetConfiguration(mp4state.hDecoder, config);
+
+ memset(mp4state.m_aac_buffer, 0, 768*6);
+ bread = fread(mp4state.m_aac_buffer, 1, 768*6, mp4state.aacfile);
+ mp4state.m_aac_bytes_into_buffer = bread;
+ mp4state.m_aac_bytes_consumed = 0;
+ mp4state.m_file_offset = 0;
+ mp4state.m_at_eof = (bread != 768*6) ? 1 : 0;
+
+ if (init==0)
+ {
+ faacDecFrameInfo frameInfo;
+
+ fill_buffer(&mp4state);
+
+ if ((mp4state.m_aac_bytes_consumed = faacDecInit(mp4state.hDecoder,
+ mp4state.m_aac_buffer, mp4state.m_aac_bytes_into_buffer,
+ &mp4state.samplerate, &mp4state.channels)) < 0)
+ {
+ show_error(module.hMainWindow, "Can't initialize decoder library.");
+ return -1;
+ }
+ advance_buffer(&mp4state, mp4state.m_aac_bytes_consumed);
+
+ do {
+ memset(&frameInfo, 0, sizeof(faacDecFrameInfo));
+ fill_buffer(&mp4state);
+ faacDecDecode(mp4state.hDecoder, &frameInfo, mp4state.m_aac_buffer, mp4state.m_aac_bytes_into_buffer);
+ } while (!frameInfo.samples && !frameInfo.error);
+
+ if (frameInfo.error)
+ {
+ show_error(module.hMainWindow, faacDecGetErrorMessage(frameInfo.error));
+ return -1;
+ }
+
+ mp4state.channels = frameInfo.channels;
+ mp4state.samplerate = frameInfo.samplerate;
+ mp4state.framesize = (frameInfo.channels != 0) ? frameInfo.samples/frameInfo.channels : 0;
+ /*
+ sbr = frameInfo.sbr;
+ profile = frameInfo.object_type;
+ header_type = frameInfo.header_type;
+ */
+
+ faacDecClose(mp4state.hDecoder);
+ fseek(mp4state.aacfile, tagsize, SEEK_SET);
+ }
+ }
+
+ mp4state.m_head = (struct seek_list*)malloc(sizeof(struct seek_list));
+ mp4state.m_tail = mp4state.m_head;
+ mp4state.m_tail->next = NULL;
+
+ mp4state.m_header_type = 0;
+ if ((mp4state.m_aac_buffer[0] == 0xFF) && ((mp4state.m_aac_buffer[1] & 0xF6) == 0xF0))
+ {
+ if (1) //(can_seek)
+ {
+ adts_parse(&mp4state, &bitrate, &length);
+ fseek(mp4state.aacfile, tagsize, SEEK_SET);
+
+ bread = fread(mp4state.m_aac_buffer, 1, 768*6, mp4state.aacfile);
+ if (bread != 768*6)
+ mp4state.m_at_eof = 1;
+ else
+ mp4state.m_at_eof = 0;
+ mp4state.m_aac_bytes_into_buffer = bread;
+ mp4state.m_aac_bytes_consumed = 0;
+
+ mp4state.m_header_type = 1;
+ }
+ } else if (memcmp(mp4state.m_aac_buffer, "ADIF", 4) == 0) {
+ int skip_size = (mp4state.m_aac_buffer[4] & 0x80) ? 9 : 0;
+ bitrate = ((unsigned int)(mp4state.m_aac_buffer[4 + skip_size] & 0x0F)<<19) |
+ ((unsigned int)mp4state.m_aac_buffer[5 + skip_size]<<11) |
+ ((unsigned int)mp4state.m_aac_buffer[6 + skip_size]<<3) |
+ ((unsigned int)mp4state.m_aac_buffer[7 + skip_size] & 0xE0);
+
+ length = (double)file_length(mp4state.aacfile);
+ if (length == -1)
+ {
+ //module.is_seekable = 0;
+ length = 0;
+ } else {
+ length = ((double)length*8.)/((double)bitrate) + 0.5;
+ }
+
+ mp4state.m_header_type = 2;
+ } else {
+ length = (double)file_length(mp4state.aacfile);
+ length = ((double)length*8.)/((double)bitrate*1000.) + 0.5;
+
+ //module.is_seekable = 1;
+ }
+
+ mp4state.m_length = (int)(length*1000.);
+
+ fill_buffer(&mp4state);
+ if ((mp4state.m_aac_bytes_consumed = faacDecInit(mp4state.hDecoder,
+ mp4state.m_aac_buffer, mp4state.m_aac_bytes_into_buffer,
+ &mp4state.samplerate, &mp4state.channels)) < 0)
+ {
+ show_error(module.hMainWindow, "Can't initialize decoder library.");
+ return -1;
+ }
+ advance_buffer(&mp4state, mp4state.m_aac_bytes_consumed);
+
+ if (mp4state.m_header_type == 2)
+ avg_bitrate = bitrate;
+ else
+ avg_bitrate = bitrate*1000;
+ } else {
+ mp4state.hDecoder = faacDecOpen();
+ if (!mp4state.hDecoder)
+ {
+ show_error(module.hMainWindow, "Unable to open decoder library.");
+ return -1;
+ }
+
+ config = faacDecGetCurrentConfiguration(mp4state.hDecoder);
+ config->outputFormat = m_resolution + 1;
+ config->downMatrix = m_downmix;
+ faacDecSetConfiguration(mp4state.hDecoder, config);
+
+ mp4state.mp4file = MP4Read(mp4state.filename, 0);
+ if (!mp4state.mp4file)
+ {
+ show_error(module.hMainWindow, "Unable to open file.");
+ faacDecClose(mp4state.hDecoder);
+ return -1;
+ }
+
+ if ((mp4state.mp4track = GetAACTrack(mp4state.mp4file)) < 0)
+ {
+ show_error(module.hMainWindow, "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);
+ if (buffer) free (buffer);
+ return -1;
+ }
+
+ /* for gapless decoding */
+ {
+ mp4AudioSpecificConfig mp4ASC;
+
+ mp4state.timescale = MP4GetTrackTimeScale(mp4state.mp4file, mp4state.mp4track);
+ mp4state.framesize = 1024;
+ mp4state.useAacLength = 0;
+
+ if (buffer)
+ {
+ if (AudioSpecificConfig(buffer, buffer_size, &mp4ASC) >= 0)
+ {
+ if (mp4ASC.frameLengthFlag == 1) mp4state.framesize = 960;
+ if (mp4ASC.sbr_present_flag == 1) mp4state.framesize *= 2;
+ }
+ }
+ }
+
+ 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(module.hMainWindow, "Number of channels not supported for playback.");
+ faacDecClose(mp4state.hDecoder);
+ if (mp4state.filetype)
+ fclose(mp4state.aacfile);
+ else
+ MP4Close(mp4state.mp4file);
+ return -1;
+ }
+
+ if (m_downmix && (mp4state.channels == 5 || mp4state.channels == 6))
+ mp4state.channels = 2;
+
+ 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 (!module.QCDCallbacks.toPlayer.OutputOpen(mp4state.filename, &wf)) // error opening device
+ {
+ faacDecClose(mp4state.hDecoder);
+ if (mp4state.filetype)
+ fclose(mp4state.aacfile);
+ else
+ MP4Close(mp4state.mp4file);
+ return -1;
+ }
+
+ mp4state.paused = 0;
+ mp4state.decode_pos_ms = 0;
+ mp4state.seek_needed = -1;
+
+ // initialize vis stuff
+ //module.SAVSAInit(maxlatency, mp4state.samplerate);
+ //module.VSASetInfo((int)mp4state.channels, mp4state.samplerate);
+
+ br = (int)floor(((float)avg_bitrate + 500.0)/1000.0 + 0.5);
+ sr = (int)floor((float)mp4state.samplerate/1000.0 + 0.5);
+ ai.struct_size = sizeof(AudioInfo);
+ ai.frequency = sr*1000;
+ ai.bitrate = br*1000;
+ ai.mode = (mp4state.channels == 2) ? 0 : 3;
+ ai.layer = 0;
+ ai.level = 0;
+ strcpy(ai.text, mp4state.filetype ? "AAC" : "MP4");
+ module.QCDCallbacks.Service(opSetAudioInfo, &ai, sizeof(AudioInfo), 0);
+
+ //module.outMod->SetVolume(-666); // set the output plug-ins default volume
+
+ killPlayThread = 0;
+
+ if (mp4state.filetype)
+ {
+ if ((play_thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AACPlayThread,
+ (void *)&killPlayThread, 0, &thread_id)) == NULL)
+ {
+ show_error(module.hMainWindow, "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(module.hMainWindow, "Cannot create playback thread");
+ faacDecClose(mp4state.hDecoder);
+ MP4Close(mp4state.mp4file);
+ return -1;
+ }
+ }
+
+ SetThreadAffinityMask(play_thread_handle, 1);
+
+ SetThreadPriority(play_thread_handle, priority_table[m_priority]);
}
- return TRUE;
+
+ return 1;
}
//-----------------------------------------------------------------------------
@@ -752,92 +1543,406 @@
#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;
-}
-//-----------------------------------------------------------------------------
+ mp4state.paused = flags;
-void SetVolume(int levelleft, int levelright, int flags)
-{
- QCDCallbacks->toPlayer.OutputSetVol(levelleft, levelright, flags);
+ if (module.QCDCallbacks.toPlayer.OutputPause(flags))
+ return 1;
+
+ mp4state.paused = !flags;
+ return 0;
}
+//void unpause()
+//{
+//#ifdef DEBUG_OUTPUT
+// in_mp4_DebugOutput("unpause");
+//#endif
+//
+// mp4state.paused = 0;
+// module.outMod->Pause(0);
+//}
+//
+//int ispaused()
+//{
+//#ifdef DEBUG_OUTPUT
+// in_mp4_DebugOutput("ispaused");
+//#endif
+//
+// return mp4state.paused;
+//}
+
//-----------------------------------------------------------------------------
-int GetCurrentPosition(const char* medianame, long *track, long *offset)
+void SetVolume(int levelleft, int levelright, int flags)
{
- return QCDCallbacks->toPlayer.OutputGetCurrentPosition((UINT*)offset, 0);
+#ifdef DEBUG_OUTPUT
+ in_mp4_DebugOutput("setvolume");
+#endif
+
+ module.QCDCallbacks.toPlayer.OutputSetVol(levelleft, levelright, flags);
}
+//void setpan(int pan)
+//{
+//#ifdef DEBUG_OUTPUT
+// in_mp4_DebugOutput("setpan");
+//#endif
+//
+// module.outMod->SetPan(pan);
+//}
+
//-----------------------------------------------------------------------------
int Stop(const char* medianame, int flags)
{
+ struct seek_list *target = mp4state.m_head;
+
#ifdef DEBUG_OUTPUT
- in_mp4_DebugOutput("stop");
+ in_mp4_DebugOutput("stop");
#endif
- if(medianame && *medianame && stricmp(mp4state.filename, medianame) == 0)
+
+ if (medianame && *medianame && stricmp(mp4state.filename, medianame) == 0)
{
- sQCDCallbacks.toPlayer.OutputStop(flags);
+ module.QCDCallbacks.toPlayer.OutputStop(flags);
+ killPlayThread = 1;
- 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);
+ if (play_thread_handle != INVALID_HANDLE_VALUE)
+ {
+ if (WaitForSingleObject(play_thread_handle, INFINITE) == WAIT_TIMEOUT)
+ TerminateThread(play_thread_handle,0);
+ CloseHandle(play_thread_handle);
+ play_thread_handle = INVALID_HANDLE_VALUE;
+ }
- mp4state.filename[0] = 0;
- if(mp4state.hDecoder)
- faacDecClose(mp4state.hDecoder);
- if (mp4state.filetype)
- fclose(mp4state.aacfile);
- else
- MP4Close(mp4state.mp4file);
+
+ if (mp4state.m_aac_buffer)
+ free(mp4state.m_aac_buffer);
+
+ while (target)
+ {
+ struct seek_list *tmp = target;
+ target = target->next;
+ if (tmp) free(tmp);
+ }
+ faacDecClose(mp4state.hDecoder);
+ if (mp4state.filetype)
+ fclose(mp4state.aacfile);
+ else
+ MP4Close(mp4state.mp4file);
+
+ //module.outMod->Close();
+ //module.SAVSADeInit();
+ mp4state.filename[0] = '\0';
+ mp4state.paused = 0;
}
-
- return TRUE;
+
+ return 1;
}
+int getsonglength(char *fn)
+{
+ long msDuration = 0;
+
+ if(!stricmp(fn + strlen(fn) - 3,"MP4") || !stricmp(fn + strlen(fn) - 3,"M4A"))
+ {
+ 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 {
+ int tagsize = 0;
+ int bread = 0;
+ double length = 0.;
+ __int64 bitrate = 128;
+ struct seek_list *target;
+ state len_state;
+
+ memset(&len_state, 0, sizeof(state));
+
+ if (!(len_state.aacfile = fopen(fn, "rb")))
+ {
+ // error
+ return 0;
+ }
+
+ len_state.m_at_eof = 0;
+
+ if (!(len_state.m_aac_buffer = (unsigned char*)malloc(768*6)))
+ {
+ //console::error("Memory allocation error.", "foo_mp4");
+ return 0;
+ }
+ memset(len_state.m_aac_buffer, 0, 768*6);
+
+ bread = fread(len_state.m_aac_buffer, 1, 768*6, len_state.aacfile);
+ len_state.m_aac_bytes_into_buffer = bread;
+ len_state.m_aac_bytes_consumed = 0;
+ len_state.m_file_offset = 0;
+
+ if (bread != 768*6)
+ len_state.m_at_eof = 1;
+
+ if (!memcmp(len_state.m_aac_buffer, "ID3", 3))
+ {
+ /* high bit is not used */
+ tagsize = (len_state.m_aac_buffer[6] << 21) | (len_state.m_aac_buffer[7] << 14) |
+ (len_state.m_aac_buffer[8] << 7) | (len_state.m_aac_buffer[9] << 0);
+
+ tagsize += 10;
+ advance_buffer(&len_state, tagsize);
+ }
+
+ len_state.m_head = (struct seek_list*)malloc(sizeof(struct seek_list));
+ len_state.m_tail = len_state.m_head;
+ len_state.m_tail->next = NULL;
+
+ len_state.m_header_type = 0;
+ if ((len_state.m_aac_buffer[0] == 0xFF) && ((len_state.m_aac_buffer[1] & 0xF6) == 0xF0))
+ {
+ if (1) //(m_reader->can_seek())
+ {
+ adts_parse(&len_state, &bitrate, &length);
+ fseek(len_state.aacfile, tagsize, SEEK_SET);
+
+ bread = fread(len_state.m_aac_buffer, 1, 768*6, len_state.aacfile);
+ if (bread != 768*6)
+ len_state.m_at_eof = 1;
+ else
+ len_state.m_at_eof = 0;
+ len_state.m_aac_bytes_into_buffer = bread;
+ len_state.m_aac_bytes_consumed = 0;
+
+ len_state.m_header_type = 1;
+ }
+ } else if (memcmp(len_state.m_aac_buffer, "ADIF", 4) == 0) {
+ int skip_size = (len_state.m_aac_buffer[4] & 0x80) ? 9 : 0;
+ bitrate = ((unsigned int)(len_state.m_aac_buffer[4 + skip_size] & 0x0F)<<19) |
+ ((unsigned int)len_state.m_aac_buffer[5 + skip_size]<<11) |
+ ((unsigned int)len_state.m_aac_buffer[6 + skip_size]<<3) |
+ ((unsigned int)len_state.m_aac_buffer[7 + skip_size] & 0xE0);
+
+ length = (double)file_length(len_state.aacfile);
+ if (length == -1)
+ length = 0;
+ else
+ length = ((double)length*8.)/((double)bitrate) + 0.5;
+
+ len_state.m_header_type = 2;
+ } else {
+ length = (double)file_length(len_state.aacfile);
+ length = ((double)length*8.)/((double)bitrate*1000.) + 0.5;
+
+ len_state.m_header_type = 0;
+ }
+
+ if (len_state.m_aac_buffer)
+ free(len_state.m_aac_buffer);
+
+ target = len_state.m_head;
+ while (target)
+ {
+ struct seek_list *tmp = target;
+ target = target->next;
+ if (tmp) free(tmp);
+ }
+
+ fclose(len_state.aacfile);
+
+ return (int)(length*1000.);
+ }
+}
+
+//int getlength()
+//{
+// if (!mp4state.filetype)
+// {
+// int track;
+// long msDuration;
+// MP4Duration length;
+//
+// if ((track = GetAACTrack(mp4state.mp4file)) < 0)
+// {
+// return -1;
+// }
+//
+// length = MP4GetTrackDuration(mp4state.mp4file, track);
+//
+// msDuration = MP4ConvertFromTrackDuration(mp4state.mp4file, track,
+// length, MP4_MSECS_TIME_SCALE);
+//
+// return msDuration;
+// } else {
+// return mp4state.m_length;
+// }
+// return 0;
+//}
+
+//-----------------------------------------------------------------------------
+
+int GetCurrentPosition(const char* medianame, long *track, long *offset)
+{
+ return module.QCDCallbacks.toPlayer.OutputGetCurrentPosition((UINT*)offset, 0);
+}
+
+//void setoutputtime(int time_in_ms)
+//{
+//#ifdef DEBUG_OUTPUT
+// in_mp4_DebugOutput("setoutputtime");
+//#endif
+//
+// mp4state.seek_needed = time_in_ms;
+//}
+
+//-----------------------------------------------------------------------------
+
+int GetTrackExtents(const char* medianame, TrackExtents *ext, int flags)
+{
+ int len;
+ FILE *fh;
+
+ len = getsonglength((char *)medianame);
+ fh = fopen(medianame, "rb");
+ if (len <= 0 || !fh)
+ return 0;
+
+ ext->track = 1;
+ ext->start = 0;
+ ext->end = len;
+ ext->bytesize = file_length(fh);
+ fclose(fh);
+ ext->unitpersec = 1000;
+
+ return 1;
+}
+
+//void eq_set(int on, char data[10], int preamp)
+//{
+//}
+
+static void remap_channels(unsigned char *data, unsigned int samples, unsigned int bps)
+{
+ unsigned int i;
+
+ switch (bps)
+ {
+ case 8:
+ {
+ unsigned char r1, r2, r3, r4, r5, r6;
+ for (i = 0; i < samples; i += 6)
+ {
+ r1 = data[i];
+ r2 = data[i+1];
+ r3 = data[i+2];
+ r4 = data[i+3];
+ r5 = data[i+4];
+ r6 = data[i+5];
+ data[i] = r2;
+ data[i+1] = r3;
+ data[i+2] = r1;
+ data[i+3] = r6;
+ data[i+4] = r4;
+ data[i+5] = r5;
+ }
+ }
+ break;
+
+ case 16:
+ default:
+ {
+ unsigned short r1, r2, r3, r4, r5, r6;
+ unsigned short *sample_buffer = (unsigned short *)data;
+ for (i = 0; i < samples; i += 6)
+ {
+ r1 = sample_buffer[i];
+ r2 = sample_buffer[i+1];
+ r3 = sample_buffer[i+2];
+ r4 = sample_buffer[i+3];
+ r5 = sample_buffer[i+4];
+ r6 = sample_buffer[i+5];
+ sample_buffer[i] = r2;
+ sample_buffer[i+1] = r3;
+ sample_buffer[i+2] = r1;
+ sample_buffer[i+3] = r6;
+ sample_buffer[i+4] = r4;
+ sample_buffer[i+5] = r5;
+ }
+ }
+ break;
+
+ case 24:
+ case 32:
+ {
+ unsigned int r1, r2, r3, r4, r5, r6;
+ unsigned int *sample_buffer = (unsigned int *)data;
+ for (i = 0; i < samples; i += 6)
+ {
+ r1 = sample_buffer[i];
+ r2 = sample_buffer[i+1];
+ r3 = sample_buffer[i+2];
+ r4 = sample_buffer[i+3];
+ r5 = sample_buffer[i+4];
+ r6 = sample_buffer[i+5];
+ sample_buffer[i] = r2;
+ sample_buffer[i+1] = r3;
+ sample_buffer[i+2] = r1;
+ sample_buffer[i+3] = r6;
+ sample_buffer[i+4] = r4;
+ sample_buffer[i+5] = r5;
+ }
+ }
+ break;
+ }
+}
+
DWORD WINAPI MP4PlayThread(void *b)
{
- BOOL done = FALSE, updatePos = FALSE;
+ int done = 0, updatepos = 0;
int l;
+ int seq_frames = 0;
+ int seq_bytes = 0;
void *sample_buffer;
unsigned char *buffer;
- int buffer_size, ms;
+ int buffer_size;
faacDecFrameInfo frameInfo;
+ WriteDataStruct wd;
+
#ifdef DEBUG_OUTPUT
in_mp4_DebugOutput("MP4PlayThread");
#endif
+ PlayThreadAlive = 1;
mp4state.last_frame = 0;
+ mp4state.initial = 1;
while (!*((int *)b))
{
/* seeking */
- if (!done && mp4state.seek_needed != -1)
+ if (mp4state.seek_needed != -1)
{
MP4Duration duration;
- QCDCallbacks->toPlayer.OutputFlush(mp4state.decode_pos_ms);
+ module.QCDCallbacks.toPlayer.OutputFlush((unsigned int)mp4state.decode_pos_ms);
duration = MP4ConvertToTrackDuration(mp4state.mp4file,
mp4state.mp4track, mp4state.seek_needed, MP4_MSECS_TIME_SCALE);
mp4state.sampleId = MP4GetSampleIdFromTime(mp4state.mp4file,
@@ -844,37 +1949,37 @@
mp4state.mp4track, duration, 0);
mp4state.decode_pos_ms = mp4state.seek_needed;
- mp4state.seek_needed = -1;
- updatePos = TRUE;
+ mp4state.seek_needed = -1;
}
- /* quit */
- if (done)
- {
- if (QCDCallbacks->toPlayer.OutputDrain(0) && !(mp4state.seek_needed >= 0))
+
+ if (done)
+ {
+ if (module.QCDCallbacks.toPlayer.OutputDrain(0) && !(mp4state.seek_needed >= 0))
{
- play_thread_handle = INVALID_HANDLE_VALUE;
- QCDCallbacks->toPlayer.OutputStop(STOPFLAG_PLAYDONE);
- QCDCallbacks->toPlayer.PlayDone(mp4state.filename);
+ module.QCDCallbacks.toPlayer.OutputStop(STOPFLAG_PLAYDONE);
+ module.QCDCallbacks.toPlayer.PlayDone(mp4state.filename);
+ PlayThreadAlive = 0;
}
else if (mp4state.seek_needed >= 0)
{
- done = FALSE;
+ done = 0;
continue;
}
break;
- }
- /* decoding */
- else
- {
+ } else/* if (module.outMod->CanWrite() >= (2048*mp4state.channels*sizeof(short)))*/ {
if (mp4state.last_frame)
{
- done = TRUE;
- }
- else
- {
+ done = 1;
+ } else {
int rc;
+ /* for gapless decoding */
+ char *buf;
+ MP4Duration dur;
+ unsigned int sample_count;
+ unsigned int delay = 0;
+
/* get acces unit from MP4 file */
buffer = NULL;
buffer_size = 0;
@@ -881,234 +1986,441 @@
rc = MP4ReadSample(mp4state.mp4file, mp4state.mp4track,
mp4state.sampleId++, &buffer, &buffer_size,
- NULL, NULL, NULL, NULL);
+ NULL, &dur, NULL, NULL);
+ if (mp4state.sampleId-1 == 1) dur = 0;
if (rc == 0 || buffer == NULL)
{
mp4state.last_frame = 1;
sample_buffer = NULL;
frameInfo.samples = 0;
- }
- else
- {
+ } else {
sample_buffer = faacDecDecode(mp4state.hDecoder, &frameInfo,
buffer, buffer_size);
}
if (frameInfo.error > 0)
{
- show_error(hwndPlayer, faacDecGetErrorMessage(frameInfo.error));
+ show_error(module.hMainWindow, faacDecGetErrorMessage(frameInfo.error));
mp4state.last_frame = 1;
}
- if (mp4state.sampleId >= mp4state.numSamples)
+ if (mp4state.sampleId > mp4state.numSamples)
mp4state.last_frame = 1;
if (buffer) free(buffer);
- if (!killPlayThread && (frameInfo.samples > 0))
+ if (mp4state.useAacLength || (mp4state.timescale != mp4state.samplerate)) {
+ sample_count = frameInfo.samples;
+ } else {
+ sample_count = (unsigned int)(dur * frameInfo.channels);
+
+ if (!mp4state.useAacLength && !mp4state.initial && (mp4state.sampleId < mp4state.numSamples/2) && (dur*frameInfo.channels != frameInfo.samples))
+ {
+ //fprintf(stderr, "MP4 seems to have incorrect frame duration, using values from AAC data.\n");
+ mp4state.useAacLength = 1;
+ sample_count = frameInfo.samples;
+ }
+ }
+
+ if (mp4state.initial && (sample_count < mp4state.framesize*mp4state.channels) && (frameInfo.samples > sample_count))
{
+ delay = frameInfo.samples - sample_count;
+ }
+
+ if (!killPlayThread && (sample_count > 0))
+ {
+ buf = (char *)sample_buffer;
+ mp4state.initial = 0;
+
+ switch (res_table[m_resolution])
+ {
+ case 8:
+ buf += delay;
+ break;
+ case 16:
+ default:
+ buf += delay * 2;
+ break;
+ case 24:
+ case 32:
+ buf += delay * 4;
+ break;
+ case 64:
+ buf += delay * 8;
+ }
+
+ if (frameInfo.channels == 6 && frameInfo.num_lfe_channels)
+ remap_channels(buf, sample_count, res_table[m_resolution]);
+
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);
+ char *temp_buffer = convert3in4to3in3(buf, sample_count);
+ memcpy((void*)buf, (void*)temp_buffer, sample_count*3);
free(temp_buffer);
}
- ms = (int)floor(((float)frameInfo.samples*1000.0) /
- ((float)mp4state.samplerate*(float)frameInfo.channels));
- mp4state.decode_pos_ms += ms;
+ //module.SAAddPCMData(buf, (int)mp4state.channels, res_table[m_resolution],
+ // mp4state.decode_pos_ms);
+ //module.VSAAddPCMData(buf, (int)mp4state.channels, res_table[m_resolution],
+ // mp4state.decode_pos_ms);
+ mp4state.decode_pos_ms += (double)sample_count * 1000.0 /
+ ((double)frameInfo.samplerate * (double)frameInfo.channels);
- l = frameInfo.samples * res_table[m_resolution] / 8;
+ l = sample_count * res_table[m_resolution] / 8;
- if (updatePos)
+ if (updatepos)
{
- QCDCallbacks->toPlayer.PositionUpdate(mp4state.decode_pos_ms);
- updatePos = FALSE;
+ module.QCDCallbacks.toPlayer.PositionUpdate((unsigned int)mp4state.decode_pos_ms);
+ updatepos = 0;
}
- {
- 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;
+ wd.bytelen = l;
+ wd.data = (short*)buf;
+ wd.markerend = 0;
+ wd.markerstart = (UINT)mp4state.decode_pos_ms;
+ wd.bps = res_table[m_resolution];
+ wd.nch = frameInfo.channels;
+ wd.numsamples = sample_count/frameInfo.channels;
+ wd.srate = frameInfo.samplerate;
- if (!QCDCallbacks->toPlayer.OutputWrite(&wd))
- done = TRUE;
+ if (!module.QCDCallbacks.toPlayer.OutputWrite(&wd))
+ done = 1;
+
+ //if (module.dsp_isactive())
+ //{
+ // void *dsp_buffer = malloc(l*2);
+ // memcpy(dsp_buffer, buf, l);
+
+ // l = module.dsp_dosamples((short*)dsp_buffer,
+ // sample_count/frameInfo.channels,
+ // res_table[m_resolution],
+ // frameInfo.channels,
+ // frameInfo.samplerate) *
+ // (frameInfo.channels*(res_table[m_resolution]/8));
+
+ // module.outMod->Write(dsp_buffer, l);
+ // if (dsp_buffer) free(dsp_buffer);
+ //} else {
+ // module.outMod->Write(buf, l);
+ //}
+
+ /* VBR bitrate display */
+ if (m_vbr_display)
+ {
+ seq_frames++;
+ seq_bytes += frameInfo.bytesconsumed;
+ if (seq_frames == (int)(floor((float)frameInfo.samplerate/(float)(sample_count/frameInfo.channels) + 0.5)))
+ {
+ ai.bitrate = (int)floor(((float)seq_bytes*8.)/1000. + 0.5) * 1000;
+ ai.frequency = (int)floor(frameInfo.samplerate/1000. + 0.5) * 1000;
+ ai.mode = (mp4state.channels == 2) ? 0 : 3;
+ module.QCDCallbacks.Service(opSetAudioInfo, &ai, sizeof(AudioInfo), 0);
+
+ seq_frames = 0;
+ seq_bytes = 0;
+ }
}
}
}
}
+
Sleep(10);
+
+ // catch pause
+ while (mp4state.paused && !killPlayThread)
+ Sleep(50);
}
- // close up
- play_thread_handle = INVALID_HANDLE_VALUE;
+ PlayThreadAlive = 0;
- return 0;
+ return 0;
}
+void *decode_aac_frame(state *st, faacDecFrameInfo *frameInfo)
+{
+ void *sample_buffer = NULL;
+
+ do
+ {
+ fill_buffer(st);
+
+ if (st->m_aac_bytes_into_buffer != 0)
+ {
+ sample_buffer = faacDecDecode(st->hDecoder, frameInfo,
+ st->m_aac_buffer, st->m_aac_bytes_into_buffer);
+
+ if (st->m_header_type != 1)
+ {
+ if (st->last_offset < st->m_file_offset)
+ {
+ st->m_tail->offset = st->m_file_offset;
+ st->m_tail->next = (struct seek_list*)malloc(sizeof(struct seek_list));
+ st->m_tail = st->m_tail->next;
+ st->m_tail->next = NULL;
+ st->last_offset = st->m_file_offset;
+ }
+ }
+
+ advance_buffer(st, frameInfo->bytesconsumed);
+ } else {
+ break;
+ }
+
+ } while (!frameInfo->samples && !frameInfo->error);
+
+ return sample_buffer;
+}
+
+int aac_seek(state *st, double seconds)
+{
+ int i, frames;
+ int bread;
+ struct seek_list *target = st->m_head;
+
+ if (1 /*can_seek*/ && ((st->m_header_type == 1) || (seconds < st->cur_pos_sec)))
+ {
+ frames = (int)(seconds*((double)st->samplerate/(double)st->framesize) + 0.5);
+
+ for (i = 0; i < frames; i++)
+ {
+ if (target->next)
+ target = target->next;
+ else
+ return 0;
+ }
+ if (target->offset == 0 && frames > 0)
+ return 0;
+ fseek(st->aacfile, target->offset, SEEK_SET);
+ st->m_file_offset = target->offset;
+
+ bread = fread(st->m_aac_buffer, 1, 768*6, st->aacfile);
+ if (bread != 768*6)
+ st->m_at_eof = 1;
+ else
+ st->m_at_eof = 0;
+ st->m_aac_bytes_into_buffer = bread;
+ st->m_aac_bytes_consumed = 0;
+ st->m_file_offset += bread;
+
+ faacDecPostSeekReset(st->hDecoder, -1);
+
+ return 1;
+ } else {
+ if (seconds > st->cur_pos_sec)
+ {
+ faacDecFrameInfo frameInfo;
+
+ frames = (int)((seconds - st->cur_pos_sec)*((double)st->samplerate/(double)st->framesize));
+
+ if (frames > 0)
+ {
+ for (i = 0; i < frames; i++)
+ {
+ memset(&frameInfo, 0, sizeof(faacDecFrameInfo));
+ decode_aac_frame(st, &frameInfo);
+
+ if (frameInfo.error || (st->m_aac_bytes_into_buffer == 0))
+ {
+ if (frameInfo.error)
+ {
+ if (faacDecGetErrorMessage(frameInfo.error) != NULL)
+ show_error(module.hMainWindow, faacDecGetErrorMessage(frameInfo.error));
+ }
+ return 0;
+ }
+ }
+ }
+
+ faacDecPostSeekReset(st->hDecoder, -1);
+ }
+ return 1;
+ }
+}
+
DWORD WINAPI AACPlayThread(void *b)
{
- BOOL done = FALSE, updatePos = FALSE;
- int l, ms;
+ int done = 0, updatepos = 0;
+ int l;
+ int seq_frames = 0;
+ int seq_bytes = 0;
- void *sample_buffer;
- faacDecFrameInfo frameInfo;
+ WriteDataStruct wd;
#ifdef DEBUG_OUTPUT
in_mp4_DebugOutput("AACPlayThread");
#endif
+ PlayThreadAlive = 1;
mp4state.last_frame = 0;
while (!*((int *)b))
{
-#if 0
/* seeking */
- if (!done && mp4state.seek_needed != -1)
+ if (mp4state.seek_needed != -1)
{
- int ms;
+ double 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;
+ ms = mp4state.seek_needed/1000;
+ if (aac_seek(&mp4state, ms)!=0)
+ {
+ module.QCDCallbacks.toPlayer.OutputFlush((unsigned int)mp4state.decode_pos_ms);
+ mp4state.cur_pos_sec = ms;
+ mp4state.decode_pos_ms = mp4state.seek_needed;
+ }
mp4state.seek_needed = -1;
- updatePos = TRUE;
}
-#endif
- /* quit */
- if (done)
- {
- if (QCDCallbacks->toPlayer.OutputDrain(0) && !(mp4state.seek_needed >= 0))
+
+ if (done)
+ {
+ if (module.QCDCallbacks.toPlayer.OutputDrain(0) && !(mp4state.seek_needed >= 0))
{
- QCDCallbacks->toPlayer.OutputStop(STOPFLAG_PLAYDONE);
- QCDCallbacks->toPlayer.PlayDone(mp4state.filename);
+ module.QCDCallbacks.toPlayer.OutputStop(STOPFLAG_PLAYDONE);
+ module.QCDCallbacks.toPlayer.PlayDone(mp4state.filename);
+ PlayThreadAlive = 0;
}
else if (mp4state.seek_needed >= 0)
{
- done = FALSE;
+ done = 0;
continue;
}
break;
- }
+ } else/* if (module.outMod->CanWrite() >= (2048*mp4state.channels*sizeof(short)))*/ {
+ faacDecFrameInfo frameInfo;
+ void *sample_buffer;
- /* decoding */
- else
- {
- if (mp4state.last_frame)
- {
- done = TRUE;
- }
- else
- {
- long tmp, read;
- unsigned char *buffer = mp4state.buffer;
+ memset(&frameInfo, 0, sizeof(faacDecFrameInfo));
- do
- {
- if (mp4state.bytes_consumed > 0)
- {
- if (mp4state.bytes_into_buffer)
- {
- memcpy(buffer, buffer+mp4state.bytes_consumed,
- mp4state.bytes_into_buffer);
- }
+ sample_buffer = decode_aac_frame(&mp4state, &frameInfo);
- 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);
- }
- }
+ if (frameInfo.error || (mp4state.m_aac_bytes_into_buffer == 0))
+ {
+ if (frameInfo.error)
+ {
+ if (faacDecGetErrorMessage(frameInfo.error) != NULL)
+ show_error(module.hMainWindow, faacDecGetErrorMessage(frameInfo.error));
+ }
+ done = 1;
+ }
+
+ if (!killPlayThread && (frameInfo.samples > 0))
+ {
+ if (frameInfo.channels == 6 && frameInfo.num_lfe_channels)
+ remap_channels(sample_buffer, frameInfo.samples, res_table[m_resolution]);
- mp4state.bytes_consumed = 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);
+ }
- 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;
- }
- }
+ //module.SAAddPCMData(sample_buffer, (int)mp4state.channels, res_table[m_resolution],
+ // mp4state.decode_pos_ms);
+ //module.VSAAddPCMData(sample_buffer, (int)mp4state.channels, res_table[m_resolution],
+ // mp4state.decode_pos_ms);
+ mp4state.decode_pos_ms += (double)frameInfo.samples * 1000.0 /
+ ((double)frameInfo.samplerate* (double)frameInfo.channels);
- sample_buffer = faacDecDecode(mp4state.hDecoder, &frameInfo,
- buffer, mp4state.bytes_into_buffer);
+ l = frameInfo.samples * res_table[m_resolution] / 8;
- mp4state.bytes_consumed += frameInfo.bytesconsumed;
- mp4state.bytes_into_buffer -= mp4state.bytes_consumed;
- } while (!frameInfo.samples && !frameInfo.error);
+ if (updatepos)
+ {
+ module.QCDCallbacks.toPlayer.PositionUpdate((unsigned int)mp4state.decode_pos_ms);
+ updatepos = 0;
+ }
- 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);
- }
+ wd.bytelen = l;
+ wd.data = (short*)sample_buffer;
+ wd.markerend = 0;
+ wd.markerstart = (UINT)mp4state.decode_pos_ms;
+ wd.bps = res_table[m_resolution];
+ wd.nch = frameInfo.channels;
+ wd.numsamples = frameInfo.samples/frameInfo.channels;
+ wd.srate = frameInfo.samplerate;
- ms = (int)floor(((float)frameInfo.samples*1000.0) /
- ((float)mp4state.samplerate*(float)frameInfo.channels));
- mp4state.decode_pos_ms += ms;
+ if (!module.QCDCallbacks.toPlayer.OutputWrite(&wd))
+ done = 1;
- l = frameInfo.samples * res_table[m_resolution] / 8;
+ //if (module.dsp_isactive())
+ //{
+ // void *dsp_buffer = malloc(l*2);
+ // memcpy(dsp_buffer, sample_buffer, l);
- if (updatePos)
- {
- QCDCallbacks->toPlayer.PositionUpdate(mp4state.decode_pos_ms);
- updatePos = FALSE;
- }
- {
- WriteDataStruct wd;
+ // l = module.dsp_dosamples((short*)dsp_buffer,
+ // frameInfo.samples/frameInfo.channels,
+ // res_table[m_resolution],
+ // frameInfo.channels,
+ // frameInfo.samplerate) *
+ // (frameInfo.channels*(res_table[m_resolution]/8));
- 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;
+ // module.outMod->Write(dsp_buffer, l);
+ // if (dsp_buffer) free(dsp_buffer);
+ //} else {
+ // module.outMod->Write(sample_buffer, l);
+ //}
- if (!QCDCallbacks->toPlayer.OutputWrite(&wd))
- done = TRUE;
- }
+ /* VBR bitrate display */
+ if (m_vbr_display)
+ {
+ seq_frames++;
+ seq_bytes += frameInfo.bytesconsumed;
+ if (seq_frames == (int)(floor((float)frameInfo.samplerate/(float)(frameInfo.samples/frameInfo.channels) + 0.5)))
+ {
+ ai.bitrate = (int)floor(((float)seq_bytes*8.)/1000. + 0.5) * 1000;
+ ai.frequency = (int)floor(frameInfo.samplerate/1000. + 0.5) * 1000;
+ ai.mode = (mp4state.channels == 2) ? 0 : 3;
+ module.QCDCallbacks.Service(opSetAudioInfo, &ai, sizeof(AudioInfo), 0);
+
+ seq_frames = 0;
+ seq_bytes = 0;
+ }
}
}
- }
+
+ if (frameInfo.channels > 0 && mp4state.samplerate > 0)
+ mp4state.cur_pos_sec += ((double)(frameInfo.samples/frameInfo.channels))/(double)mp4state.samplerate;
+ }
+
Sleep(10);
+
+ // catch pause
+ while (mp4state.paused && !killPlayThread)
+ Sleep(50);
}
- // close up
- play_thread_handle = INVALID_HANDLE_VALUE;
+ PlayThreadAlive = 0;
return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+int WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID pRes)
+{
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ {
+ module.hInstance = hInst;
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+PLUGIN_API QCDModInitIn* INPUTDLL_ENTRY_POINT(QCDModInitIn *ModInit, QCDModInfo *ModInfo)
+{
+ module.QCDCallbacks.size = sizeof(QCDModInitIn);
+ module.QCDCallbacks.version = PLUGIN_API_VERSION;
+ module.QCDCallbacks.toModule.Initialize = Initialize;
+ module.QCDCallbacks.toModule.ShutDown = ShutDown;
+ module.QCDCallbacks.toModule.GetTrackExtents = GetTrackExtents;
+ module.QCDCallbacks.toModule.GetMediaSupported = GetMediaSupported;
+ module.QCDCallbacks.toModule.Play = Play;
+ module.QCDCallbacks.toModule.Pause = Pause;
+ module.QCDCallbacks.toModule.Stop = Stop;
+ module.QCDCallbacks.toModule.About = About;
+ module.QCDCallbacks.toModule.Configure = Configure;
+ module.QCDCallbacks.toModule.SetEQ = NULL;
+ module.QCDCallbacks.toModule.SetVolume = SetVolume;
+
+ return &module.QCDCallbacks;
}
--- a/plugins/QCDMp4/QCDMp4.dsp
+++ b/plugins/QCDMp4/QCDMp4.dsp
@@ -25,7 +25,7 @@
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
MTL=midl.exe
RSC=rc.exe
@@ -43,7 +43,7 @@
# 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 CPP /nologo /MD /W3 /GX /O1 /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"
@@ -51,7 +51,7 @@
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.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
@@ -69,7 +69,7 @@
# 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 CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "..\..\common\mp4v2" /I "..\..\common\mp4av" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /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"
@@ -77,7 +77,7 @@
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.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
@@ -96,10 +96,6 @@
# End Source File
# Begin Source File
-SOURCE=.\AAC2Mp4Enc.c
-# End Source File
-# Begin Source File
-
SOURCE=.\aacinfo.c
# End Source File
# Begin Source File
@@ -112,6 +108,10 @@
# End Source File
# Begin Source File
+SOURCE=.\QCDMp4Tag.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\utils.c
# End Source File
# End Group
@@ -120,10 +120,6 @@
# 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
@@ -136,31 +132,23 @@
# 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
+SOURCE=.\QCDModInput.h
# End Source File
# Begin Source File
-SOURCE=.\QCDModEncode.h
+SOURCE=.\QCDTagsDLL.h
# End Source File
# Begin Source File
-SOURCE=.\QCDModInput.h
+SOURCE=.\QCDModTagEditor.h
# End Source File
# Begin Source File
-SOURCE=.\resource.h
+SOURCE=.\QCDModDefs.h
# End Source File
# Begin Source File
@@ -170,10 +158,6 @@
# 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
--- a/plugins/QCDMp4/QCDMp4.dsw
+++ b/plugins/QCDMp4/QCDMp4.dsw
@@ -3,7 +3,7 @@
###############################################################################
-Project: "QCDMp4"=".\QCDMp4.dsp" - Package Owner=<4>
+Project: "QCDMp4"=.\QCDMp4.dsp - Package Owner=<4>
Package=<5>
{{{
@@ -15,16 +15,16 @@
Project_Dep_Name libfaad
End Project Dependency
Begin Project Dependency
- Project_Dep_Name libmp4av_st
+ Project_Dep_Name libmp4v2_st
End Project Dependency
Begin Project Dependency
- Project_Dep_Name libmp4v2_st
+ Project_Dep_Name libmp4av_st
End Project Dependency
}}}
###############################################################################
-Project: "libfaad"="..\..\libfaad\libfaad.dsp" - Package Owner=<4>
+Project: "libfaad"=..\..\libfaad\libfaad.dsp - Package Owner=<4>
Package=<5>
{{{
@@ -36,7 +36,7 @@
###############################################################################
-Project: "libmp4av_st"="..\..\common\mp4av\libmp4av_st.dsp" - Package Owner=<4>
+Project: "libmp4av_st"=..\..\common\mp4av\libmp4av_st.dsp - Package Owner=<4>
Package=<5>
{{{
@@ -48,7 +48,7 @@
###############################################################################
-Project: "libmp4v2_st"="..\..\common\mp4v2\libmp4v2_st60.dsp" - Package Owner=<4>
+Project: "libmp4v2_st"=..\..\common\mp4v2\libmp4v2_st60.dsp - Package Owner=<4>
Package=<5>
{{{
--- a/plugins/QCDMp4/QCDMp4.rc
+++ b/plugins/QCDMp4/QCDMp4.rc
@@ -1,4 +1,4 @@
-//Microsoft Developer Studio generated resource script.
+// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
@@ -13,7 +13,7 @@
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
-// Dutch (Netherlands) resources
+// ������(����) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NLD)
#ifdef _WIN32
@@ -27,18 +27,18 @@
// TEXTINCLUDE
//
-1 TEXTINCLUDE MOVEABLE PURE
+1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
-2 TEXTINCLUDE MOVEABLE PURE
+2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
-3 TEXTINCLUDE MOVEABLE PURE
+3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
@@ -52,10 +52,11 @@
// Dialog
//
-IDD_CONFIG_INPUT DIALOG DISCARDABLE 0, 0, 151, 108
-STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
+IDD_CONFIG DIALOGEX 0, 0, 233, 93
+STYLE DS_SETFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
CAPTION "Configuration"
-FONT 8, "MS Sans Serif"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
CONTROL "Slider1",IDC_PRIORITY,"msctls_trackbar32",TBS_VERT |
TBS_NOTICKS | WS_TABSTOP,13,15,18,46
@@ -62,17 +63,21 @@
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
+ BS_AUTORADIOBUTTON | WS_DISABLED,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 "Downmix to stereo",IDC_DOWNMIX,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,152,13,74,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
+ WS_TABSTOP,152,26,55,10
+ CONTROL "VBR Display",IDC_VBR,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,152,39,55,10
+ CONTROL "Show errors",IDC_ERROR,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,152,52,53,10
+ DEFPUSHBUTTON "OK",IDOK,176,72,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,115,72,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
@@ -80,39 +85,7 @@
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
@@ -119,41 +92,19 @@
//
#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO MOVEABLE PURE
+GUIDELINES DESIGNINFO
BEGIN
- IDD_CONFIG_INPUT, DIALOG
+ IDD_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 7
- RIGHTMARGIN, 144
+ RIGHTMARGIN, 226
TOPMARGIN, 7
- BOTTOMMARGIN, 101
+ BOTTOMMARGIN, 86
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
+#endif // ������(����) resources
/////////////////////////////////////////////////////////////////////////////
--- a/plugins/QCDMp4/QCDMp4.sln
+++ b/plugins/QCDMp4/QCDMp4.sln
@@ -1,21 +1,27 @@
-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}"
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QCDMp4", "QCDMp4.vcproj", "{2D8F479D-A591-4502-9456-398425D5F834}"
+ ProjectSection(ProjectDependencies) = postProject
+ {2398BB2F-FFF9-490B-B4CC-863F2D21AE46} = {2398BB2F-FFF9-490B-B4CC-863F2D21AE46}
+ {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49} = {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}
+ {82CAD808-21AF-40A6-92EC-AE01AA67B413} = {82CAD808-21AF-40A6-92EC-AE01AA67B413}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaad", "..\..\libfaad\libfaad.vcproj", "{82CAD808-21AF-40A6-92EC-AE01AA67B413}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmp4v2_st", "..\..\common\mp4v2\libmp4v2_st60.vcproj", "{2398BB2F-FFF9-490B-B4CC-863F2D21AE46}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmp4av_st", "..\..\common\mp4av\libmp4av_st.vcproj", "{8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
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}
+ Debug = Debug
+ Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{2D8F479D-A591-4502-9456-398425D5F834}.Debug.ActiveCfg = Debug|Win32
--- a/plugins/QCDMp4/QCDMp4.vcproj
+++ b/plugins/QCDMp4/QCDMp4.vcproj
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
+<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="7.00"
- Name="in_mp4"
+ Version="7.10"
+ Name="QCDMp4"
SccProjectName=""
SccLocalPath="">
<Platforms>
@@ -25,7 +25,7 @@
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
- PrecompiledHeaderFile=".\Debug/in_mp4.pch"
+ PrecompiledHeaderFile=".\Debug/QCDMp4.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
@@ -32,14 +32,7 @@
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>
+ CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
@@ -46,16 +39,13 @@
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="ws2_32.lib odbc32.lib odbccp32.lib"
- OutputFile=".\Debug/in_mp4.dll"
+ OutputFile=".\Debug/QCDMp4.dll"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\Debug/in_mp4.pdb"
+ ProgramDatabaseFile=".\Debug/QCDMp4.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>
+ ImportLibrary=".\Debug/QCDMp4.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
@@ -62,7 +52,7 @@
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
- TypeLibraryName=".\Debug/in_mp4.tlb"/>
+ TypeLibraryName=".\Debug/QCDMp4.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
@@ -76,7 +66,13 @@
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
@@ -98,24 +94,13 @@
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
- PrecompiledHeaderFile=".\Release/in_mp4.pch"
+ PrecompiledHeaderFile=".\Release/QCDMp4.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>
+ CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
@@ -122,15 +107,12 @@
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="ws2_32.lib"
- OutputFile=".\Release/in_mp4.dll"
+ OutputFile=".\Release/QCDMp4.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
- ProgramDatabaseFile=".\Release/in_mp4.pdb"
+ ProgramDatabaseFile=".\Release/QCDMp4.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>
+ ImportLibrary=".\Release/QCDMp4.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
@@ -137,7 +119,7 @@
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
- TypeLibraryName=".\Release/in_mp4.tlb"/>
+ TypeLibraryName=".\Release/QCDMp4.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
@@ -151,50 +133,85 @@
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
+ <References>
+ </References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
- RelativePath="aac2mp4.cpp"/>
+ RelativePath="aac2mp4.cpp">
+ </File>
<File
- RelativePath="aacinfo.c"/>
+ RelativePath="aacinfo.c">
+ </File>
<File
- RelativePath=".\config.c"/>
+ RelativePath=".\config.c">
+ </File>
<File
- RelativePath=".\in_mp4.c"/>
+ RelativePath=".\QCDMp4.c">
+ </File>
<File
- RelativePath=".\utils.c"/>
+ RelativePath=".\QCDMp4Tag.cpp">
+ </File>
+ <File
+ RelativePath=".\utils.c">
+ </File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
- RelativePath="aac2mp4.h"/>
+ RelativePath="aac2mp4.h">
+ </File>
<File
- RelativePath="aacinfo.h"/>
+ RelativePath="aacinfo.h">
+ </File>
<File
- RelativePath=".\config.h"/>
+ RelativePath=".\config.h">
+ </File>
<File
- RelativePath="..\..\include\faad.h"/>
+ RelativePath="..\..\include\faad.h">
+ </File>
<File
- RelativePath=".\in2.h"/>
+ RelativePath=".\QCDInputDLL.h">
+ </File>
<File
- RelativePath=".\out.h"/>
+ RelativePath=".\QCDModDefs.h">
+ </File>
<File
- RelativePath="resource.h"/>
+ RelativePath=".\QCDModInput.h">
+ </File>
<File
- RelativePath=".\utils.h"/>
+ RelativePath=".\QCDModTagEditor.h">
+ </File>
+ <File
+ RelativePath=".\QCDTagsDLL.h">
+ </File>
+ <File
+ RelativePath="resource.h">
+ </File>
+ <File
+ RelativePath=".\utils.h">
+ </File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
<File
- RelativePath=".\in_mp4.rc"/>
+ RelativePath=".\QCDMp4.rc">
+ </File>
</Filter>
</Files>
- <Globals/>
+ <Globals>
+ </Globals>
</VisualStudioProject>
--- /dev/null
+++ b/plugins/QCDMp4/QCDMp4Tag.cpp
@@ -1,0 +1,511 @@
+#include <mp4.h>
+#include <faad.h>
+#include "QCDTagsDLL.h"
+
+
+//..............................................................................
+// Global Variables
+
+QCDModInitTag ModInitTag;
+BOOL uSetDlgItemText(void *tagHandle, int fieldId, const char *str);
+UINT uGetDlgItemText(void *tagHandle, int fieldId, char *str, int max);
+
+//------------------------------------------------------------------------------
+
+PLUGIN_API QCDModInitTag* TAGEDITORDLL_ENTRY_POINT()
+{
+ ModInitTag.size = sizeof(QCDModInitTag);
+ ModInitTag.version = PLUGIN_API_VERSION;
+ ModInitTag.ShutDown = ShutDown_Tag;
+
+ ModInitTag.Read = Read_Tag;
+ ModInitTag.Write = Write_Tag; // Leave null for operations that plugin does not support
+ ModInitTag.Strip = Strip_Tag; // ie: if plugin only reads tags, leave Write and Strip null
+
+ ModInitTag.description = "MP4 Tags";
+ ModInitTag.defaultexts = "MP4:M4A";
+
+ return &ModInitTag;
+}
+
+//-----------------------------------------------------------------------------
+
+void ShutDown_Tag(int flags)
+{
+ // TODO:
+ // prepare plugin to be unloaded. All allocations should be freed.
+ // flags param is unused
+}
+
+//-----------------------------------------------------------------------------
+
+bool Read_Tag(LPCSTR filename, void* tagHandle)
+{
+ // TODO:
+ // read metadata from tag and set each field to tagHandle
+ // only TAGFIELD_* are supported (see QCDModTagEditor.h)
+
+ // example of how to set value to tagHandle
+ // use SetFieldA for ASCII or MultiBytes strings.
+ // use SetFieldW for UNICODE strings
+ //
+ // ModInitTag.SetFieldW(tagHandle, TAGFIELD_COMPOSER, szwValue);
+
+ // return true for successfull read, false for failure
+
+ MP4FileHandle file = MP4_INVALID_FILE_HANDLE;
+ char *pVal, dummy1[1024];
+ short dummy, dummy2;
+
+ unsigned __int32 valueSize = 0;
+
+#ifdef DEBUG_OUTPUT
+ in_mp4_DebugOutput("mp4_tag_read");
+#endif
+
+ file = MP4Read(filename, 0);
+
+ if (file == MP4_INVALID_FILE_HANDLE)
+ return false;
+
+ /* get Metadata */
+
+ pVal = NULL;
+ MP4GetMetadataName(file, &pVal);
+ uSetDlgItemText(tagHandle, TAGFIELD_TITLE, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataArtist(file, &pVal);
+ uSetDlgItemText(tagHandle, TAGFIELD_ARTIST, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataWriter(file, &pVal);
+ uSetDlgItemText(tagHandle, TAGFIELD_COMPOSER, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataComment(file, &pVal);
+ uSetDlgItemText(tagHandle, TAGFIELD_COMMENT, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataAlbum(file, &pVal);
+ uSetDlgItemText(tagHandle, TAGFIELD_ALBUM, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataGenre(file, &pVal);
+ uSetDlgItemText(tagHandle, TAGFIELD_GENRE, pVal);
+
+ //dummy = 0;
+ //MP4GetMetadataTempo(file, &dummy);
+ //wsprintf(dummy1, "%d", dummy);
+ //SetDlgItemText(hwndDlg,IDC_METATEMPO, dummy1);
+
+ dummy = 0; dummy2 = 0;
+ MP4GetMetadataTrack(file, (unsigned __int16*)&dummy, (unsigned __int16*)&dummy2);
+ wsprintf(dummy1, "%d", dummy);
+ ModInitTag.SetFieldA(tagHandle, TAGFIELD_TRACK, dummy1);
+ //wsprintf(dummy1, "%d", dummy2);
+ //SetDlgItemText(hwndDlg,IDC_METATRACK2, dummy1);
+
+ //dummy = 0; dummy2 = 0;
+ //MP4GetMetadataDisk(file, &dummy, &dummy2);
+ //wsprintf(dummy1, "%d", dummy);
+ //SetDlgItemText(hwndDlg,IDC_METADISK1, dummy1);
+ //wsprintf(dummy1, "%d", dummy2);
+ //SetDlgItemText(hwndDlg,IDC_METADISK2, dummy1);
+
+ pVal = NULL;
+ MP4GetMetadataYear(file, &pVal);
+ uSetDlgItemText(tagHandle, TAGFIELD_YEAR, pVal);
+
+ //dummy3 = 0;
+ //MP4GetMetadataCompilation(file, &dummy3);
+ //if (dummy3)
+ // SendMessage(GetDlgItem(hwndDlg, IDC_METACOMPILATION), BM_SETCHECK, BST_CHECKED, 0);
+
+ pVal = NULL;
+ MP4GetMetadataTool(file, &pVal);
+ uSetDlgItemText(tagHandle, TAGFIELD_ENCODER, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataFreeForm(file, "CONDUCTOR", (unsigned __int8**)&pVal, &valueSize);
+ uSetDlgItemText(tagHandle, TAGFIELD_CONDUCTOR, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataFreeForm(file, "ORCHESTRA", (unsigned __int8**)&pVal, &valueSize);
+ uSetDlgItemText(tagHandle, TAGFIELD_ORCHESTRA, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataFreeForm(file, "YEARCOMPOSED", (unsigned __int8**)&pVal, &valueSize);
+ uSetDlgItemText(tagHandle, TAGFIELD_YEARCOMPOSED, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataFreeForm(file, "ORIGARTIST", (unsigned __int8**)&pVal, &valueSize);
+ uSetDlgItemText(tagHandle, TAGFIELD_ORIGARTIST, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataFreeForm(file, "LABEL", (unsigned __int8**)&pVal, &valueSize);
+ uSetDlgItemText(tagHandle, TAGFIELD_LABEL, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataFreeForm(file, "COPYRIGHT", (unsigned __int8**)&pVal, &valueSize);
+ uSetDlgItemText(tagHandle, TAGFIELD_COPYRIGHT, pVal);
+
+ pVal = NULL;
+ MP4GetMetadataFreeForm(file, "CDDBTAGID", (unsigned __int8**)&pVal, &valueSize);
+ uSetDlgItemText(tagHandle, TAGFIELD_CDDBTAGID, pVal);
+
+ /* ! Metadata */
+
+ MP4Close(file);
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+
+bool Write_Tag(LPCSTR filename, void* tagHandle)
+{
+ // TODO:
+ // read metadata from tagHandle and set each field to supported tag
+ // only TAGFIELD_* are supported (see QCDModTagEditor.h)
+
+ // example of how to get value from tagHandle
+ // use SetFieldA for ASCII or MultiBytes strings.
+ // use SetFieldW for UNICODE strings
+ //
+ // szwValue = ModInitTag.GetFieldW(tagHandle, TAGFIELD_ORCHESTRA);
+
+ // write tag to file
+
+ MP4FileHandle file = MP4_INVALID_FILE_HANDLE;
+ char dummy1[1024];
+ short dummy, dummy2;
+
+#ifdef DEBUG_OUTPUT
+ in_mp4_DebugOutput("mp4_tag_write");
+#endif
+
+ /* save Metadata changes */
+
+ file = MP4Modify(filename, 0, 0);
+ if (file == MP4_INVALID_FILE_HANDLE)
+ return false;
+
+ uGetDlgItemText(tagHandle, TAGFIELD_TITLE, dummy1, 1024);
+ MP4SetMetadataName(file, dummy1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_COMPOSER, dummy1, 1024);
+ MP4SetMetadataWriter(file, dummy1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_ARTIST, dummy1, 1024);
+ MP4SetMetadataArtist(file, dummy1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_ALBUM, dummy1, 1024);
+ MP4SetMetadataAlbum(file, dummy1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_COMMENT, dummy1, 1024);
+ MP4SetMetadataComment(file, dummy1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_GENRE, dummy1, 1024);
+ MP4SetMetadataGenre(file, dummy1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_YEAR, dummy1, 1024);
+ MP4SetMetadataYear(file, dummy1);
+
+ dummy = 0; dummy2 = 0;
+ MP4GetMetadataTrack(file, (unsigned __int16*)&dummy, (unsigned __int16*)&dummy2);
+ memcpy(dummy1, ModInitTag.GetFieldA(tagHandle, TAGFIELD_TRACK), sizeof(dummy1));
+ //GetDlgItemText(hwndDlg, IDC_METATRACK1, dummy1, 1024);
+ dummy = atoi(dummy1);
+ //GetDlgItemText(hwndDlg, IDC_METATRACK2, dummy1, 1024);
+ //dummy2 = atoi(dummy1);
+ MP4SetMetadataTrack(file, dummy, dummy2);
+
+ //GetDlgItemText(hwndDlg, IDC_METADISK1, dummy1, 1024);
+ //dummy = atoi(dummy1);
+ //GetDlgItemText(hwndDlg, IDC_METADISK2, dummy1, 1024);
+ //dummy2 = atoi(dummy1);
+ //MP4SetMetadataDisk(file, dummy, dummy2);
+
+ //GetDlgItemText(hwndDlg, IDC_METATEMPO, dummy1, 1024);
+ //dummy = atoi(dummy1);
+ //MP4SetMetadataTempo(file, dummy);
+
+ //dummy3 = SendMessage(GetDlgItem(hwndDlg, IDC_METACOMPILATION), BM_GETCHECK, 0, 0);
+ //MP4SetMetadataCompilation(file, dummy3);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_ENCODER, dummy1, 1024);
+ MP4SetMetadataTool(file, dummy1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_CONDUCTOR, dummy1, 1024);
+ MP4SetMetadataFreeForm(file, "CONDUCTOR", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_ORCHESTRA, dummy1, 1024);
+ MP4SetMetadataFreeForm(file, "ORCHESTRA", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_YEARCOMPOSED, dummy1, 1024);
+ MP4SetMetadataFreeForm(file, "YEARCOMPOSED", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_ORIGARTIST, dummy1, 1024);
+ MP4SetMetadataFreeForm(file, "ORIGARTIST", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_LABEL, dummy1, 1024);
+ MP4SetMetadataFreeForm(file, "LABEL", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_COPYRIGHT, dummy1, 1024);
+ MP4SetMetadataFreeForm(file, "COPYRIGHT", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
+
+ uGetDlgItemText(tagHandle, TAGFIELD_CDDBTAGID, dummy1, 1024);
+ MP4SetMetadataFreeForm(file, "CDDBTAGID", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
+
+ MP4Close(file);
+
+ MP4Optimize(filename, NULL, 0);
+ /* ! */
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+
+bool Strip_Tag(LPCSTR filename)
+{
+ // TODO:
+ // remove tag from file.
+ // do whatever is need to remove the supported tag from filename
+
+ // return true for successfull strip, false for failure
+
+ MP4FileHandle file;
+
+ file = MP4Modify(filename, 0, 0);
+ if (file == MP4_INVALID_FILE_HANDLE)
+ return false;
+
+ MP4MetadataDelete(file);
+
+ MP4Close(file);
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+
+/* Convert UNICODE to UTF-8
+ Return number of bytes written */
+int unicodeToUtf8 ( const WCHAR* lpWideCharStr, char* lpMultiByteStr, int cwcChars )
+{
+ const unsigned short* pwc = (unsigned short *)lpWideCharStr;
+ unsigned char* pmb = (unsigned char *)lpMultiByteStr;
+ const unsigned short* pwce;
+ size_t cBytes = 0;
+
+ if ( cwcChars >= 0 ) {
+ pwce = pwc + cwcChars;
+ } else {
+ pwce = (unsigned short *)((size_t)-1);
+ }
+
+ while ( pwc < pwce ) {
+ unsigned short wc = *pwc++;
+
+ if ( wc < 0x00000080 ) {
+ *pmb++ = (char)wc;
+ cBytes++;
+ } else
+ if ( wc < 0x00000800 ) {
+ *pmb++ = (char)(0xC0 | ((wc >> 6) & 0x1F));
+ cBytes++;
+ *pmb++ = (char)(0x80 | (wc & 0x3F));
+ cBytes++;
+ } else
+ if ( wc < 0x00010000 ) {
+ *pmb++ = (char)(0xE0 | ((wc >> 12) & 0x0F));
+ cBytes++;
+ *pmb++ = (char)(0x80 | ((wc >> 6) & 0x3F));
+ cBytes++;
+ *pmb++ = (char)(0x80 | (wc & 0x3F));
+ cBytes++;
+ }
+ if ( wc == L'\0' )
+ return cBytes;
+ }
+
+ return cBytes;
+}
+
+/* Convert UTF-8 coded string to UNICODE
+ Return number of characters converted */
+int utf8ToUnicode ( const char* lpMultiByteStr, WCHAR* lpWideCharStr, int cmbChars )
+{
+ const unsigned char* pmb = (unsigned char *)lpMultiByteStr;
+ unsigned short* pwc = (unsigned short *)lpWideCharStr;
+ const unsigned char* pmbe;
+ size_t cwChars = 0;
+
+ if ( cmbChars >= 0 ) {
+ pmbe = pmb + cmbChars;
+ } else {
+ pmbe = (unsigned char *)((size_t)-1);
+ }
+
+ while ( pmb < pmbe ) {
+ char mb = *pmb++;
+ unsigned int cc = 0;
+ unsigned int wc;
+
+ while ( (cc < 7) && (mb & (1 << (7 - cc)))) {
+ cc++;
+ }
+
+ if ( cc == 1 || cc > 6 ) // illegal character combination for UTF-8
+ continue;
+
+ if ( cc == 0 ) {
+ wc = mb;
+ } else {
+ wc = (mb & ((1 << (7 - cc)) - 1)) << ((cc - 1) * 6);
+ while ( --cc > 0 ) {
+ if ( pmb == pmbe ) // reached end of the buffer
+ return cwChars;
+ mb = *pmb++;
+ if ( ((mb >> 6) & 0x03) != 2 ) // not part of multibyte character
+ return cwChars;
+ wc |= (mb & 0x3F) << ((cc - 1) * 6);
+ }
+ }
+
+ if ( wc & 0xFFFF0000 )
+ wc = L'?';
+ *pwc++ = wc;
+ cwChars++;
+ if ( wc == L'\0' )
+ return cwChars;
+ }
+
+ return cwChars;
+}
+
+/* convert Windows ANSI to UTF-8 */
+int ConvertANSIToUTF8 ( const char* ansi, char* utf8 )
+{
+ WCHAR* wszValue; // Unicode value
+ size_t ansi_len;
+ size_t len;
+
+ *utf8 = '\0';
+ if ( ansi == NULL )
+ return 0;
+
+ ansi_len = strlen ( ansi );
+
+ if ( (wszValue = (WCHAR *)malloc ( (ansi_len + 1) * 2 )) == NULL )
+ return 0;
+
+ /* Convert ANSI value to Unicode */
+ if ( (len = MultiByteToWideChar ( CP_ACP, 0, ansi, ansi_len + 1, wszValue, (ansi_len + 1) * 2 )) == 0 ) {
+ free ( wszValue );
+ return 0;
+ }
+
+ /* Convert Unicode value to UTF-8 */
+ if ( (len = unicodeToUtf8 ( wszValue, utf8, -1 )) == 0 ) {
+ free ( wszValue );
+ return 0;
+ }
+
+ free ( wszValue );
+
+ return len-1;
+}
+
+/* convert UTF-8 to Windows ANSI */
+int ConvertUTF8ToANSI ( const char* utf8, char* ansi )
+{
+ WCHAR* wszValue; // Unicode value
+ size_t utf8_len;
+ size_t len;
+
+ *ansi = '\0';
+ if ( utf8 == NULL )
+ return 0;
+
+ utf8_len = strlen ( utf8 );
+
+ if ( (wszValue = (WCHAR *)malloc ( (utf8_len + 1) * 2 )) == NULL )
+ return 0;
+
+ /* Convert UTF-8 value to Unicode */
+ if ( (len = utf8ToUnicode ( utf8, wszValue, utf8_len + 1 )) == 0 ) {
+ free ( wszValue );
+ return 0;
+ }
+
+ /* Convert Unicode value to ANSI */
+ if ( (len = WideCharToMultiByte ( CP_ACP, 0, wszValue, -1, ansi, (utf8_len + 1) * 2, NULL, NULL )) == 0 ) {
+ free ( wszValue );
+ return 0;
+ }
+
+ free ( wszValue );
+
+ return len-1;
+}
+
+BOOL uSetDlgItemText(void *tagHandle, int fieldId, const char *str)
+{
+ char *temp;
+ size_t len;
+ int r;
+
+ if (!str) return FALSE;
+ len = strlen(str);
+ temp = (char *)malloc(len+1);
+ if (!temp) return FALSE;
+ memset(temp, '\0', len+1);
+ r = ConvertUTF8ToANSI(str, temp);
+ if (r > 0)
+ ModInitTag.SetFieldA(tagHandle, fieldId, temp);
+ free(temp);
+
+ return r>0 ? TRUE : FALSE;
+}
+
+UINT uGetDlgItemText(void *tagHandle, int fieldId, char *str, int max)
+{
+ char *temp, *utf8;;
+ int len;
+
+ const char *p;
+
+ if (!str) return 0;
+ len = strlen( ModInitTag.GetFieldA(tagHandle, fieldId) );
+ temp = (char *)malloc(len+1);
+ if (!temp) return 0;
+ utf8 = (char *)malloc((len+1)*4);
+ if (!utf8)
+ {
+ free(temp);
+ return 0;
+ }
+
+ memset(temp, '\0', len+1);
+ memset(utf8, '\0', (len+1)*4);
+ p = ModInitTag.GetFieldA(tagHandle, fieldId);
+ memcpy(temp, p, len+1);
+ if (len > 0)
+ {
+ len = ConvertANSIToUTF8(temp, utf8);
+ if (len > max-1)
+ {
+ len = max-1;
+ utf8[max] = '\0';
+ }
+ memcpy(str, utf8, len+1);
+ }
+
+ free(temp);
+ free(utf8);
+
+ return len;
+}
--- /dev/null
+++ b/plugins/QCDMp4/QCDTagsDLL.h
@@ -1,0 +1,14 @@
+#ifndef QCDTAGS_H
+#define QCDTAGS_H
+
+#include "QCDModTagEditor.h"
+
+extern HINSTANCE hInstance;
+
+void ShutDown_Tag(int flags);
+bool Read_Tag(LPCSTR filename, void* tagData);
+bool Write_Tag(LPCSTR filename, void* tagData);
+bool Strip_Tag(LPCSTR filename);
+
+
+#endif
\ No newline at end of file
--- a/plugins/QCDMp4/aac2mp4.cpp
+++ b/plugins/QCDMp4/aac2mp4.cpp
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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
@@ -16,7 +16,13 @@
** 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 $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through [email protected].
+**
+** $Id: aac2mp4.cpp,v 1.3 2003/12/06 04:24:17 rjamorim Exp $
**/
#include <mpeg4ip.h>
--- a/plugins/QCDMp4/aac2mp4.h
+++ b/plugins/QCDMp4/aac2mp4.h
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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
@@ -16,7 +16,13 @@
** 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 $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through [email protected].
+**
+** $Id: aac2mp4.h,v 1.3 2003/12/06 04:24:17 rjamorim Exp $
**/
#ifndef AAC2MP4_H__
--- a/plugins/QCDMp4/aacinfo.c
+++ b/plugins/QCDMp4/aacinfo.c
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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
@@ -16,7 +16,13 @@
** 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 $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through [email protected].
+**
+** $Id: aacinfo.c,v 1.3 2003/12/06 04:24:17 rjamorim Exp $
**/
#define WIN32_LEAN_AND_MEAN
@@ -108,13 +114,11 @@
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);
}
+ frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11)
+ | (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5);
t_framelength += frame_length;
--- a/plugins/QCDMp4/aacinfo.h
+++ b/plugins/QCDMp4/aacinfo.h
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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
@@ -16,7 +16,13 @@
** 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 $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through [email protected].
+**
+** $Id: aacinfo.h,v 1.3 2003/12/06 04:24:17 rjamorim Exp $
**/
#ifndef AACINFO_INCLUDED
--- a/plugins/QCDMp4/config.c
+++ b/plugins/QCDMp4/config.c
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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
@@ -16,7 +16,13 @@
** 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 $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through [email protected].
+**
+** $Id: config.c,v 1.3 2003/12/06 04:24:17 rjamorim Exp $
**/
#define WIN32_LEAN_AND_MEAN
@@ -23,12 +29,15 @@
#include <windows.h>
#include "config.h"
-char app_name[] = "QCDMp4";
+char app_name[] = "AudioCoding.com MPEG-4 General Audio player";
char INI_FILE[MAX_PATH];
int m_priority = 3;
int m_resolution = 0;
int m_show_errors = 1;
int m_use_for_aac = 1;
+int m_downmix = 0;
+int m_vbr_display = 0;
+char titleformat[MAX_PATH];
void _r_s(char *name,char *data, int mlen)
{
--- a/plugins/QCDMp4/config.h
+++ b/plugins/QCDMp4/config.h
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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
@@ -16,18 +16,27 @@
** 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 $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through [email protected].
+**
+** $Id: config.h,v 1.3 2003/12/06 04:24:17 rjamorim Exp $
**/
-extern char app_name[];
-extern char INI_FILE[];
+char app_name[];
+char INI_FILE[];
int m_priority;
int m_resolution;
int m_show_errors;
int m_use_for_aac;
+int m_downmix;
+int m_vbr_display;
+char titleformat[MAX_PATH];
#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);
+void _r_s(char *name,char *data, int mlen);
binary files a/plugins/QCDMp4/logo.bmp /dev/null differ
--- a/plugins/QCDMp4/resource.h
+++ b/plugins/QCDMp4/resource.h
@@ -1,13 +1,8 @@
//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
+// Microsoft Visual C++ 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
@@ -31,21 +26,42 @@
#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
+#define IDC_METACOMPILATION 1012
+#define IDC_METANAME 1013
+#define IDC_METAARTIST 1014
+#define IDC_METAWRITER 1015
+#define IDC_METAALBUM 1016
+#define IDC_METACOMMENTS 1017
+#define IDC_METAGENRE 1018
+#define IDC_METAYEAR 1019
+#define IDC_METATRACK1 1020
+#define IDC_METADISK1 1021
+#define IDC_METATEMPO 1022
+#define IDC_METATRACK2 1023
+#define IDC_METADISK2 1024
+#define IDC_STATIC1 1025
+#define IDC_STATIC2 1026
+#define IDC_STATIC3 1027
+#define IDC_STATIC4 1028
+#define IDC_STATIC5 1029
+#define IDC_STATIC6 1030
+#define IDC_STATIC7 1031
+#define IDC_STATIC8 1032
+#define IDC_STATIC9 1033
+#define IDC_STATIC10 1034
+#define IDC_STATIC11 1035
+#define IDC_STATIC12 1036
+#define IDC_DOWNMIX 1038
+#define IDC_VBR 1039
+#define IDC_TITLEFORMAT 1040
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 106
+#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1020
+#define _APS_NEXT_CONTROL_VALUE 1041
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
--- a/plugins/QCDMp4/utils.c
+++ b/plugins/QCDMp4/utils.c
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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
@@ -16,7 +16,13 @@
** 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 $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through [email protected].
+**
+** $Id: utils.c,v 1.3 2003/12/06 04:24:17 rjamorim Exp $
**/
#define WIN32_LEAN_AND_MEAN
--- a/plugins/QCDMp4/utils.h
+++ b/plugins/QCDMp4/utils.h
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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
@@ -16,7 +16,13 @@
** 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 $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through [email protected].
+**
+** $Id: utils.h,v 1.3 2003/12/06 04:24:17 rjamorim Exp $
**/
#ifndef UTILS_INCLUDED