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 + -
显示快捷键?