~ft/aacdec

976c310f1d8d21d5f76415d124522dbda55f0b79 — rjamorim 17 years ago 054797b
Latest modifications by shaohao
M plugins/QCDMp4/QCDMp4.c => plugins/QCDMp4/QCDMp4.c +622 -56
@@ 22,7 22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
** $Id: QCDMp4.c,v 1.3 2003/11/16 19:52:41 menno Exp $
** $Id: QCDMp4.c,v 1.4 2003/12/06 04:24:17 rjamorim Exp $
**/

//#define DEBUG_OUTPUT


@@ 40,7 40,7 @@
#include "QCDInputDLL.h"
#include "utils.h"
#include "config.h"
#include "aacinfo.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";


@@ 71,8 71,8 @@ static int res_table[] = {
    16
};
//static char info_fn[_MAX_PATH];

// post this to the main window at end of file (after playback has stopped)
//
//// 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


@@ 125,7 125,7 @@ static state mp4state;

//static In_Module module; // the output module (declared near the bottom of this file)
struct {
	HINSTANCE		hInstance;
	HINSTANCE		hDllInstance;
	HWND			hMainWindow;
	QCDModInitIn	QCDCallbacks;
} module;


@@ 141,6 141,295 @@ DWORD WINAPI MP4PlayThread(void *b); // the decode thread procedure
DWORD WINAPI AACPlayThread(void *b); // the decode thread procedure


//typedef struct tag
//{
//    char *item;
//    char *value;
//} tag;
//
//typedef struct medialib_tags
//{
//    struct tag *tags;
//    unsigned int count;
//} medialib_tags;
//
//int tag_add_field(medialib_tags *tags, const char *item, const char *value)
//{
//    void *backup = (void *)tags->tags;
//
//    if (!item || (item && !*item) || !value) return 0;
//
//    tags->tags = (struct tag *)realloc(tags->tags, (tags->count+1) * sizeof(tag));
//    if (!tags->tags) {
//        if (backup) free(backup);
//        return 0;
//    }
//    else
//    {
//        int i_len = strlen(item);
//        int v_len = strlen(value);
//
//        tags->tags[tags->count].item = (char *)malloc(i_len+1);
//        tags->tags[tags->count].value = (char *)malloc(v_len+1);
//
//        if (!tags->tags[tags->count].item || !tags->tags[tags->count].value)
//        {
//            if (!tags->tags[tags->count].item) free (tags->tags[tags->count].item);
//            if (!tags->tags[tags->count].value) free (tags->tags[tags->count].value);
//            tags->tags[tags->count].item = NULL;
//            tags->tags[tags->count].value = NULL;
//            return 0;
//        }
//
//        memcpy(tags->tags[tags->count].item, item, i_len);
//        memcpy(tags->tags[tags->count].value, value, v_len);
//        tags->tags[tags->count].item[i_len] = '\0';
//        tags->tags[tags->count].value[v_len] = '\0';
//
//        tags->count++;
//        return 1;
//    }
//}
//
//int tag_set_field(medialib_tags *tags, const char *item, const char *value)
//{
//    unsigned int i;
//
//    if (!item || (item && !*item) || !value) return 0;
//
//    for (i = 0; i < tags->count; i++)
//    {
//        if (!stricmp(tags->tags[i].item, item))
//        {
//            void *backup = (void *)tags->tags[i].value;
//            int v_len = strlen(value);
//
//            tags->tags[i].value = (char *)realloc(tags->tags[i].value, v_len+1);
//            if (!tags->tags[i].value)
//            {
//                if (backup) free(backup);
//                return 0;
//            }
//
//            memcpy(tags->tags[i].value, value, v_len);
//            tags->tags[i].value[v_len] = '\0';
//
//            return 1;
//        }
//    }
//
//    return tag_add_field(tags, item, value);
//}
//
//int tag_delete(medialib_tags *tags)
//{
//    unsigned int i;
//
//    for (i = 0; i < tags->count; i++)
//    {
//        if (tags->tags[i].item) free(tags->tags[i].item);
//        if (tags->tags[i].value) free(tags->tags[i].value);
//    }
//
//    if (tags->tags) free(tags->tags);
//
//    tags->tags = NULL;
//    tags->count = 0;
//}
//
//int ReadMP4Tag(MP4FileHandle file, medialib_tags *tags)
//{
//    unsigned __int32 valueSize;
//    unsigned __int8 *pValue;
//    char *pName;
//    unsigned int i = 0;
//
//    do {
//        pName = 0;
//        pValue = 0;
//        valueSize = 0;
//
//        MP4GetMetadataByIndex(file, i, (const char **)&pName, &pValue, &valueSize);
//
//        if (valueSize > 0)
//        {
//            char *val = (char *)malloc(valueSize+1);
//            if (!val) return 0;
//            memcpy(val, pValue, valueSize);
//            val[valueSize] = '\0';
//
//            if (pName[0] == '\xa9')
//            {
//                if (memcmp(pName, "�nam", 4) == 0)
//                {
//                    tag_add_field(tags, "title", val);
//                } else if (memcmp(pName, "�ART", 4) == 0) {
//                    tag_add_field(tags, "artist", val);
//                } else if (memcmp(pName, "�wrt", 4) == 0) {
//                    tag_add_field(tags, "writer", val);
//                } else if (memcmp(pName, "�alb", 4) == 0) {
//                    tag_add_field(tags, "album", val);
//                } else if (memcmp(pName, "�day", 4) == 0) {
//                    tag_add_field(tags, "date", val);
//                } else if (memcmp(pName, "�too", 4) == 0) {
//                    tag_add_field(tags, "tool", val);
//                } else if (memcmp(pName, "�cmt", 4) == 0) {
//                    tag_add_field(tags, "comment", val);
//                } else if (memcmp(pName, "�gen", 4) == 0) {
//                    tag_add_field(tags, "genre", val);
//                } else {
//                    tag_add_field(tags, pName, val);
//                }
//            } else if (memcmp(pName, "gnre", 4) == 0) {
//                char *t=0;
//                if (MP4GetMetadataGenre(file, &t))
//                {
//                    tag_add_field(tags, "genre", t);
//                }
//            } else if (memcmp(pName, "trkn", 4) == 0) {
//                unsigned __int16 trkn = 0, tot = 0;
//                char t[200];
//                if (MP4GetMetadataTrack(file, &trkn, &tot))
//                {
//                    if (tot > 0)
//                        wsprintf(t, "%d/%d", trkn, tot);
//                    else
//                        wsprintf(t, "%d", trkn);
//                    tag_add_field(tags, "tracknumber", t);
//                }
//            } else if (memcmp(pName, "disk", 4) == 0) {
//                unsigned __int16 disk = 0, tot = 0;
//                char t[200];
//                if (MP4GetMetadataDisk(file, &disk, &tot))
//                {
//                    if (tot > 0)
//                        wsprintf(t, "%d/%d", disk, tot);
//                    else
//                        wsprintf(t, "%d", disk);
//                    tag_add_field(tags, "disc", t);
//                }
//            } else if (memcmp(pName, "cpil", 4) == 0) {
//                unsigned __int8 cpil = 0;
//                char t[200];
//                if (MP4GetMetadataCompilation(file, &cpil))
//                {
//                    wsprintf(t, "%d", cpil);
//                    tag_add_field(tags, "compilation", t);
//                }
//            } else if (memcmp(pName, "tmpo", 4) == 0) {
//                unsigned __int16 tempo = 0;
//                char t[200];
//                if (MP4GetMetadataTempo(file, &tempo))
//                {
//                    wsprintf(t, "%d BPM", tempo);
//                    tag_add_field(tags, "tempo", t);
//                }
//            } else if (memcmp(pName, "NDFL", 4) == 0) {
//                /* Removed */
//            } else {
//                tag_add_field(tags, pName, val);
//            }
//
//            free(val);
//        }
//
//        i++;
//    } while (valueSize > 0);
//
//    return 1;
//}
//
//int mp4_set_metadata(MP4FileHandle file, const char *item, const char *val)
//{
//    if (!item || (item && !*item) || !val || (val && !*val)) return 0;
//
//    if (!stricmp(item, "track") || !stricmp(item, "tracknumber"))
//    {
//        unsigned __int16 trkn, tot;
//        int t1 = 0, t2 = 0;
//        sscanf(val, "%d/%d", &t1, &t2);
//        trkn = t1, tot = t2;
//        if (!trkn) return 1;
//        if (MP4SetMetadataTrack(file, trkn, tot)) return 1;
//    }
//    else if (!stricmp(item, "disc") || !stricmp(item, "disknumber"))
//    {
//        unsigned __int16 disk, tot;
//        int t1 = 0, t2 = 0;
//        sscanf(val, "%d/%d", &t1, &t2);
//        disk = t1, tot = t2;
//        if (!disk) return 1;
//        if (MP4SetMetadataDisk(file, disk, tot)) return 1;
//    }
//    else if (!stricmp(item, "compilation"))
//    {
//        unsigned __int8 cpil = atoi(val);
//        if (!cpil) return 1;
//        if (MP4SetMetadataCompilation(file, cpil)) return 1;
//    }
//    else if (!stricmp(item, "tempo"))
//    {
//        unsigned __int16 tempo = atoi(val);
//        if (!tempo) return 1;
//        if (MP4SetMetadataTempo(file, tempo)) return 1;
//    }
//    else if (!stricmp(item, "artist"))
//    {
//        if (MP4SetMetadataArtist(file, val)) return 1;
//    }
//    else if (!stricmp(item, "writer"))
//    {
//        if (MP4SetMetadataWriter(file, val)) return 1;
//    }
//    else if (!stricmp(item, "title"))
//    {
//        if (MP4SetMetadataName(file, val)) return 1;
//    }
//    else if (!stricmp(item, "album"))
//    {
//        if (MP4SetMetadataAlbum(file, val)) return 1;
//    }
//    else if (!stricmp(item, "date") || !stricmp(item, "year"))
//    {
//        if (MP4SetMetadataYear(file, val)) return 1;
//    }
//    else if (!stricmp(item, "comment"))
//    {
//        if (MP4SetMetadataComment(file, val)) return 1;
//    }
//    else if (!stricmp(item, "genre"))
//    {
//        if (MP4SetMetadataGenre(file, val)) return 1;
//    }
//    else if (!stricmp(item, "tool"))
//    {
//        if (MP4SetMetadataTool(file, val)) return 1;
//    }
//    else
//    {
//        if (MP4SetMetadataFreeForm(file, (char *)item, (u_int8_t *)val, (u_int32_t)strlen(val))) return 1;
//    }
//
//    return 0;
//}
//
//int WriteMP4Tag(MP4FileHandle file, const medialib_tags *tags)
//{
//    unsigned int i;
//
//    for (i = 0; i < tags->count; i++)
//    {
//        const char *item = tags->tags[i].item;
//        const char *value = tags->tags[i].value;
//
//        if (value && *value)
//        {
//            mp4_set_metadata(file, item, value);
//        }
//    }
//}


#ifdef DEBUG_OUTPUT
void in_mp4_DebugOutput(char *message)
{


@@ 428,6 717,7 @@ void ShutDown(int flags)
//    int r;
//
//    if (!str) return FALSE;
//    if (!*str) return TRUE;
//    len = strlen(str);
//    temp = malloc(len+1);
//    if (!temp) return FALSE;


@@ 445,7 735,8 @@ void ShutDown(int flags)
//    int len;
//    HWND w;
//
//    if (!str) return 0;
//    if (!str || !max) return 0;
//    *str = '\0';
//    w = GetDlgItem(hwnd, id);
//    len = GetWindowTextLength(w);
//    temp = malloc(len+1);


@@ 482,6 773,10 @@ void ShutDown(int flags)
//    MP4FileHandle file;
//    char *pVal, dummy1[1024], dummy3;
//    short dummy, dummy2;
//    char temp[1024];
//    struct medialib_tags tags;
//    tags.count = 0;
//    tags.tags = NULL;
//
//#ifdef DEBUG_OUTPUT
//    in_mp4_DebugOutput("mp4_info_dialog_proc");


@@ 496,7 791,6 @@ void ShutDown(int flags)
//        EnableWindow(GetDlgItem(hwndDlg,IDC_CONVERT2), FALSE);
//        ShowWindow(GetDlgItem(hwndDlg,IDC_CONVERT2), SW_HIDE);
//
//
//        file = MP4Read(info_fn, 0);
//
//        if (file == MP4_INVALID_FILE_HANDLE)


@@ 509,51 803,66 @@ void ShutDown(int flags)
//        /* get Metadata */
//
//        pVal = NULL;
//        MP4GetMetadataName(file, &pVal);
//        uSetDlgItemText(hwndDlg,IDC_METANAME, pVal);
//        if (MP4GetMetadataName(file, &pVal))
//            uSetDlgItemText(hwndDlg,IDC_METANAME, pVal);
//
//        pVal = NULL;
//        MP4GetMetadataArtist(file, &pVal);
//        uSetDlgItemText(hwndDlg,IDC_METAARTIST, pVal);
//        if (MP4GetMetadataArtist(file, &pVal))
//            uSetDlgItemText(hwndDlg,IDC_METAARTIST, pVal);
//
//        pVal = NULL;
//        MP4GetMetadataWriter(file, &pVal);
//        uSetDlgItemText(hwndDlg,IDC_METAWRITER, pVal);
//        if (MP4GetMetadataWriter(file, &pVal))
//            uSetDlgItemText(hwndDlg,IDC_METAWRITER, pVal);
//
//        pVal = NULL;
//        MP4GetMetadataComment(file, &pVal);
//        uSetDlgItemText(hwndDlg,IDC_METACOMMENTS, pVal);
//        if (MP4GetMetadataComment(file, &pVal))
//            uSetDlgItemText(hwndDlg,IDC_METACOMMENTS, pVal);
//
//        pVal = NULL;
//        MP4GetMetadataAlbum(file, &pVal);
//        uSetDlgItemText(hwndDlg,IDC_METAALBUM, pVal);
//        if (MP4GetMetadataAlbum(file, &pVal))
//            uSetDlgItemText(hwndDlg,IDC_METAALBUM, pVal);
//
//        pVal = NULL;
//        MP4GetMetadataGenre(file, &pVal);
//        uSetDlgItemText(hwndDlg,IDC_METAGENRE, pVal);
//        if (MP4GetMetadataGenre(file, &pVal))
//            uSetDlgItemText(hwndDlg,IDC_METAGENRE, pVal);
//
//        dummy = 0;
//        MP4GetMetadataTempo(file, &dummy);
//        wsprintf(dummy1, "%d", dummy);
//        SetDlgItemText(hwndDlg,IDC_METATEMPO, dummy1);
//        if (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);
//        if (dummy)
//        {
//            wsprintf(dummy1, "%d", dummy);
//            SetDlgItemText(hwndDlg,IDC_METATRACK1, dummy1);
//        }
//        if (dummy2)
//        {
//            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);
//        if (dummy)
//        {
//            wsprintf(dummy1, "%d", dummy);
//            SetDlgItemText(hwndDlg,IDC_METADISK1, dummy1);
//        }
//        if (dummy2)
//        {
//            wsprintf(dummy1, "%d", dummy2);
//            SetDlgItemText(hwndDlg,IDC_METADISK2, dummy1);
//        }
//
//        pVal = NULL;
//        MP4GetMetadataYear(file, &pVal);
//        uSetDlgItemText(hwndDlg,IDC_METAYEAR, pVal);
//        if (MP4GetMetadataYear(file, &pVal))
//            uSetDlgItemText(hwndDlg,IDC_METAYEAR, pVal);
//
//        dummy3 = 0;
//        MP4GetMetadataCompilation(file, &dummy3);


@@ 575,52 884,71 @@ void ShutDown(int flags)
//
//            /* save Metadata changes */
//
//            tag_delete(&tags);
//            file = MP4Read(info_fn, 0);
//            if (file != MP4_INVALID_FILE_HANDLE)
//            {
//                ReadMP4Tag(file, &tags);
//                MP4Close(file);
//
//                file = MP4Modify(info_fn, 0, 0);
//                if (file != MP4_INVALID_FILE_HANDLE)
//                {
//                    MP4MetadataDelete(file);
//                    MP4Close(file);
//                }
//            }
//
//            file = MP4Modify(info_fn, 0, 0);
//            if (file == MP4_INVALID_FILE_HANDLE)
//            {
//                tag_delete(&tags);
//                EndDialog(hwndDlg, wParam);
//                return FALSE;
//            }
//
//            uGetDlgItemText(hwndDlg, IDC_METANAME, dummy1, 1024);
//            MP4SetMetadataName(file, dummy1);
//            tag_set_field(&tags, "title", dummy1);
//
//            uGetDlgItemText(hwndDlg, IDC_METAWRITER, dummy1, 1024);
//            MP4SetMetadataWriter(file, dummy1);
//            tag_set_field(&tags, "writer", dummy1);
//
//            uGetDlgItemText(hwndDlg, IDC_METAARTIST, dummy1, 1024);
//            MP4SetMetadataArtist(file, dummy1);
//            tag_set_field(&tags, "artist", dummy1);
//
//            uGetDlgItemText(hwndDlg, IDC_METAALBUM, dummy1, 1024);
//            MP4SetMetadataAlbum(file, dummy1);
//            tag_set_field(&tags, "album", dummy1);
//
//            uGetDlgItemText(hwndDlg, IDC_METACOMMENTS, dummy1, 1024);
//            MP4SetMetadataComment(file, dummy1);
//            tag_set_field(&tags, "comment", dummy1);
//
//            uGetDlgItemText(hwndDlg, IDC_METAGENRE, dummy1, 1024);
//            MP4SetMetadataGenre(file, dummy1);
//            tag_set_field(&tags, "genre", dummy1);
//
//            uGetDlgItemText(hwndDlg, IDC_METAYEAR, dummy1, 1024);
//            MP4SetMetadataYear(file, dummy1);
//            tag_set_field(&tags, "year", dummy1);
//
//            GetDlgItemText(hwndDlg, IDC_METATRACK1, dummy1, 1024);
//            dummy = atoi(dummy1);
//            GetDlgItemText(hwndDlg, IDC_METATRACK2, dummy1, 1024);
//            dummy2 = atoi(dummy1);
//            MP4SetMetadataTrack(file, dummy, dummy2);
//            wsprintf(temp, "%d/%d", dummy, dummy2);
//            tag_set_field(&tags, "track", temp);
//
//            GetDlgItemText(hwndDlg, IDC_METADISK1, dummy1, 1024);
//            dummy = atoi(dummy1);
//            GetDlgItemText(hwndDlg, IDC_METADISK2, dummy1, 1024);
//            dummy2 = atoi(dummy1);
//            MP4SetMetadataDisk(file, dummy, dummy2);
//            wsprintf(temp, "%d/%d", dummy, dummy2);
//            tag_set_field(&tags, "disc", temp);
//
//            GetDlgItemText(hwndDlg, IDC_METATEMPO, dummy1, 1024);
//            dummy = atoi(dummy1);
//            MP4SetMetadataTempo(file, dummy);
//            tag_set_field(&tags, "tempo", dummy1);
//
//            dummy3 = SendMessage(GetDlgItem(hwndDlg, IDC_METACOMPILATION), BM_GETCHECK, 0, 0);
//            MP4SetMetadataCompilation(file, dummy3);
//            tag_set_field(&tags, "compilation", (dummy3 ? "1" : "0"));
//
//            WriteMP4Tag(file, &tags);
//
//            MP4Close(file);
//


@@ 795,7 1123,6 @@ void ShutDown(int flags)
//    char *pVal, dummy1[1024];
//    short dummy, dummy2;
//
//
//    while (*in && out < bound)
//    {
//        switch (*in)


@@ 968,7 1295,7 @@ BOOL CALLBACK config_dialog_proc(HWND hwndDlg, UINT message,

void Configure(int flags)
{
	DialogBox(module.hInstance, MAKEINTRESOURCE(IDD_CONFIG),
    DialogBox(module.hDllInstance, MAKEINTRESOURCE(IDD_CONFIG),
		module.hMainWindow, config_dialog_proc);
}



@@ 1179,6 1506,8 @@ int GetMediaSupported(const char* medianame, MediaInfo *mediaInfo)
	return 0;
}

//-----------------------------------------------------------------------------

int Play(const char* medianame, int playfrom, int playto, int flags)
{
    WAVEFORMATEX wf;


@@ 1231,7 1560,6 @@ int Play(const char* medianame, int playfrom, int playto, int flags)
        int bread = 0;
        double length = 0.;
        __int64 bitrate = 128;
        faacDecFrameInfo frameInfo;

        //module.is_seekable = 1;



@@ 1488,7 1816,7 @@ int Play(const char* medianame, int playfrom, int playto, int flags)
    mp4state.decode_pos_ms =  0;
    mp4state.seek_needed   = -1;

    // initialize vis stuff
    //// initialize vis stuff
    //module.SAVSAInit(maxlatency, mp4state.samplerate);
    //module.VSASetInfo((int)mp4state.channels, mp4state.samplerate);



@@ 1596,15 1924,15 @@ void SetVolume(int levelleft, int levelright, int flags)

int Stop(const char* medianame, int flags)
{
	struct seek_list *target = mp4state.m_head;
    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)
	{
		module.QCDCallbacks.toPlayer.OutputStop(flags);
	module.QCDCallbacks.toPlayer.OutputStop(flags);
    killPlayThread = 1;

    if (play_thread_handle != INVALID_HANDLE_VALUE)


@@ 1633,14 1961,14 @@ int Stop(const char* medianame, int flags)

    //module.outMod->Close();
    //module.SAVSADeInit();
		mp4state.filename[0] = '\0';
		mp4state.paused = 0;
	mp4state.filename[0] = '\0';
	mp4state.paused = 0;
	}

	return 1;
}

int getsonglength(char *fn)
int getsonglength(const char *fn)
{
    long msDuration = 0;



@@ 1950,6 2278,7 @@ DWORD WINAPI MP4PlayThread(void *b)

            mp4state.decode_pos_ms = mp4state.seek_needed;
            mp4state.seek_needed = -1;
			updatepos = 1;
        }

        if (done)


@@ 2267,6 2596,7 @@ DWORD WINAPI AACPlayThread(void *b)
                mp4state.decode_pos_ms = mp4state.seek_needed;
            }
            mp4state.seek_needed = -1;
			updatepos = 1;
        }

        if (done)


@@ 2341,7 2671,7 @@ DWORD WINAPI AACPlayThread(void *b)
				if (!module.QCDCallbacks.toPlayer.OutputWrite(&wd))
					done = 1;

				//if (module.dsp_isactive())
                //if (module.dsp_isactive())
                //{
                //    void *dsp_buffer = malloc(l*2);
                //    memcpy(dsp_buffer, sample_buffer, l);


@@ 2399,9 2729,9 @@ int WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID pRes)
{
	if (fdwReason == DLL_PROCESS_ATTACH)
	{
		module.hInstance = hInst;
		module.hDllInstance = hInst;
	}
	return TRUE;
	return 1;
}

//-----------------------------------------------------------------------------


@@ 2424,3 2754,239 @@ PLUGIN_API QCDModInitIn* INPUTDLL_ENTRY_POINT(QCDModInitIn *ModInit, QCDModInfo 

	return &module.QCDCallbacks;
}

///* new Media Library interface */
//
//int mp4_get_metadata(MP4FileHandle file, const char *item, char *dest, int dlen)
//{
//    char *pVal = NULL, dummy1[4096];
//    short dummy = 0, dummy2 = 0;
//
//    if (dlen < 1) return 0;
//
//    if (!stricmp(item, "track") || !stricmp(item, "tracknumber"))
//    {
//        if (MP4GetMetadataTrack(file, &dummy, &dummy2))
//        {
//            wsprintf(dummy1, "%d", (int)dummy);
//            strncpy(dest, dummy1, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "disc") || !stricmp(item, "disknumber"))
//    {
//        if (MP4GetMetadataDisk(file, &dummy, &dummy2))
//        {
//            wsprintf(dummy1, "%d", (int)dummy);
//            strncpy(dest, dummy1, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "compilation"))
//    {
//        u_int8_t cpil = 0;
//        if (MP4GetMetadataCompilation(file, &cpil))
//        {
//            wsprintf(dummy1, "%d", (int)cpil);
//            strncpy(dest, dummy1, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "tempo"))
//    {
//        u_int16_t tempo = 0;
//        if (MP4GetMetadataTempo(file, &tempo))
//        {
//            wsprintf(dummy1, "%d", (int)tempo);
//            strncpy(dest, dummy1, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "artist"))
//    {
//        if (MP4GetMetadataArtist(file, &pVal))
//        {
//            strncpy(dest, pVal, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "writer"))
//    {
//        if (MP4GetMetadataWriter(file, &pVal))
//        {
//            strncpy(dest, pVal, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "title"))
//    {
//        if (MP4GetMetadataName(file, &pVal))
//        {
//            strncpy(dest, pVal, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "album"))
//    {
//        if (MP4GetMetadataAlbum(file, &pVal))
//        {
//            strncpy(dest, pVal, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "date") || !stricmp(item, "year"))
//    {
//        if (MP4GetMetadataYear(file, &pVal))
//        {
//            strncpy(dest, pVal, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "comment"))
//    {
//        if (MP4GetMetadataComment(file, &pVal))
//        {
//            strncpy(dest, pVal, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "genre"))
//    {
//        if (MP4GetMetadataGenre(file, &pVal))
//        {
//            strncpy(dest, pVal, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else if (!stricmp(item, "tool"))
//    {
//        if (MP4GetMetadataTool(file, &pVal))
//        {
//            strncpy(dest, pVal, dlen-1);
//            dest[dlen-1] = '\0';
//            return 1;
//        }
//    }
//    else
//    {
//        u_int32_t valueSize = 0;
//        u_int8_t *pValue = NULL;
//
//        if (MP4GetMetadataFreeForm(file, (char *)item, &pValue, &valueSize))
//        {
//            unsigned int len = (valueSize < (unsigned int)(dlen-1)) ? valueSize : (unsigned int)(dlen-1);
//            memcpy(dest, pValue, len);
//            dest[len] = '\0';
//            return 1;
//        }
//    }
//
//    return 0;
//}
//
//__declspec(dllexport) int winampGetExtendedFileInfo(const char *fn, const char *data, char *dest, int destlen)
//{
//    if (!fn || (fn && !*fn) || !destlen) return 0;
//
//    dest[0] = '\0';
//
//    if (!stricmp(data, "length"))
//    {
//        char temp[32];
//        int len = getsonglength(fn);
//        itoa(len, temp, 10);
//        strncpy(dest, temp, destlen-1);
//        dest[destlen-1] = '\0';
//    }
//    else
//    {
//        char temp[2048], temp2[2048];
//        MP4FileHandle file = MP4Read(fn, 0);
//        if (file == MP4_INVALID_FILE_HANDLE) return 0;
//
//        if (mp4_get_metadata(file, data, temp, sizeof(temp)))
//        {
//            int len = ConvertUTF8ToANSI(temp, temp2);
//            if (len > destlen-1) len = destlen-1;
//            memcpy(dest, temp2, len);
//            dest[len] = '\0';
//        }
//
//        MP4Close(file);
//    }
//
//    return 1;
//}
//
//static struct medialib_tags mltags = {0, 0};
//static BOOL medialib_init = FALSE;
//static char medialib_lastfn[2048] = "";
//
//__declspec(dllexport) int winampSetExtendedFileInfo(const char *fn, const char *data, char *val)
//{
//    int len, ret = 0;
//    char *temp;
//
//    if (!medialib_init || (medialib_init && stricmp(fn, medialib_lastfn))) {
//        MP4FileHandle file;
//        strcpy(medialib_lastfn, fn);
//
//        if (medialib_init) tag_delete(&mltags);
//
//        file = MP4Read(fn, 0);
//        if (file == MP4_INVALID_FILE_HANDLE) return 0;
//        ReadMP4Tag(file, &mltags);
//        MP4Close(file);
//        medialib_init = TRUE;
//    }
//
//    len = strlen(val);
//    temp = (char *)malloc((len+1)*4);
//    if (!temp) return 0;
//
//    if (ConvertANSIToUTF8(val, temp))
//    {
//        ret = 1;
//        tag_set_field(&mltags, data, temp);
//    }
//
//    free(temp);
//
//    return ret;
//}    
//
//__declspec(dllexport) int winampWriteExtendedFileInfo()
//{
//    if (medialib_init)
//    {
//        MP4FileHandle file = MP4Modify(medialib_lastfn, 0, 0);
//        if (file == MP4_INVALID_FILE_HANDLE) return 0;
//
//        MP4MetadataDelete(file);
//        MP4Close(file);
//
//        file = MP4Modify(medialib_lastfn, 0, 0);
//        if (file == MP4_INVALID_FILE_HANDLE) return 0;
//
//        WriteMP4Tag(file, &mltags);
//
//        MP4Close(file);
//
//        return 1;
//    }
//    else
//    {
//        return 0;
//    }
//}

M plugins/QCDMp4/QCDMp4.rc => plugins/QCDMp4/QCDMp4.rc +70 -0
@@ 13,6 13,76 @@
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// ����(�л����񹲺͹�) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32

/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_CONFIG DIALOGEX 0, 0, 242, 93
STYLE DS_SETFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | 
    WS_SYSMENU
CAPTION "Configuration"
FONT 9, "����", 400, 0, 0x86
BEGIN
    CONTROL         "Slider1",IDC_PRIORITY,"msctls_trackbar32",TBS_VERT | 
                    TBS_NOTICKS | WS_TABSTOP,13,15,18,46
    CONTROL         "16 λ",IDC_16BITS,"Button",BS_AUTORADIOBUTTON,77,18,37,
                    10
    CONTROL         "16 λ��Ƶ����",IDC_16BITS_DITHERED,"Button",
                    BS_AUTORADIOBUTTON | WS_DISABLED,77,29,64,10
    CONTROL         "24 λ",IDC_24BITS,"Button",BS_AUTORADIOBUTTON,77,40,37,
                    10
    CONTROL         "32 λ",IDC_32BITS,"Button",BS_AUTORADIOBUTTON,77,51,37,
                    10
    CONTROL         "���»�Ƶ��������",IDC_DOWNMIX,"Button",BS_AUTOCHECKBOX | 
                    WS_TABSTOP,152,13,80,10
    CONTROL         "֧�� AAC ��ʽ",IDC_USEFORAAC,"Button",BS_AUTOCHECKBOX | 
                    WS_TABSTOP,152,26,68,10
    CONTROL         "��ʾ�ɱ������",IDC_VBR,"Button",BS_AUTOCHECKBOX | 
                    WS_TABSTOP,152,39,72,10
    CONTROL         "��ʾ������Ϣ",IDC_ERROR,"Button",BS_AUTOCHECKBOX | 
                    WS_TABSTOP,152,52,64,10
    DEFPUSHBUTTON   "ȷ��",IDOK,185,72,50,14
    PUSHBUTTON      "ȡ��",IDCANCEL,127,72,50,14
    GROUPBOX        "���ȼ�",IDC_STATIC,7,7,57,58
    LTEXT           "��",IDC_STATIC,34,18,25,8
    LTEXT           "��׼",IDC_STATIC,34,35,23,8
    LTEXT           "��",IDC_STATIC,34,52,24,8
    GROUPBOX        "������",IDC_STATIC,71,7,73,58
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO 
BEGIN
    IDD_CONFIG, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 235
        TOPMARGIN, 7
        BOTTOMMARGIN, 86
    END
END
#endif    // APSTUDIO_INVOKED

#endif    // ����(�л����񹲺͹�) resources
/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////
// ������(����) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NLD)

M plugins/QCDMp4/QCDMp4.vcproj => plugins/QCDMp4/QCDMp4.vcproj +3 -13
@@ 83,6 83,7 @@
			ATLMinimizesCRunTimeLibraryUsage="FALSE">
			<Tool
				Name="VCCLCompilerTool"
				Optimization="1"
				GlobalOptimizations="TRUE"
				InlineFunctionExpansion="1"
				EnableIntrinsicFunctions="TRUE"


@@ 91,7 92,7 @@
				AdditionalIncludeDirectories="..\..\include,..\..\common\mp4v2,..\..\common\mp4av"
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
				StringPooling="TRUE"
				RuntimeLibrary="0"
				RuntimeLibrary="2"
				EnableFunctionLevelLinking="TRUE"
				UsePrecompiledHeader="2"
				PrecompiledHeaderFile=".\Release/QCDMp4.pch"


@@ 110,6 111,7 @@
				OutputFile=".\Release/QCDMp4.dll"
				LinkIncremental="1"
				SuppressStartupBanner="TRUE"
				IgnoreDefaultLibraryNames=""
				ProgramDatabaseFile=".\Release/QCDMp4.pdb"
				SubSystem="2"
				ImportLibrary=".\Release/QCDMp4.lib"/>


@@ 149,12 151,6 @@
			Name="Source Files"
			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
			<File
				RelativePath="aac2mp4.cpp">
			</File>
			<File
				RelativePath="aacinfo.c">
			</File>
			<File
				RelativePath=".\config.c">
			</File>
			<File


@@ 171,12 167,6 @@
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl">
			<File
				RelativePath="aac2mp4.h">
			</File>
			<File
				RelativePath="aacinfo.h">
			</File>
			<File
				RelativePath=".\config.h">
			</File>
			<File

M plugins/QCDMp4/QCDMp4Tag.cpp => plugins/QCDMp4/QCDMp4Tag.cpp +367 -39
@@ 6,7 6,298 @@
//..............................................................................
// Global Variables

typedef struct tag
{
    char *item;
    char *value;
} tag;

typedef struct medialib_tags
{
    struct tag *tags;
    unsigned int count;
} medialib_tags;

int tag_add_field(medialib_tags *tags, const char *item, const char *value)
{
    void *backup = (void *)tags->tags;

    if (!item || (item && !*item) || !value) return 0;

    tags->tags = (struct tag *)realloc(tags->tags, (tags->count+1) * sizeof(tag));
    if (!tags->tags) {
        if (backup) free(backup);
        return 0;
    }
    else
    {
        int i_len = strlen(item);
        int v_len = strlen(value);

        tags->tags[tags->count].item = (char *)malloc(i_len+1);
        tags->tags[tags->count].value = (char *)malloc(v_len+1);

        if (!tags->tags[tags->count].item || !tags->tags[tags->count].value)
        {
            if (!tags->tags[tags->count].item) free (tags->tags[tags->count].item);
            if (!tags->tags[tags->count].value) free (tags->tags[tags->count].value);
            tags->tags[tags->count].item = NULL;
            tags->tags[tags->count].value = NULL;
            return 0;
        }

        memcpy(tags->tags[tags->count].item, item, i_len);
        memcpy(tags->tags[tags->count].value, value, v_len);
        tags->tags[tags->count].item[i_len] = '\0';
        tags->tags[tags->count].value[v_len] = '\0';

        tags->count++;
        return 1;
    }
}

int tag_set_field(medialib_tags *tags, const char *item, const char *value)
{
    unsigned int i;

    if (!item || (item && !*item) || !value) return 0;

    for (i = 0; i < tags->count; i++)
    {
        if (!stricmp(tags->tags[i].item, item))
        {
            void *backup = (void *)tags->tags[i].value;
            int v_len = strlen(value);

            tags->tags[i].value = (char *)realloc(tags->tags[i].value, v_len+1);
            if (!tags->tags[i].value)
            {
                if (backup) free(backup);
                return 0;
            }

            memcpy(tags->tags[i].value, value, v_len);
            tags->tags[i].value[v_len] = '\0';

            return 1;
        }
    }

    return tag_add_field(tags, item, value);
}

void tag_delete(medialib_tags *tags)
{
    unsigned int i;

    for (i = 0; i < tags->count; i++)
    {
        if (tags->tags[i].item) free(tags->tags[i].item);
        if (tags->tags[i].value) free(tags->tags[i].value);
    }

    if (tags->tags) free(tags->tags);

    tags->tags = NULL;
    tags->count = 0;
}

int ReadMP4Tag(MP4FileHandle file, medialib_tags *tags)
{
    unsigned __int32 valueSize;
    unsigned __int8 *pValue;
    char *pName;
    unsigned int i = 0;

    do {
        pName = 0;
        pValue = 0;
        valueSize = 0;

        MP4GetMetadataByIndex(file, i, (const char **)&pName, &pValue, &valueSize);

        if (valueSize > 0)
        {
            char *val = (char *)malloc(valueSize+1);
            if (!val) return 0;
            memcpy(val, pValue, valueSize);
            val[valueSize] = '\0';

            if (pName[0] == '\xa9')
            {
                if (memcmp(pName, "�nam", 4) == 0)
                {
                    tag_add_field(tags, "title", val);
                } else if (memcmp(pName, "�ART", 4) == 0) {
                    tag_add_field(tags, "artist", val);
                } else if (memcmp(pName, "�wrt", 4) == 0) {
                    tag_add_field(tags, "writer", val);
                } else if (memcmp(pName, "�alb", 4) == 0) {
                    tag_add_field(tags, "album", val);
                } else if (memcmp(pName, "�day", 4) == 0) {
                    tag_add_field(tags, "date", val);
                } else if (memcmp(pName, "�too", 4) == 0) {
                    tag_add_field(tags, "tool", val);
                } else if (memcmp(pName, "�cmt", 4) == 0) {
                    tag_add_field(tags, "comment", val);
                } else if (memcmp(pName, "�gen", 4) == 0) {
                    tag_add_field(tags, "genre", val);
                } else {
                    tag_add_field(tags, pName, val);
                }
            } else if (memcmp(pName, "gnre", 4) == 0) {
                char *t=0;
                if (MP4GetMetadataGenre(file, &t))
                {
                    tag_add_field(tags, "genre", t);
                }
            } else if (memcmp(pName, "trkn", 4) == 0) {
                unsigned __int16 trkn = 0, tot = 0;
                char t[200];
                if (MP4GetMetadataTrack(file, &trkn, &tot))
                {
                    if (tot > 0)
                        wsprintf(t, "%d/%d", trkn, tot);
                    else
                        wsprintf(t, "%d", trkn);
                    tag_add_field(tags, "tracknumber", t);
                }
            } else if (memcmp(pName, "disk", 4) == 0) {
                unsigned __int16 disk = 0, tot = 0;
                char t[200];
                if (MP4GetMetadataDisk(file, &disk, &tot))
                {
                    if (tot > 0)
                        wsprintf(t, "%d/%d", disk, tot);
                    else
                        wsprintf(t, "%d", disk);
                    tag_add_field(tags, "disc", t);
                }
            } else if (memcmp(pName, "cpil", 4) == 0) {
                unsigned __int8 cpil = 0;
                char t[200];
                if (MP4GetMetadataCompilation(file, &cpil))
                {
                    wsprintf(t, "%d", cpil);
                    tag_add_field(tags, "compilation", t);
                }
            } else if (memcmp(pName, "tmpo", 4) == 0) {
                unsigned __int16 tempo = 0;
                char t[200];
                if (MP4GetMetadataTempo(file, &tempo))
                {
                    wsprintf(t, "%d BPM", tempo);
                    tag_add_field(tags, "tempo", t);
                }
            } else if (memcmp(pName, "NDFL", 4) == 0) {
                /* Removed */
            } else {
                tag_add_field(tags, pName, val);
            }

            free(val);
        }

        i++;
    } while (valueSize > 0);

    return 1;
}

int mp4_set_metadata(MP4FileHandle file, const char *item, const char *val)
{
    if (!item || (item && !*item) || !val || (val && !*val)) return 0;

    if (!stricmp(item, "track") || !stricmp(item, "tracknumber"))
    {
        unsigned __int16 trkn, tot;
        int t1 = 0, t2 = 0;
        sscanf(val, "%d/%d", &t1, &t2);
        trkn = t1, tot = t2;
        if (!trkn) return 1;
        if (MP4SetMetadataTrack(file, trkn, tot)) return 1;
    }
    else if (!stricmp(item, "disc") || !stricmp(item, "disknumber"))
    {
        unsigned __int16 disk, tot;
        int t1 = 0, t2 = 0;
        sscanf(val, "%d/%d", &t1, &t2);
        disk = t1, tot = t2;
        if (!disk) return 1;
        if (MP4SetMetadataDisk(file, disk, tot)) return 1;
    }
    else if (!stricmp(item, "compilation"))
    {
        unsigned __int8 cpil = atoi(val);
        if (!cpil) return 1;
        if (MP4SetMetadataCompilation(file, cpil)) return 1;
    }
    else if (!stricmp(item, "tempo"))
    {
        unsigned __int16 tempo = atoi(val);
        if (!tempo) return 1;
        if (MP4SetMetadataTempo(file, tempo)) return 1;
    }
    else if (!stricmp(item, "artist"))
    {
        if (MP4SetMetadataArtist(file, val)) return 1;
    }
    else if (!stricmp(item, "writer"))
    {
        if (MP4SetMetadataWriter(file, val)) return 1;
    }
    else if (!stricmp(item, "title"))
    {
        if (MP4SetMetadataName(file, val)) return 1;
    }
    else if (!stricmp(item, "album"))
    {
        if (MP4SetMetadataAlbum(file, val)) return 1;
    }
    else if (!stricmp(item, "date") || !stricmp(item, "year"))
    {
        if (MP4SetMetadataYear(file, val)) return 1;
    }
    else if (!stricmp(item, "comment"))
    {
        if (MP4SetMetadataComment(file, val)) return 1;
    }
    else if (!stricmp(item, "genre"))
    {
        if (MP4SetMetadataGenre(file, val)) return 1;
    }
    else if (!stricmp(item, "tool"))
    {
        if (MP4SetMetadataTool(file, val)) return 1;
    }
    else
    {
        if (MP4SetMetadataFreeForm(file, (char *)item, (u_int8_t *)val, (u_int32_t)strlen(val) + 1)) return 1;
    }

    return 0;
}

void WriteMP4Tag(MP4FileHandle file, const medialib_tags *tags)
{
    unsigned int i;

    for (i = 0; i < tags->count; i++)
    {
        const char *item = tags->tags[i].item;
        const char *value = tags->tags[i].value;

        if (value && *value)
        {
            mp4_set_metadata(file, item, value);
        }
    }
}

QCDModInitTag	ModInitTag;

medialib_tags tags;

BOOL uSetDlgItemText(void *tagHandle, int fieldId, const char *str);
UINT uGetDlgItemText(void *tagHandle, int fieldId, char *str, int max);



@@ 35,6 326,7 @@ void ShutDown_Tag(int flags)
	// TODO:
	// prepare plugin to be unloaded. All allocations should be freed.
	// flags param is unused
	tag_delete(&tags);
}

//-----------------------------------------------------------------------------


@@ 56,8 348,7 @@ bool Read_Tag(LPCSTR filename, void* tagHandle)
	MP4FileHandle file = MP4_INVALID_FILE_HANDLE;
	char *pVal, dummy1[1024];
	short dummy, dummy2;

	unsigned __int32 valueSize = 0;
	u_int32_t valueSize = 0;

#ifdef DEBUG_OUTPUT
	in_mp4_DebugOutput("mp4_tag_read");


@@ 96,26 387,41 @@ bool Read_Tag(LPCSTR filename, void* tagHandle)

	//dummy = 0;
	//MP4GetMetadataTempo(file, &dummy);
	//wsprintf(dummy1, "%d", dummy);
	//SetDlgItemText(hwndDlg,IDC_METATEMPO, dummy1);
	//if (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);
	if (dummy)
	{
		wsprintf(dummy1, "%d", dummy);
		ModInitTag.SetFieldA(tagHandle, TAGFIELD_TRACK, dummy1);
	}
	//if (dumm2)
	//{
	//	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);
	//if (dummy)
	//{
	//	wsprintf(dummy1, "%d", dummy);
	//	SetDlgItemText(hwndDlg,IDC_METADISK1, dummy1);
	//}
	//if (dummy)
	//{
	//	wsprintf(dummy1, "%d", dummy2);
	//	SetDlgItemText(hwndDlg,IDC_METADISK2, dummy1);
	//}

	pVal = NULL;
	MP4GetMetadataYear(file, &pVal);
	uSetDlgItemText(tagHandle, TAGFIELD_YEAR, pVal);
	if (MP4GetMetadataYear(file, &pVal))
		uSetDlgItemText(tagHandle, TAGFIELD_YEAR, pVal);

	//dummy3 = 0;
	//MP4GetMetadataCompilation(file, &dummy3);


@@ 179,6 485,7 @@ bool Write_Tag(LPCSTR filename, void* tagHandle)

	MP4FileHandle file = MP4_INVALID_FILE_HANDLE;
    char dummy1[1024];
    char temp[1024];
    short dummy, dummy2;

#ifdef DEBUG_OUTPUT


@@ 187,76 494,95 @@ bool Write_Tag(LPCSTR filename, void* tagHandle)

	/* save Metadata changes */

	tag_delete(&tags);
	file = MP4Read(filename, 0);
	if (file != MP4_INVALID_FILE_HANDLE)
	{
		ReadMP4Tag(file, &tags);
		MP4Close(file);

		file = MP4Modify(filename, 0, 0);
		if (file != MP4_INVALID_FILE_HANDLE)
		{
			MP4MetadataDelete(file);
			MP4Close(file);
		}
	}

	file = MP4Modify(filename, 0, 0);
	if (file == MP4_INVALID_FILE_HANDLE)
	{
		tag_delete(&tags);
		//EndDialog(hwndDlg, wParam);
		return false;
	}

	uGetDlgItemText(tagHandle, TAGFIELD_TITLE, dummy1, 1024);
	MP4SetMetadataName(file, dummy1);
	tag_set_field(&tags, "title", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_COMPOSER, dummy1, 1024);
	MP4SetMetadataWriter(file, dummy1);
	tag_set_field(&tags, "writer", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_ARTIST, dummy1, 1024);
	MP4SetMetadataArtist(file, dummy1);
	tag_set_field(&tags, "artist", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_ALBUM, dummy1, 1024);
	MP4SetMetadataAlbum(file, dummy1);
	tag_set_field(&tags, "album", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_COMMENT, dummy1, 1024);
	MP4SetMetadataComment(file, dummy1);
	tag_set_field(&tags, "comment", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_GENRE, dummy1, 1024);
	MP4SetMetadataGenre(file, dummy1);
	tag_set_field(&tags, "genre", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_YEAR, dummy1, 1024);
	MP4SetMetadataYear(file, dummy1);
	tag_set_field(&tags, "year", dummy1);

	dummy = 0; dummy2 = 0;
	dummy = 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);
	wsprintf(temp, "%d/%d", dummy, dummy2);
	tag_set_field(&tags, "track", temp);

	//GetDlgItemText(hwndDlg, IDC_METADISK1, dummy1, 1024);
	//dummy = atoi(dummy1);
	//GetDlgItemText(hwndDlg, IDC_METADISK2, dummy1, 1024);
	//dummy2 = atoi(dummy1);
	//MP4SetMetadataDisk(file, dummy, dummy2);
	//wsprintf(temp, "%d/%d", dummy, dummy2);
	//tag_set_field(&tags, "disc", temp);

	//GetDlgItemText(hwndDlg, IDC_METATEMPO, dummy1, 1024);
	//dummy = atoi(dummy1);
	//MP4SetMetadataTempo(file, dummy);
	//tag_set_field(&tags, "tempo", dummy1);

	//dummy3 = SendMessage(GetDlgItem(hwndDlg, IDC_METACOMPILATION), BM_GETCHECK, 0, 0);
	//MP4SetMetadataCompilation(file, dummy3);
	//tag_set_field(&tags, "compilation", (dummy3 ? "1" : "0"));

	uGetDlgItemText(tagHandle, TAGFIELD_ENCODER, dummy1, 1024);
	MP4SetMetadataTool(file, dummy1);
	tag_set_field(&tags, "tool", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_CONDUCTOR, dummy1, 1024);
	MP4SetMetadataFreeForm(file, "CONDUCTOR", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
	tag_set_field(&tags, "CONDUCTOR", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_ORCHESTRA, dummy1, 1024);
	MP4SetMetadataFreeForm(file, "ORCHESTRA", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
	tag_set_field(&tags, "ORCHESTRA", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_YEARCOMPOSED, dummy1, 1024);
	MP4SetMetadataFreeForm(file, "YEARCOMPOSED", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
	tag_set_field(&tags, "YEARCOMPOSED", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_ORIGARTIST, dummy1, 1024);
	MP4SetMetadataFreeForm(file, "ORIGARTIST", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
	tag_set_field(&tags, "ORIGARTIST", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_LABEL, dummy1, 1024);
	MP4SetMetadataFreeForm(file, "LABEL", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
	tag_set_field(&tags, "LABEL", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_COPYRIGHT, dummy1, 1024);
	MP4SetMetadataFreeForm(file, "COPYRIGHT", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
	tag_set_field(&tags, "COPYRIGHT", dummy1);

	uGetDlgItemText(tagHandle, TAGFIELD_CDDBTAGID, dummy1, 1024);
	MP4SetMetadataFreeForm(file, "CDDBTAGID", (unsigned __int8*)dummy1, strlen(dummy1) + 1);
	tag_set_field(&tags, "CDDBTAGID", dummy1);

	WriteMP4Tag(file, &tags);

	MP4Close(file);



@@ 459,6 785,7 @@ BOOL uSetDlgItemText(void *tagHandle, int fieldId, const char *str)
    int r;

    if (!str) return FALSE;
	if (!*str) return FALSE;
    len = strlen(str);
    temp = (char *)malloc(len+1);
    if (!temp) return FALSE;


@@ 478,7 805,7 @@ UINT uGetDlgItemText(void *tagHandle, int fieldId, char *str, int max)

	const char *p;

    if (!str) return 0;
    if (!str || !max) return 0;
    len = strlen( ModInitTag.GetFieldA(tagHandle, fieldId) );
    temp = (char *)malloc(len+1);
    if (!temp) return 0;


@@ 491,6 818,7 @@ UINT uGetDlgItemText(void *tagHandle, int fieldId, char *str, int max)

	memset(temp, '\0', len+1);
	memset(utf8, '\0', (len+1)*4);
	memset(str, '\0', max);
	p = ModInitTag.GetFieldA(tagHandle, fieldId);
	memcpy(temp, p, len+1);
    if (len > 0)