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