📄 qcdmp4.c
字号:
/*** 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** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.** ** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.** ** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.**** 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 Mpeg4AAClicense@nero.com.**** $Id: QCDMp4.c,v 1.4 2003/12/06 04:24:17 rjamorim Exp $**///#define DEBUG_OUTPUT#define WIN32_LEAN_AND_MEAN#include <windows.h>#include <commctrl.h>#include <commdlg.h>#include <stdlib.h>#include <math.h>#include <faad.h>#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, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_LOWEST};static int res_id_table[] = { IDC_16BITS, IDC_24BITS, IDC_32BITS, 0, 0, /*IDC_16BITS_DITHERED*/ IDC_16BITS /* temp hack */};static int res_table[] = { 16, 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+2struct seek_list{ struct seek_list *next; __int64 offset;};typedef struct state{ /* general stuff */ faacDecHandle hDecoder; int samplerate; unsigned char channels; 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; int mp4track; MP4SampleId numSamples; MP4SampleId sampleId; /* AAC stuff */ FILE *aacfile; 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;//static In_Module module; // the output module (declared near the bottom of this file)struct { HINSTANCE hDllInstance; HWND hMainWindow; QCDModInitIn QCDCallbacks;} module;AudioInfo ai;static int killPlayThread;static int PlayThreadAlive = 0; // 1=play thread still runningHANDLE 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 procedureDWORD 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, "﹏am", 4) == 0)// {// tag_add_field(tags, "title", val);// } else if (memcmp(pName, "〢RT", 4) == 0) {// tag_add_field(tags, "artist", val);// } else if (memcmp(pName, "﹚rt", 4) == 0) {// tag_add_field(tags, "writer", val);// } else if (memcmp(pName, "゛lb", 4) == 0) {// tag_add_field(tags, "album", val);// } else if (memcmp(pName, "ヾay", 4) == 0) {// tag_add_field(tags, "date", val);// } else if (memcmp(pName, "﹖oo", 4) == 0) {// tag_add_field(tags, "tool", val);// } else if (memcmp(pName, "ヽmt", 4) == 0) {// tag_add_field(tags, "comment", val);// } else if (memcmp(pName, "ゞen", 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_OUTPUTvoid in_mp4_DebugOutput(char *message){ char s[1024]; sprintf(s, "in_mp4: %s: %s", mp4state.filename, message); OutputDebugString(s);}#endifint file_length(FILE *f){ long end = 0; long cur = ftell(f);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -