lame_codec.c

来自「这个库实现了录象功能」· C语言 代码 · 共 685 行 · 第 1/2 页

C
685
字号
  chunk_ptr = codec->encoder_output;  while(codec->encoder_output_size > 4)    {    if(!decode_header(&h, chunk_ptr))      {      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "Ouch: lame created non mp3 data\n");      break;      }    if(codec->encoder_output_size >= h.frame_bytes)      {      codec->encoder_output_size -= h.frame_bytes;      chunk_ptr += h.frame_bytes;      chunk_bytes += h.frame_bytes;      chunk_samples += h.samples_per_frame;      }    else      break;    }  if(chunk_ptr > codec->encoder_output)    {    if(track_map->track->strl)      {      quicktime_write_chunk_header(file, track_map->track, &chunk_atom);      result = !quicktime_write_data(file, codec->encoder_output, chunk_bytes);      quicktime_write_chunk_footer(file,                                    track_map->track,                                    track_map->current_chunk,                                   &chunk_atom,                                   chunk_samples);      if(file->total_riffs == 1)        {        track_map->track->strl->strh.dwLength += chunk_bytes;        }      }    else      {      lqt_start_audio_vbr_chunk(file, track);      quicktime_write_chunk_header(file, track_map->track, &chunk_atom);      lqt_start_audio_vbr_frame(file, track);      result = !quicktime_write_data(file, codec->encoder_output, chunk_bytes);          if(samples < 0)        {        lqt_finish_audio_vbr_frame(file, track, chunk_samples);        quicktime_write_chunk_footer(file,                                      track_map->track,                                      track_map->current_chunk,                                     &chunk_atom,                                     track_map->vbr_num_frames);        codec->samples_written += chunk_samples;        }      else        {        lqt_finish_audio_vbr_frame(file, track, samples);        quicktime_write_chunk_footer(file,                                      track_map->track,                                      track_map->current_chunk,                                     &chunk_atom,                                     track_map->vbr_num_frames);        codec->samples_written += samples;        }      }        track_map->current_chunk++;    /* Adjust mp3 buffer */    if(codec->encoder_output_size)      memmove(codec->encoder_output, chunk_ptr, codec->encoder_output_size);        }      return result;  }#define PUT_16_LE(num, ptr) \ptr[0] = num & 0xff; \ptr[1] = (num >> 8) & 0xff;\ptr+=2;#define PUT_32_LE(num, ptr) \ptr[0] = num & 0xff; \ptr[1] = (num >> 8) & 0xff;\ptr[2] = (num >> 16) & 0xff;\ptr[3] = (num >> 24) & 0xff;\ptr+=4;/* nanosoft style mp3 definitions */#define MPEGLAYER3_ID_UNKNOWN            0#define MPEGLAYER3_ID_MPEG               1#define MPEGLAYER3_ID_CONSTANTFRAMESIZE  2#define MPEGLAYER3_FLAG_PADDING_ISO      0x00000000#define MPEGLAYER3_FLAG_PADDING_ON       0x00000001#define MPEGLAYER3_FLAG_PADDING_OFF      0x00000002static int encode(quicktime_t *file,                   void * _input,                   long samples,                  int track)  {  int16_t * input;  int result = 0;  int encoded_size;  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_trak_t *trak = track_map->track;  quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  int i;  uint8_t extradata[12];  uint8_t * extradata_ptr;  uint32_t tmp;  int mpeg_version;    if(!codec->encode_initialized)    {    if(!trak->strl)      lqt_init_vbr_audio(file, track);    codec->encode_initialized = 1;    codec->lame_global = lame_init();    if(trak->strl || (codec->bitrate_mode == vbr_off))      {      lame_set_VBR(codec->lame_global, vbr_off);      lame_set_brate(codec->lame_global, codec->bitrate / 1000);      }    else if(codec->bitrate_mode == vbr_default)      {      lame_set_VBR(codec->lame_global, vbr_default);      lame_set_VBR_q(codec->lame_global, codec->quality_vbr);      }    else if(codec->bitrate_mode == vbr_abr)      {      lame_set_VBR(codec->lame_global, vbr_abr);      lame_set_VBR_min_bitrate_kbps(codec->lame_global, codec->bitrate_min/1000);      lame_set_VBR_max_bitrate_kbps(codec->lame_global, codec->bitrate_max/1000);      }        lame_set_quality(codec->lame_global, codec->quality);    lame_set_in_samplerate(codec->lame_global, track_map->samplerate);    lame_set_out_samplerate(codec->lame_global, track_map->samplerate);        lame_set_bWriteVbrTag(codec->lame_global, 0);        /* Also support Mono streams */        codec->stereo = (trak->mdia.minf.stbl.stsd.table[0].channels == 1) ? 0 : 1;    lame_set_num_channels(codec->lame_global, (codec->stereo ? 2 : 1));        //    lame_set_padding_type(codec->lame_global, PAD_ALL); // PAD_NO | PAD_ALL | PAD_ADJUST        if((result = lame_init_params(codec->lame_global)) < 0)      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "lame_init_params returned %d\n", result);    //    codec->encoded_header = mpeg3_new_layer();    codec->samples_per_frame = lame_get_framesize(codec->lame_global);    /* Initialize AVI header */    if(trak->strl)      {      /* strh stuff */      trak->strl->strh.dwRate = codec->bitrate / 8;      trak->strl->strh.dwScale = 1;      trak->strl->strh.dwSampleSize = 1;      /* WAVEFORMATEX stuff */            trak->strl->strf.wf.f.WAVEFORMAT.nBlockAlign = 1;      trak->strl->strf.wf.f.WAVEFORMAT.nAvgBytesPerSec =  codec->bitrate / 8;      trak->strl->strf.wf.f.PCMWAVEFORMAT.wBitsPerSample = 0;      /* Extradata (completely unneccesary for decoding) */      mpeg_version = lame_get_version(codec->lame_global);            extradata_ptr = extradata;      tmp = MPEGLAYER3_ID_MPEG; // WORD          wID      PUT_16_LE(tmp, extradata_ptr);      tmp = MPEGLAYER3_FLAG_PADDING_ISO; // DWORD         fdwFlags;      PUT_32_LE(tmp, extradata_ptr);            switch(mpeg_version)        {        case 0: // MPEG-2          tmp = ((144000 / 2) * (codec->bitrate/1000)) / track_map->samplerate; // WORD nBlockSize;          break;        case 1: // MPEG-1          tmp = ((144000 / 1) * (codec->bitrate/1000)) / track_map->samplerate; // WORD nBlockSize;          break;        case 2: // MPEG-2.5          tmp = ((144000 / 4) * (codec->bitrate/1000)) / track_map->samplerate; // WORD nBlockSize;          break;        }            PUT_16_LE(tmp, extradata_ptr);      tmp = 1; // WORD nFramesPerBlock;      PUT_16_LE(tmp, extradata_ptr);      tmp = 1393; //  WORD nCodecDelay;      PUT_16_LE(tmp, extradata_ptr);            quicktime_strf_set_audio_extradata(&trak->strl->strf, extradata, 12);      }    }  /* Reallocate output if necessary */  encoded_size = (5*samples)/4 + 7200;    if(codec->encoder_output_alloc < encoded_size + codec->encoder_output_size)    {    codec->encoder_output_alloc = encoded_size + codec->encoder_output_size + 16;    codec->encoder_output       = realloc(codec->encoder_output, codec->encoder_output_alloc);    }  if(codec->input_buffer_alloc < samples)    {    codec->input_buffer_alloc = samples + 16;    codec->input_buffer[0] =      realloc(codec->input_buffer[0], codec->input_buffer_alloc * sizeof(*codec->input_buffer[0]));        if(codec->stereo)      codec->input_buffer[1] =        realloc(codec->input_buffer[1], codec->input_buffer_alloc * sizeof(*codec->input_buffer[1]));    }  input = (int16_t*)_input;      if(codec->stereo)    {    for(i = 0; i < samples; i++)      {      codec->input_buffer[0][i] = *(input++);      codec->input_buffer[1][i] = *(input++);      }    }  else    {    for(i = 0; i < samples; i++)      codec->input_buffer[0][i] = *(input++);    }    result = lame_encode_buffer(codec->lame_global,                              codec->input_buffer[0],                              codec->stereo ? codec->input_buffer[1] : codec->input_buffer[0],                              samples,                              codec->encoder_output + codec->encoder_output_size,                              codec->encoder_output_alloc - codec->encoder_output_size);  codec->samples_read += samples;      if(result > 0)    {    codec->encoder_output_size += result;    result = write_data(file, track, codec, -1);    }    return result;  }static int set_parameter(quicktime_t *file, int track,                          const char *key, const void *value)  {  quicktime_audio_map_t *atrack = &(file->atracks[track]);  quicktime_mp3_codec_t *codec =    ((quicktime_codec_t*)atrack->codec)->priv;    if(!strcasecmp(key, "mp3_bitrate_mode"))    {    if(!strcmp((char*)value, "CBR"))      codec->bitrate_mode = vbr_off;    else if(strcmp((char*)value, "ABR"))      codec->bitrate_mode = vbr_abr;    else if(strcmp((char*)value, "VBR"))      codec->bitrate_mode = vbr_default;    }  else if(!strcasecmp(key, "mp3_bitrate"))    codec->bitrate = *(int*)value;  else if(!strcasecmp(key, "mp3_bitrate_min"))    codec->bitrate_min = *(int*)value;  else if(!strcasecmp(key, "mp3_bitrate_max"))    codec->bitrate_max = *(int*)value;  else if(!strcasecmp(key, "mp3_quality"))    codec->quality = *(int*)value;  else if(!strcasecmp(key, "mp3_quality_vbr"))    codec->quality_vbr = *(int*)value;    return 0;  }static int flush(quicktime_t *file, int track)  {  int result = 0;  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;    if(codec->encode_initialized)    {    //    samples_left = lame_get_mf_samples_to_encode(codec->lame_global);        result = lame_encode_flush(codec->lame_global,                               codec->encoder_output + codec->encoder_output_size,                                codec->encoder_output_alloc);    /* Check if more frames arrived */    if(result > 0)      {      codec->encoder_output_size += result;      write_data(file, track, codec, codec->samples_read - codec->samples_written);      return 1;      }    }  return 0;  }void quicktime_init_codec_lame(quicktime_audio_map_t *atrack)  {  quicktime_mp3_codec_t *codec;    /* Init public items */  ((quicktime_codec_t*)atrack->codec)->priv = calloc(1, sizeof(quicktime_mp3_codec_t));  ((quicktime_codec_t*)atrack->codec)->delete_acodec = delete_codec;  //  ((quicktime_codec_t*)atrack->codec)->decode_audio = decode;  ((quicktime_codec_t*)atrack->codec)->encode_audio = encode;  ((quicktime_codec_t*)atrack->codec)->set_parameter = set_parameter;  ((quicktime_codec_t*)atrack->codec)->flush = flush;    codec = ((quicktime_codec_t*)atrack->codec)->priv;  codec->bitrate = 256000;  codec->quality = 0;  atrack->sample_format = LQT_SAMPLE_INT16;  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?