📄 in_mp4.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: in_mp4.c,v 1.54 2004/09/04 14:56:30 menno Exp $**///#define DEBUG_OUTPUT#define WIN32_LEAN_AND_MEAN#include <windows.h>#include <commctrl.h>#include <commdlg.h>#include <stdlib.h>#include <stdio.h>#include <io.h>#include <math.h>#include <neaacdec.h>#define USE_TAGGING#include <mp4ff.h>#include "resource.h"#include "in2.h"#include "utils.h"#include "config.h"#include "aacinfo.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 */ NeAACDecHandle 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 */ mp4ff_t *mp4file; int mp4track; long numSamples; long sampleId; mp4ff_callback_t mp4cb; FILE *mp4File; /* 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)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, NeAACDecFrameInfo *frameInfo);DWORD WINAPI MP4PlayThread(void *b); // the decode thread procedureDWORD WINAPI AACPlayThread(void *b); // the decode thread procedureuint32_t read_callback(void *user_data, void *buffer, uint32_t length){ return fread(buffer, 1, length, (FILE*)user_data);}uint32_t seek_callback(void *user_data, uint64_t position){ return fseek((FILE*)user_data, position, SEEK_SET);}uint32_t write_callback(void *user_data, void *buffer, uint32_t length){ return fwrite(buffer, 1, length, (FILE*)user_data);}uint32_t truncate_callback(void *user_data){ _chsize(fileno((FILE*)user_data), ftell((FILE*)user_data)); return 1;}int tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value, size_t v_len){ void *backup = (void *)tags->tags; if (!item || (item && !*item) || !value) return 0; tags->tags = (mp4ff_tag_t *)realloc(tags->tags, (tags->count+1) * sizeof(mp4ff_tag_t)); if (!tags->tags) { if (backup) free(backup); return 0; } else { size_t i_len = strlen(item); if (v_len == 0) 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->tags[tags->count].len = v_len; tags->count++; return 1; }}int tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value, size_t v_len){ 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; if (v_len == 0) 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';// tags->tags[i].len = v_len; return 1; } } return tag_add_field(tags, item, value, v_len);}int tag_delete(mp4ff_metadata_t *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(mp4ff_t *file, mp4ff_metadata_t *tags){ unsigned __int8 *pValue; char *pName; unsigned int i = 0; do { pName = 0; pValue = 0; if (mp4ff_meta_get_by_index(file, i, (char **)&pName, &pValue)) { char *val = (char *)strdup(pValue); if (!val) return 0; if (pName[0] == '
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -