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

📄 vorbis.c

📁 这个库实现了录象功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************* vorbis.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 "qtvorbis.h"#define LQT_LIBQUICKTIME#include <quicktime/lqt_codecapi.h>#include <vorbis/vorbisenc.h>#include <stdlib.h>#include <string.h>#define LOG_DOMAIN "vorbis"typedef struct{/* Common stuff */        float ** sample_buffer;        int sample_buffer_alloc; /* Encoder stuff */        int max_bitrate;	int nominal_bitrate;	int min_bitrate;	int use_vbr;        int write_OVHS;        int encode_initialized;	ogg_stream_state enc_os;	ogg_page enc_og;        uint8_t * enc_header;        int enc_header_len;        int header_written;ogg_packet enc_op;	vorbis_info enc_vi;	vorbis_comment enc_vc;	vorbis_dsp_state enc_vd;	vorbis_block enc_vb;//        int64_t last_granulepos;// Number of samples written to disk	int encoded_samples;        int enc_samples_in_buffer;        int chunk_started;        quicktime_atom_t chunk_atom;/* Decoder stuff */	ogg_sync_state   dec_oy; /* sync and verify incoming physical bitstream */	ogg_stream_state dec_os; /* take physical pages, weld into a logical				stream of packets */	ogg_page         dec_og; /* one Ogg bitstream page.  Vorbis packets are inside */	ogg_packet       dec_op; /* one raw packet of data for decode */	vorbis_info      dec_vi; /* struct that stores all the static vorbis bitstream				settings */	vorbis_comment   dec_vc; /* struct that stores all the bitstream user comments */	vorbis_dsp_state dec_vd; /* central working state for the packet->PCM decoder */	vorbis_block     dec_vb; /* local working space for packet->PCM decode */	int decode_initialized;        int stream_initialized;    /* Buffer for the entire chunk */        uint8_t * chunk_buffer;        int chunk_buffer_alloc;        int bytes_in_chunk_buffer;  /* Start and end positions of the sample buffer */            int64_t sample_buffer_start;        int64_t sample_buffer_end;// Number of last sample relative to file	int64_t output_position;// Number of last sample relative to output buffer	long output_end;// Number of samples in output buffer	long output_size;// Number of samples allocated in output buffer	long output_allocated;// Current reading position in file	int64_t chunk;// Number of samples decoded in the current chunk	int chunk_samples;        int header_read;  } quicktime_vorbis_codec_t;/* =================================== public for vorbis */static int delete_codec(quicktime_audio_map_t *atrack)  {  quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;  int i;  if(codec->encode_initialized)    {    ogg_stream_clear(&codec->enc_os);    vorbis_block_clear(&codec->enc_vb);    vorbis_dsp_clear(&codec->enc_vd);    vorbis_comment_clear(&codec->enc_vc);    vorbis_info_clear(&codec->enc_vi);    }  if(codec->decode_initialized)    {    ogg_stream_clear(&codec->dec_os);    vorbis_block_clear(&codec->dec_vb);    vorbis_dsp_clear(&codec->dec_vd);    vorbis_comment_clear(&codec->dec_vc);    vorbis_info_clear(&codec->dec_vi);    }  if(codec->sample_buffer)     {    for(i = 0; i < atrack->channels; i++)      free(codec->sample_buffer[i]);    free(codec->sample_buffer);    }  if(codec->chunk_buffer)    free(codec->chunk_buffer);  if(codec->enc_header)    free(codec->enc_header);          free(codec);  return 0;  }static int next_chunk(quicktime_t * file, int track)  {  int i;  int num_packets;  int samples;  int chunk_size;  char * buffer;  uint8_t * header;  uint32_t header_len;  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  if(!codec->header_read) /* Try OVHS atom */    {    header = quicktime_wave_get_user_atom(track_map->track, "OVHS", &header_len);    if(header)      {      lqt_log(file, LQT_LOG_DEBUG, LOG_DOMAIN, "Using OVHS Atom, %d bytes", header_len-8);      buffer = ogg_sync_buffer(&codec->dec_oy, header_len-8);      memcpy(buffer, header + 8, header_len-8);      ogg_sync_wrote(&codec->dec_oy, header_len-8);      return 1;      }    }    if(lqt_audio_is_vbr(file, track))    {    num_packets = lqt_audio_num_vbr_packets(file, track, track_map->current_chunk, &samples);    if(!num_packets)      return 0;        for(i = 0; i < num_packets; i++)      {      chunk_size = lqt_audio_read_vbr_packet(file, track, track_map->current_chunk, i,                                             &(codec->chunk_buffer),                                             &(codec->chunk_buffer_alloc), &samples);      buffer = ogg_sync_buffer(&codec->dec_oy, chunk_size);      memcpy(buffer, codec->chunk_buffer, chunk_size);      ogg_sync_wrote(&codec->dec_oy, chunk_size);      }    }  else    {    chunk_size = lqt_read_audio_chunk(file,                                      track, track_map->current_chunk,                                      &(codec->chunk_buffer),                                      &(codec->chunk_buffer_alloc), (int*)0);    if(chunk_size <= 0)      {      return 0;      }        buffer = ogg_sync_buffer(&codec->dec_oy, chunk_size);    memcpy(buffer, codec->chunk_buffer, chunk_size);    ogg_sync_wrote(&codec->dec_oy, chunk_size);    }    track_map->current_chunk++;    return 1;  }static int next_page(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;  int result = 0;    while(result < 1)    {    result = ogg_sync_pageout(&codec->dec_oy, &codec->dec_og);    if(result == 0)      {      if(!next_chunk(file, track))        {        return 0;        }      }    else      {      if(!codec->stream_initialized)        {        ogg_stream_init(&codec->dec_os, ogg_page_serialno(&codec->dec_og));        codec->stream_initialized = 1;        }      ogg_stream_pagein(&codec->dec_os, &codec->dec_og);      }    }  return 1;  }static int next_packet(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;  int result = 0;  while(result < 1)    {    result = ogg_stream_packetout(&codec->dec_os, &codec->dec_op);        if(result == 0)      {      if(!next_page(file, track))        return 0;      }    }  return 1;  }static float ** alloc_sample_buffer(float ** old, int channels, int samples,                             int * sample_buffer_alloc)  {  int i;  if(!old)    {    old = calloc(channels, sizeof(*(old)));    }  if(*sample_buffer_alloc < samples)    {    *sample_buffer_alloc = samples + 256;    for(i = 0; i < channels; i++)      {      old[i] = realloc(old[i], (*sample_buffer_alloc) * sizeof(float));      }    }  return old;  }static int decode_frame(quicktime_t * file, int track)  {  int i;  float ** channels;  int samples_decoded = 0;  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  while(1)    {    samples_decoded = vorbis_synthesis_pcmout(&codec->dec_vd, &(channels));    if(samples_decoded > 0)      break;    /* Decode new data */    if(!next_packet(file, track))      {      return 0;      }    if(vorbis_synthesis(&codec->dec_vb, &codec->dec_op) == 0)      {      vorbis_synthesis_blockin(&codec->dec_vd,                               &codec->dec_vb);      }    }  codec->sample_buffer = alloc_sample_buffer(codec->sample_buffer,                                             file->atracks[track].channels,                                             codec->sample_buffer_end -                                             codec->sample_buffer_start + samples_decoded,                                             &(codec->sample_buffer_alloc));  for(i = 0; i < track_map->channels; i++)    {    memcpy(codec->sample_buffer[i] + (int)(codec->sample_buffer_end - codec->sample_buffer_start),           channels[i], samples_decoded * sizeof(float));    }  vorbis_synthesis_read(&codec->dec_vd, samples_decoded);  codec->sample_buffer_end += samples_decoded;  return 1;  }static int decode(quicktime_t *file,                   void * _output,                  long samples,                   int track)   {  int i, j;  int64_t chunk_sample; /* For seeking only */  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  //  int64_t total_samples;  int samples_decoded;  int samples_to_skip;  int samples_to_move;  int samples_copied;  float * output;  if(!_output) /* Global initialization */    {    return 0;    }    /* Initialize codec */  if(!codec->decode_initialized)    {    codec->decode_initialized = 1;    ogg_sync_init(&codec->dec_oy); /* Now we can read pages */    vorbis_info_init(&codec->dec_vi);    vorbis_comment_init(&codec->dec_vc);        if(!next_page(file, track))      {      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "decode: next page failed");      return 0;      }    if(!next_packet(file, track))      {      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "decode: next packet failed");      return 0;      }        if(vorbis_synthesis_headerin(&codec->dec_vi, &codec->dec_vc,                                 &codec->dec_op) < 0)      {      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN,              "decode: vorbis_synthesis_headerin: not a vorbis header");      return 0;      }    if(!next_packet(file, track))      {      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "decode: next packet failed");      return 0;      }    if(vorbis_synthesis_headerin(&codec->dec_vi, &codec->dec_vc, &codec->dec_op) < 0)      {      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN,              "decode: vorbis_synthesis_headerin: not a vorbis header");      return 0;      }    if(!next_packet(file, track))      return 0;    if(vorbis_synthesis_headerin(&codec->dec_vi, &codec->dec_vc, &codec->dec_op) < 0)      {      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN,              "decode: vorbis_synthesis_headerin: not a vorbis header");      return 0;      }    codec->header_read = 1;    vorbis_synthesis_init(&codec->dec_vd, &codec->dec_vi);    vorbis_block_init(&codec->dec_vd, &codec->dec_vb);    }  /* Check if we have to reposition the stream */    if(file->atracks[track].last_position != file->atracks[track].current_position)    {    /* Get the next chunk */    if(lqt_audio_is_vbr(file, track))      lqt_chunk_of_sample_vbr(&chunk_sample,                              &(track_map->current_chunk),

⌨️ 快捷键说明

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