lame_codec.c
来自「这个库实现了录象功能」· C语言 代码 · 共 685 行 · 第 1/2 页
C
685 行
/******************************************************************************* lame_codec.c libquicktime - A library for reading and writing quicktime/avi/mp4 files. http://libquicktime.sourceforge.net Copyright (C) 2002 Heroine Virtual Ltd. Copyright (C) 2002-2007 Members of the libquicktime project. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************/ #include "lqt_private.h"#include <lame/lame.h>#include <stdlib.h>#include <string.h>#include <lame_codec.h>#define LOG_DOMAIN "lame"/* * We decode all headers to figure out, how many COMPLETE frames we have encoded. *//* The following code was ported from gmerlin_avdecoder (http://gmerlin.sourceforge.net) *//* MPEG Audio header parsing code */static int mpeg_bitrates[5][16] = { /* MPEG-1 */ { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, // I 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0}, { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, // II 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0 }, { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, // III 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0 }, /* MPEG-2 LSF */ { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, // I 128000, 144000, 160000, 176000, 192000, 224000, 256000, 0 }, { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0 } // II & III};static int mpeg_samplerates[3][3] = { { 44100, 48000, 32000 }, // MPEG1 { 22050, 24000, 16000 }, // MPEG2 { 11025, 12000, 8000 } // MPEG2.5 };#define MPEG_ID_MASK 0x00180000#define MPEG_MPEG1 0x00180000#define MPEG_MPEG2 0x00100000#define MPEG_MPEG2_5 0x00000000#define MPEG_LAYER_MASK 0x00060000#define MPEG_LAYER_III 0x00020000#define MPEG_LAYER_II 0x00040000#define MPEG_LAYER_I 0x00060000#define MPEG_PROTECTION 0x00010000#define MPEG_BITRATE_MASK 0x0000F000#define MPEG_FREQUENCY_MASK 0x00000C00#define MPEG_PAD_MASK 0x00000200#define MPEG_PRIVATE_MASK 0x00000100#define MPEG_MODE_MASK 0x000000C0#define MPEG_MODE_EXT_MASK 0x00000030#define MPEG_COPYRIGHT_MASK 0x00000008#define MPEG_HOME_MASK 0x00000004#define MPEG_EMPHASIS_MASK 0x00000003#define LAYER_I_SAMPLES 384#define LAYER_II_III_SAMPLES 1152/* Header detection stolen from the mpg123 plugin of xmms */static int header_check(uint32_t head){ if ((head & 0xffe00000) != 0xffe00000) return 0; if (!((head >> 17) & 3)) return 0; if (((head >> 12) & 0xf) == 0xf) return 0; if (!((head >> 12) & 0xf)) return 0; if (((head >> 10) & 0x3) == 0x3) return 0; if (((head >> 19) & 1) == 1 && ((head >> 17) & 3) == 3 && ((head >> 16) & 1) == 1) return 0; if ((head & 0xffff0000) == 0xfffe0000) return 0; return 1;}typedef enum { MPEG_VERSION_NONE = 0, MPEG_VERSION_1 = 1, MPEG_VERSION_2 = 2, MPEG_VERSION_2_5 } mpeg_version_t;#define CHANNEL_STEREO 0#define CHANNEL_JSTEREO 1#define CHANNEL_DUAL 2#define CHANNEL_MONO 3typedef struct { mpeg_version_t version; int layer; int bitrate_mode; int bitrate; int min_bitrate; /* ABR only */ int max_bitrate; /* ABR only */ int samplerate; int frame_bytes; int channel_mode; int mode; int samples_per_frame; } mpeg_header;static int decode_header(mpeg_header * h, uint8_t * ptr) { uint32_t header; int index; /* For calculation of the byte length of a frame */ int pad; int slots_per_frame; h->frame_bytes = 0; header = ptr[3] | (ptr[2] << 8) | (ptr[1] << 16) | (ptr[0] << 24); if(!header_check(header)) return 0; index = (header & MPEG_MODE_MASK) >> 6; switch(index) { case 0: h->channel_mode = CHANNEL_STEREO; break; case 1: h->channel_mode = CHANNEL_JSTEREO; break; case 2: h->channel_mode = CHANNEL_DUAL; break; case 3: h->channel_mode = CHANNEL_MONO; break; } /* Get Version */ switch(header & MPEG_ID_MASK) { case MPEG_MPEG1: h->version = MPEG_VERSION_1; break; case MPEG_MPEG2: h->version = MPEG_VERSION_2; break; case MPEG_MPEG2_5: h->version = MPEG_VERSION_2_5; break; default: return 0; } /* Get Layer */ switch(header & MPEG_LAYER_MASK) { case MPEG_LAYER_I: h->layer = 1; break; case MPEG_LAYER_II: h->layer = 2; break; case MPEG_LAYER_III: h->layer = 3; break; } index = (header & MPEG_BITRATE_MASK) >> 12; switch(h->version) { case MPEG_VERSION_1: switch(h->layer) { case 1: h->bitrate = mpeg_bitrates[0][index]; break; case 2: h->bitrate = mpeg_bitrates[1][index]; break; case 3: h->bitrate = mpeg_bitrates[2][index]; break; } break; case MPEG_VERSION_2: case MPEG_VERSION_2_5: switch(h->layer) { case 1: h->bitrate = mpeg_bitrates[3][index]; break; case 2: case 3: h->bitrate = mpeg_bitrates[4][index]; break; } break; default: // This won't happen, but keeps gcc quiet return 0; } index = (header & MPEG_FREQUENCY_MASK) >> 10; switch(h->version) { case MPEG_VERSION_1: h->samplerate = mpeg_samplerates[0][index]; break; case MPEG_VERSION_2: h->samplerate = mpeg_samplerates[1][index]; break; case MPEG_VERSION_2_5: h->samplerate = mpeg_samplerates[2][index]; break; default: // This won't happen, but keeps gcc quiet return 0; } pad = (header & MPEG_PAD_MASK) ? 1 : 0; if(h->layer == 1) { h->frame_bytes = ((12 * h->bitrate / h->samplerate) + pad) * 4; } else { slots_per_frame = ((h->layer == 3) && ((h->version == MPEG_VERSION_2) || (h->version == MPEG_VERSION_2_5))) ? 72 : 144; h->frame_bytes = (slots_per_frame * h->bitrate) / h->samplerate + pad; } // h->mode = (ptr[3] >> 6) & 3; h->samples_per_frame = (h->layer == 1) ? LAYER_I_SAMPLES : LAYER_II_III_SAMPLES; if(h->version != MPEG_VERSION_1) h->samples_per_frame /= 2; // dump_header(h); return 1; }typedef struct { // mp3 encoder lame_global_flags *lame_global; // mpeg3_layer_t *encoded_header; int encode_initialized; int input_size; int input_allocated; unsigned char *encoder_output; int encoder_output_alloc; int encoder_output_size; int samples_per_frame; int stereo; int16_t * input_buffer[2]; int input_buffer_alloc; int64_t samples_read; /* samples passed to lame_encode_buffer */ int64_t samples_written; /* samples written to the file */ /* Configuration stuff */ int bitrate_mode; int bitrate; int bitrate_min; int bitrate_max; int quality; int quality_vbr; } quicktime_mp3_codec_t;static int delete_codec(quicktime_audio_map_t *atrack) { quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv; // if(codec->mp3) mpeg3_delete_layer(codec->mp3); // if(codec->mp3_header) mpeg3_delete_layer(codec->mp3_header); // if(codec->packet_buffer) free(codec->packet_buffer); /* if(codec->output) */ /* { */ /* int i; */ /* for(i = 0; i < atrack->channels; i++) */ /* free(codec->output[i]); */ /* free(codec->output); */ /* } */ if(codec->lame_global) { lame_close(codec->lame_global); } if(codec->input_buffer[0]) free(codec->input_buffer[0]); if(codec->input_buffer[1]) free(codec->input_buffer[1]); if(codec->encoder_output) free(codec->encoder_output); // if(codec->encoded_header) mpeg3_delete_layer(codec->encoded_header); free(codec); return 0; }static int write_data(quicktime_t *file, int track, quicktime_mp3_codec_t *codec, int samples) { mpeg_header h; quicktime_atom_t chunk_atom; int result = 0; int chunk_bytes = 0, chunk_samples = 0; quicktime_audio_map_t *track_map; uint8_t * chunk_ptr; track_map = &file->atracks[track]; memset(&h, 0, sizeof(h));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?