ima4.c

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

C
593
字号
          codec->chunk_buffer_ptr = codec->chunk_buffer;          }                if(file->atracks[track].current_position != file->atracks[track].last_position)          {          /* Seeking happened */          quicktime_chunk_of_sample(&chunk_sample, &chunk,                                    file->atracks[track].track,                                    file->atracks[track].current_position);          /* Read the chunk */          if(file->atracks[track].current_chunk != chunk)            //          if(1)            {            file->atracks[track].current_chunk = chunk;            codec->chunk_buffer_size =              lqt_read_audio_chunk(file, track, file->atracks[track].current_chunk,                                   &(codec->chunk_buffer),                                   &(codec->chunk_buffer_alloc), &(codec->chunk_samples));            if(codec->chunk_buffer_size <= 0)              return 0;            codec->chunk_buffer_ptr = codec->chunk_buffer;            }          else            {            codec->chunk_buffer_size += (int)(codec->chunk_buffer_ptr - codec->chunk_buffer);            codec->chunk_buffer_ptr = codec->chunk_buffer;            }                    samples_to_skip = file->atracks[track].current_position - chunk_sample;          if(samples_to_skip < 0)            {            lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "Cannot skip backwards");            samples_to_skip = 0;            }                    /* Skip frames */          while(samples_to_skip > SAMPLES_PER_BLOCK)            {            codec->chunk_buffer_ptr += file->atracks[track].channels * BLOCK_SIZE;            codec->chunk_buffer_size -= file->atracks[track].channels * BLOCK_SIZE;            samples_to_skip -= SAMPLES_PER_BLOCK;            codec->chunk_samples -= SAMPLES_PER_BLOCK;            }          /* Decode frame */          for(i = 0; i < file->atracks[track].channels; i++)            {            ima4_decode_block(&(file->atracks[track]), codec->sample_buffer + i, codec->chunk_buffer_ptr, file->atracks[track].channels);            codec->chunk_buffer_ptr += BLOCK_SIZE;            codec->chunk_buffer_size -= BLOCK_SIZE;            }          codec->chunk_samples -= SAMPLES_PER_BLOCK;          /* Skip samples */                    codec->sample_buffer_size = SAMPLES_PER_BLOCK - samples_to_skip;          }                /* Decode until we are done */        samples_decoded = 0;        while(samples_decoded < samples)          {          /* Decode new frame if necessary */          if(!codec->sample_buffer_size)            {            /* Get new chunk if necessary */                        if(!codec->chunk_buffer_size)              {              file->atracks[track].current_chunk++;              codec->chunk_buffer_size =                lqt_read_audio_chunk(file, track, file->atracks[track].current_chunk,                                     &(codec->chunk_buffer),                                     &(codec->chunk_buffer_alloc), &(codec->chunk_samples));                            if(codec->chunk_buffer_size <= 0)                break;              codec->chunk_buffer_ptr = codec->chunk_buffer;              }                        /* Decode one frame */            for(i = 0; i < file->atracks[track].channels; i++)              {              ima4_decode_block(&(file->atracks[track]),                                codec->sample_buffer + i,                                codec->chunk_buffer_ptr, file->atracks[track].channels);              codec->chunk_buffer_ptr += BLOCK_SIZE;              codec->chunk_buffer_size -= BLOCK_SIZE;              }                        if(codec->chunk_samples < SAMPLES_PER_BLOCK)              codec->sample_buffer_size = codec->chunk_samples;            else              codec->sample_buffer_size = SAMPLES_PER_BLOCK;                        codec->chunk_samples -= SAMPLES_PER_BLOCK;            //            codec->sample_buffer_size = SAMPLES_PER_BLOCK;            }                    /* Copy samples */          samples_copied = samples - samples_decoded;          if(samples_copied > codec->sample_buffer_size)            samples_copied = codec->sample_buffer_size;          memcpy(output + file->atracks[track].channels * samples_decoded,                 codec->sample_buffer + file->atracks[track].channels * (SAMPLES_PER_BLOCK - codec->sample_buffer_size),                 samples_copied * 2 * file->atracks[track].channels);          samples_decoded += samples_copied;          codec->sample_buffer_size -= samples_copied;          }                file->atracks[track].last_position = file->atracks[track].current_position + samples_decoded;        return samples_decoded;}static int encode(quicktime_t *file, void *_input, long samples, int track)  {  int result = 0;  int64_t j;  int64_t chunk_bytes;  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  quicktime_trak_t *trak = track_map->track;  int16_t *input_ptr, *input;  unsigned char *output_ptr;  quicktime_atom_t chunk_atom;  int samples_encoded, total_samples_copied, samples_copied, frames_encoded, old_buffer_size;    /* Get output size */  chunk_bytes = ima4_samples_to_bytes(samples + codec->sample_buffer_size, track_map->channels);  if(codec->chunk_buffer_alloc < chunk_bytes)    {    /* Allocate space for one extra block */    codec->chunk_buffer_alloc = chunk_bytes + track_map->channels * BLOCK_SIZE;    codec->chunk_buffer = realloc(codec->chunk_buffer, codec->chunk_buffer_alloc);    }          if(!codec->last_samples)    codec->last_samples = calloc(track_map->channels, sizeof(*(codec->last_samples)));          if(!codec->last_indexes)    codec->last_indexes = calloc(track_map->channels, sizeof(*(codec->last_samples)));          if(!codec->sample_buffer)    {    codec->sample_buffer = malloc(sizeof(*(codec->sample_buffer)) * track_map->channels * SAMPLES_PER_BLOCK);    }          /* Encode from the input buffer to the read_buffer up to a multiple of  */  /* blocks. */  output_ptr = codec->chunk_buffer;  input = (int16_t*)_input;  input_ptr = input;  samples_encoded = 0;  frames_encoded = 0;  total_samples_copied = 0;    old_buffer_size = codec->sample_buffer_size;    while(samples_encoded < samples + old_buffer_size)    {    /* Copy input to sample buffer */    samples_copied = SAMPLES_PER_BLOCK - codec->sample_buffer_size;        if(samples_copied > samples - total_samples_copied)      samples_copied = samples - total_samples_copied;       memcpy(codec->sample_buffer + track_map->channels * codec->sample_buffer_size,           input_ptr,           samples_copied * track_map->channels * 2);    total_samples_copied += samples_copied;        input_ptr += samples_copied * track_map->channels;    codec->sample_buffer_size += samples_copied;    if(codec->sample_buffer_size == SAMPLES_PER_BLOCK)      {      for(j = 0; j < track_map->channels; j++)        {        ima4_encode_block(track_map, output_ptr, codec->sample_buffer + j,                          track_map->channels, j);        output_ptr += BLOCK_SIZE;        }      samples_encoded += SAMPLES_PER_BLOCK;      frames_encoded ++;      codec->sample_buffer_size = 0;      }    else      {      break;      }    }      /* Write to disk */          /* The block division may result in 0 samples getting encoded. */  /* Don't write 0 samples. */  if(samples_encoded)    {    quicktime_write_chunk_header(file, trak, &chunk_atom);    result = quicktime_write_data(file, codec->chunk_buffer, chunk_bytes);    quicktime_write_chunk_footer(file,                                  trak,                                 track_map->current_chunk,                                 &chunk_atom,                                  samples_encoded);    if(result)       result = 0;     else       result = 1; /* defeat fwrite's return */    track_map->current_chunk++;    }  return result;  }static int flush(quicktime_t *file, int track)  {  quicktime_atom_t chunk_atom;  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  quicktime_trak_t *trak = track_map->track;    int result = 0;  int i;  unsigned char *output_ptr;    if(codec->sample_buffer_size)    {    /* Zero out enough to get a block */    i = codec->sample_buffer_size * track_map->channels;    while(i < SAMPLES_PER_BLOCK * track_map->channels)      codec->sample_buffer[i++] = 0;    output_ptr = codec->chunk_buffer;    for(i = 0; i < track_map->channels; i++)      {      ima4_encode_block(track_map, output_ptr, codec->sample_buffer + i, track_map->channels, i);      output_ptr += BLOCK_SIZE;      }    quicktime_write_chunk_header(file, trak, &chunk_atom);    result = quicktime_write_data(file, codec->chunk_buffer, (int)(output_ptr - codec->chunk_buffer));    quicktime_write_chunk_footer(file,                                 trak,                                 track_map->current_chunk,                                 &chunk_atom,                                  codec->sample_buffer_size);    track_map->current_chunk++;    return 1;    }  return 0;  }void quicktime_init_codec_ima4(quicktime_audio_map_t *atrack){	quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;	quicktime_ima4_codec_t *codec;/* Set sample format */        atrack->sample_format = LQT_SAMPLE_INT16;                /* Init public items */	codec_base->priv = calloc(1, sizeof(quicktime_ima4_codec_t));	codec_base->delete_acodec = delete_codec;	codec_base->decode_video = 0;	codec_base->encode_video = 0;	codec_base->decode_audio = decode;	codec_base->encode_audio = encode;	codec_base->flush = flush;        //	codec_base->fourcc = QUICKTIME_IMA4;        //	codec_base->title = "IMA 4";        //	codec_base->desc = "IMA 4";        //	codec_base->wav_id = 0x11;/* Init private items */	codec = codec_base->priv;}

⌨️ 快捷键说明

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