📄 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.56 2004/10/19 18:02:10 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+2
struct 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 running
HANDLE 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 procedure
DWORD WINAPI AACPlayThread(void *b); // the decode thread procedure
uint32_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 + -