⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vorbis.c

📁 这个库实现了录象功能
💻 C
📖 第 1 页 / 共 2 页
字号:
                              track_map->track,                              track_map->current_position);    else      quicktime_chunk_of_sample(&chunk_sample,                                &(track_map->current_chunk),                                track_map->track,                                track_map->current_position);          if(track_map->current_chunk >= file->atracks[track].track->mdia.minf.stbl.stco.total_entries)      {      return 0;      }                /* Reset everything */          vorbis_dsp_clear(&codec->dec_vd);    vorbis_block_clear(&codec->dec_vb);          ogg_stream_clear(&codec->dec_os);    ogg_sync_reset(&codec->dec_oy);    codec->stream_initialized = 0;    /* Initialize again */    ogg_sync_init(&codec->dec_oy);    // ogg_stream_init(&codec->dec_os, ogg_page_serialno(&codec->dec_og));    vorbis_synthesis_init(&codec->dec_vd, &codec->dec_vi);    vorbis_block_init(&codec->dec_vd, &codec->dec_vb);    if(!next_page(file, track))      return 0;          /* Reset sample buffer */          codec->sample_buffer_start = chunk_sample;    codec->sample_buffer_end   = chunk_sample;    /* Decode frames until we have enough */          while(track_map->current_position + samples > codec->sample_buffer_end)      {      if(!decode_frame(file, track))        break;      }    }    /* Flush unneeded samples */    if(track_map->current_position > codec->sample_buffer_start)    {    samples_to_skip = track_map->current_position - codec->sample_buffer_start;    samples_to_move = codec->sample_buffer_end - track_map->current_position;    if(samples_to_move > 0)      {      for(i = 0; i < track_map->channels; i++)        {        memmove(codec->sample_buffer[i],                &(codec->sample_buffer[i][samples_to_skip]),                samples_to_move * sizeof(float));        }      }    codec->sample_buffer_start = track_map->current_position;    if(samples_to_move > 0)      codec->sample_buffer_end = codec->sample_buffer_start + samples_to_move;    else      codec->sample_buffer_end = codec->sample_buffer_start;    }    /* Read new chunks until we have enough samples */  while(codec->sample_buffer_end < codec->sample_buffer_start + samples)    {    if(!decode_frame(file, track))      break;    }  samples_decoded = (codec->sample_buffer_end - codec->sample_buffer_start) < samples ?    (codec->sample_buffer_end - codec->sample_buffer_start) : samples;  samples_copied = samples;  if(samples_copied > samples_decoded)    samples_copied = samples_decoded;  output = (float*)_output;  for(i = 0; i < samples_copied; i++)    {    for(j = 0; j < track_map->channels; j++)      {      *(output++) = codec->sample_buffer[j][i];      }    }    file->atracks[track].last_position = file->atracks[track].current_position + samples_copied;    return samples_copied;  }/* Encoding part */#define ENCODE_SAMPLES 4096static int flush_header(quicktime_t * file, int track)  {  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  while(ogg_stream_flush(&codec->enc_os, &codec->enc_og))    {    codec->enc_header = realloc(codec->enc_header, codec->enc_header_len +                                codec->enc_og.header_len + codec->enc_og.body_len);        memcpy(codec->enc_header + codec->enc_header_len,           codec->enc_og.header, codec->enc_og.header_len);    memcpy(codec->enc_header + codec->enc_header_len + codec->enc_og.header_len,           codec->enc_og.body, codec->enc_og.body_len);        codec->enc_header_len += codec->enc_og.header_len + codec->enc_og.body_len;    }  if(codec->write_OVHS)    {    lqt_log(file, LQT_LOG_INFO, LOG_DOMAIN,            "Writing OVHS atom %d bytes\n", codec->enc_header_len);    quicktime_wave_set_user_atom(track_map->track, "OVHS",                                 codec->enc_header, codec->enc_header_len);        codec->header_written = 1;    }  return 0;  }static int flush_data(quicktime_t * file, int track)  {  int64_t new_encoded_samples;  int result = 0;  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_trak_t *trak = track_map->track;  quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;    while(vorbis_analysis_blockout(&codec->enc_vd, &codec->enc_vb) == 1)    {    /* While there is compressed data available... */        //    vorbis_analysis(&codec->enc_vb, &codec->enc_op);    vorbis_analysis(&codec->enc_vb, NULL);    //    vorbis_analysis(&codec->enc_vb, &codec->enc_op);    vorbis_bitrate_addblock(&codec->enc_vb);    while(vorbis_bitrate_flushpacket(&codec->enc_vd, &codec->enc_op))      {            /* While packets are available */      ogg_stream_packetin(&codec->enc_os, &codec->enc_op);            }    }  while(!result)    {    //        ogg_stream_flush(&codec->enc_os, &codec->enc_og);    //          break;    /* While pages are available */        if(!ogg_stream_flush(&codec->enc_os, &codec->enc_og))      break;    if(!codec->chunk_started)      {      codec->chunk_started = 1;      lqt_start_audio_vbr_chunk(file, track);      quicktime_write_chunk_header(file, trak, &codec->chunk_atom);      }    lqt_start_audio_vbr_frame(file, track);    if(!codec->header_written)      {      codec->header_written = 1;      result = !quicktime_write_data(file, codec->enc_header, codec->enc_header_len);      }        result = !quicktime_write_data(file, codec->enc_og.header, codec->enc_og.header_len);    if(!result)      {      result = !quicktime_write_data(file, codec->enc_og.body, codec->enc_og.body_len);      }    new_encoded_samples = codec->enc_os.granulepos;    lqt_finish_audio_vbr_frame(file, track, new_encoded_samples - codec->encoded_samples);    codec->encoded_samples = new_encoded_samples;            if(ogg_page_eos(&codec->enc_og)) break;    }  return result;  }static void flush_audio(quicktime_t * file, int track)  {  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;    float ** output;  int i;  output = vorbis_analysis_buffer(&codec->enc_vd, codec->enc_samples_in_buffer);  for(i = 0; i < track_map->channels; i++)    {    memcpy(output[i], codec->sample_buffer[i], sizeof(float) * codec->enc_samples_in_buffer);    }  vorbis_analysis_wrote(&codec->enc_vd, codec->enc_samples_in_buffer);  codec->enc_samples_in_buffer = 0;  flush_data(file, track);  }static int encode(quicktime_t *file,                   void *_input,                  long samples,                  int track)  {  int i, j;  int samples_copied, samples_to_copy;  int result = 0;  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_trak_t *trak = track_map->track;  quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  int samplerate = track_map->samplerate;  float * input;    if(!codec->encode_initialized)    {    ogg_packet header;    ogg_packet header_comm;    ogg_packet header_code;     codec->encode_initialized = 1;    lqt_init_vbr_audio(file, track);    if(file->file_type == LQT_FILE_AVI)      trak->mdia.minf.stbl.stsd.table[0].sample_size = 0;    vorbis_info_init(&codec->enc_vi);    if(codec->use_vbr)      {      result = vorbis_encode_setup_managed(&codec->enc_vi,                                           track_map->channels,                                            samplerate,                                            codec->max_bitrate,                                            codec->nominal_bitrate,                                            codec->min_bitrate);      result |= vorbis_encode_ctl(&codec->enc_vi, OV_ECTL_RATEMANAGE_AVG, NULL);      result |= vorbis_encode_setup_init(&codec->enc_vi);      }    else      {      vorbis_encode_init(&codec->enc_vi,                         track_map->channels,                         samplerate,                          codec->max_bitrate,                          codec->nominal_bitrate,                          codec->min_bitrate);      }    vorbis_comment_init(&codec->enc_vc);    vorbis_analysis_init(&codec->enc_vd, &codec->enc_vi);    vorbis_block_init(&codec->enc_vd, &codec->enc_vb);    //    	srand(time(NULL));    ogg_stream_init(&codec->enc_os, rand());    vorbis_analysis_headerout(&codec->enc_vd,                               &codec->enc_vc,                              &header,                              &header_comm,                              &header_code);    ogg_stream_packetin(&codec->enc_os, &header);     ogg_stream_packetin(&codec->enc_os, &header_comm);    ogg_stream_packetin(&codec->enc_os, &header_code);    //        FLUSH_OGG1    flush_header(file, track);    codec->sample_buffer = alloc_sample_buffer(codec->sample_buffer, track_map->channels,                                               ENCODE_SAMPLES,                                               &codec->sample_buffer_alloc);    }          samples_copied = 0;  while(samples_copied < samples)    {    samples_to_copy = samples - samples_copied;    if(samples_to_copy > ENCODE_SAMPLES - codec->enc_samples_in_buffer)      samples_to_copy = ENCODE_SAMPLES - codec->enc_samples_in_buffer;    input = ((float*)_input + samples_copied * track_map->channels);        for(j = 0; j < samples_to_copy; j++)      {      for(i = 0; i < track_map->channels; i++)        codec->sample_buffer[i][codec->enc_samples_in_buffer + j] = *(input++);            }    samples_copied += samples_to_copy;    codec->enc_samples_in_buffer += samples_to_copy;        if(codec->enc_samples_in_buffer >= ENCODE_SAMPLES)      flush_audio(file, track);    }      result = 0;  // Wrote a chunk.  if(codec->chunk_started)    {    quicktime_write_chunk_footer(file,                                  trak,                                 track_map->current_chunk,                                 &codec->chunk_atom,                                  track_map->vbr_num_frames);    track_map->current_chunk++;    codec->chunk_started = 0;    }  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_vorbis_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;	if(!strcasecmp(key, "vorbis_vbr"))		codec->use_vbr = *(int*)value;	else	if(!strcasecmp(key, "vorbis_bitrate"))		codec->nominal_bitrate = *(int*)value;	else	if(!strcasecmp(key, "vorbis_max_bitrate"))		codec->max_bitrate = *(int*)value;	else	if(!strcasecmp(key, "vorbis_min_bitrate"))		codec->min_bitrate = *(int*)value;        return 0;}static int flush(quicktime_t *file, int track){	quicktime_audio_map_t *track_map = &(file->atracks[track]);	quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;	quicktime_trak_t *trak = track_map->track;        flush_audio(file, track);	vorbis_analysis_wrote(&codec->enc_vd,0);        flush_data(file, track);                //	FLUSH_OGG2		if(codec->chunk_started)	{                quicktime_write_chunk_footer(file,                                              trak,                                             track_map->current_chunk,                                             &codec->chunk_atom,                                              track_map->vbr_num_frames);		track_map->current_chunk++;                codec->chunk_started = 0;                return 1;	}        return 0;}void quicktime_init_codec_vorbis(quicktime_audio_map_t *atrack){	quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;	quicktime_vorbis_codec_t *codec;	char *compressor = atrack->track->mdia.minf.stbl.stsd.table[0].format;/* Init public items */	codec_base->priv = calloc(1, sizeof(quicktime_vorbis_codec_t));	codec_base->delete_acodec = delete_codec;	codec_base->decode_audio = decode;	codec_base->encode_audio = encode;	codec_base->set_parameter = set_parameter;	codec_base->flush = flush;        	codec = codec_base->priv;	codec->nominal_bitrate = 128000;	codec->max_bitrate = -1;	codec->min_bitrate = -1;        atrack->sample_format = LQT_SAMPLE_FLOAT;        if(quicktime_match_32(compressor, "OggV"))          {          codec->write_OVHS = 1;          }        /* Set Vorbis 5.1 channel mapping */        if(atrack->channels == 6)          {          if(!atrack->channel_setup)            {            atrack->channel_setup = calloc(6, sizeof(*atrack->channel_setup));            atrack->channel_setup[0] =  LQT_CHANNEL_FRONT_LEFT;            atrack->channel_setup[1] =  LQT_CHANNEL_FRONT_CENTER;            atrack->channel_setup[2] =  LQT_CHANNEL_FRONT_RIGHT;            atrack->channel_setup[3] =  LQT_CHANNEL_LFE;            atrack->channel_setup[4] =  LQT_CHANNEL_BACK_LEFT;            atrack->channel_setup[5] =  LQT_CHANNEL_BACK_RIGHT;            }          }}

⌨️ 快捷键说明

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