static int encode(quicktime_t *file, int16_t **input_i, float **input_f, int track, long samples) { int result = 0; long i, j, offset; quicktime_audio_map_t *track_map = &(file->atracks[track]); quicktime_sowt_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv; int step = track_map->channels * quicktime_audio_bits(file, track) / 8; int sample; float sample_f; get_work_buffer(file, track, samples * step); if(input_i) { for(i = 0; i < track_map->channels; i++) { switch(quicktime_audio_bits(file, track)) { case 8: for(j = 0; j < samples; j++) { sample = input_i[i][j] >> 8; codec->work_buffer[j * step + i] = sample; } break; case 16: for(j = 0; j < samples; j++) { sample = input_i[i][j]; codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8; codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff; } break; case 24: for(j = 0; j < samples; j++) { sample = input_i[i][j]; codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff00) >> 8; codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff); codec->work_buffer[j * step + i * 3 + 2] = 0; } break; } } } else { for(i = 0; i < track_map->channels; i++)
int quicktime_write_audio(quicktime_t *file, char *audio_buffer, long samples, int track) { int result; int64_t bytes; quicktime_atom_t chunk_atom; quicktime_audio_map_t *track_map = &file->atracks[track]; quicktime_trak_t *trak = track_map->track; /* write chunk for 1 track */ bytes = samples * quicktime_audio_bits(file, track) / 8 * file->atracks[track].channels; quicktime_write_chunk_header(file, trak, &chunk_atom); result = !quicktime_write_data(file, audio_buffer, bytes); quicktime_write_chunk_footer(file, trak, track_map->current_chunk, &chunk_atom, samples); /* file->atracks[track].current_position += samples; */ file->atracks[track].current_chunk++; return result; }
int quicktime_write_audio(quicktime_t *file, char *audio_buffer, long samples, int track) { long offset; int result; long bytes; /* Defeat 32 bit file size limit. */ if(quicktime_test_position(file)) return 1; /* write chunk for 1 track */ bytes = samples * quicktime_audio_bits(file, track) / 8 * file->atracks[track].channels; offset = quicktime_position(file); result = quicktime_write_data(file, audio_buffer, bytes); if(result) result = 0; else result = 1; /* defeat fwrite's return */ quicktime_update_tables(file, file->atracks[track].track, offset, file->atracks[track].current_chunk, file->atracks[track].current_position, samples, 0, 0, 0, 0); file->atracks[track].current_position += samples; file->atracks[track].current_chunk++; return result; }
static int quicktime_decode_rawaudio(quicktime_t *file, int16_t *output_i, float *output_f, long samples, int track, int channel) { int i, result; int little_endian = is_little_endian(); quicktime_audio_map_t *track_map = &(file->atracks[track]); quicktime_rawaudio_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv; int bits = quicktime_audio_bits(file, track); int byts = bits/8, channels = file->atracks[track].channels; int size = channels * byts; get_work_buffer(file, track, samples * size); result = !quicktime_read_audio(file, codec->work_buffer, samples, track); if( result ) return result; // Undo increment since this is done in codecs.c track_map->current_position -= samples; if( !little_endian ) { if( output_i ) { switch( byts ) { case 1: rd_samples(int16_t,rd8be_s16,output_i,size); break; case 2: rd_samples(int16_t,rd16be_s16,output_i,size); break; case 3: rd_samples(int16_t,rd24be_s16,output_i,size); break; } } else if( output_f ) { switch( byts ) { case 1: rd_samples(float,rd8be_flt,output_f,size); break; case 2: rd_samples(float,rd16be_flt,output_f,size); break; case 3: rd_samples(float,rd24be_flt,output_f,size); break; } } } else { // Undo increment since this is done in codecs.c track_map->current_position -= samples; if( output_i ) { switch( byts ) { case 1: rd_samples(int16_t,rd8le_s16,output_i,size); break; case 2: rd_samples(int16_t,rd16le_s16,output_i,size); break; case 3: rd_samples(int16_t,rd24le_s16,output_i,size); break; } } else if( output_f ) { switch( byts ) { case 1: rd_samples(float,rd8le_flt,output_f,size); break; case 2: rd_samples(float,rd16le_flt,output_f,size); break; case 3: rd_samples(float,rd24le_flt,output_f,size); break; } } } /*printf("quicktime_decode_rawaudio 2\n"); */ return 0; }
static int quicktime_encode_rawaudio(quicktime_t *file, int16_t **input_i, float **input_f, int track, long samples) { int i, j, result; int little_endian = is_little_endian(); quicktime_audio_map_t *track_map = &(file->atracks[track]); quicktime_rawaudio_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv; int bits = quicktime_audio_bits(file, track); int byts = bits/8, channels = file->atracks[track].channels; int size = channels * byts; get_work_buffer(file, track, samples * size); if( !little_endian ) { if( input_i ) { switch( byts ) { case 1: wr_samples(int16_t,wr8be_s16,input_i,size); break; case 2: wr_samples(int16_t,wr16be_s16,input_i,size); break; case 3: wr_samples(int16_t,wr24be_s16,input_i,size); break; } } else if( input_f ) { switch( byts ) { case 1: wr_samples(float,wr8be_flt,input_f,size); break; case 2: wr_samples(float,wr16be_flt,input_f,size); break; case 3: wr_samples(float,wr24be_flt,input_f,size); break; } } } else { if( input_i ) { switch( byts ) { case 1: wr_samples(int16_t,wr8le_s16,input_i,size); break; case 2: wr_samples(int16_t,wr16le_s16,input_i,size); break; case 3: wr_samples(int16_t,wr24le_s16,input_i,size); break; } } else if( input_f ) { switch( byts ) { case 1: wr_samples(float,wr8le_flt,input_f,size); break; case 2: wr_samples(float,wr16le_flt,input_f,size); break; case 3: wr_samples(float,wr24le_flt,input_f,size); break; } } } result = quicktime_write_audio(file, (char *)codec->work_buffer, samples, track); return result; }
static int decode(quicktime_t *file, int16_t *output_i, float *output_f, long samples, int track, int channel) { int result = 0; long i, j; quicktime_audio_map_t *track_map = &(file->atracks[track]); quicktime_sowt_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv; int step = track_map->channels * quicktime_audio_bits(file, track) / 8; get_work_buffer(file, track, samples * step); /* * printf("decode 1 %d\n", quicktime_audio_bits(file, track)); * sleep(1); */ result = !quicktime_read_audio(file, codec->work_buffer, samples, track); /* Undo increment since this is done in codecs.c */ track_map->current_position -= samples; /* Handle AVI byte order */ if(!file->use_avi) swap_bytes(codec->work_buffer, samples, track_map->channels, quicktime_audio_bits(file, track)); switch(quicktime_audio_bits(file, track)) { case 8: if(output_i && !result) { for(i = 0, j = channel; i < samples; i++) { output_i[i] = ((int16_t)codec->work_buffer[j]) << 8; j += step; } } else if(output_f && !result) { for(i = 0, j = channel; i < samples; i++) { output_f[i] = ((float)codec->work_buffer[j]) / 0x7f; j += step; } } break; case 16: if(output_i && !result) { for(i = 0, j = channel * 2; i < samples; i++) { output_i[i] = ((int16_t)codec->work_buffer[j]) << 8 | ((unsigned char)codec->work_buffer[j + 1]); j += step; } } else if(output_f && !result) { for(i = 0, j = channel * 2; i < samples; i++) { output_f[i] = (float)((((int16_t)codec->work_buffer[j]) << 8) | ((unsigned char)codec->work_buffer[j + 1])) / 0x7fff; j += step; } } break; case 24: if(output_i && !result) { for(i = 0, j = channel * 3; i < samples; i++) { output_i[i] = (((int16_t)codec->work_buffer[j]) << 8) | ((unsigned char)codec->work_buffer[j + 1]); j += step; } } else if(output_f && !result) { for(i = 0, j = channel * 3; i < samples; i++) { output_f[i] = (float)((((int)codec->work_buffer[j]) << 16) | (((unsigned char)codec->work_buffer[j + 1]) << 8) | ((unsigned char)codec->work_buffer[j + 2])) / 0x7fffff; j += step; } } break; default: break; } return result; }
void decode_mov(decode_t *decode) { quicktime_t *qt_handle=NULL; unsigned char **p_raw_buffer; char *p_v_codec=NULL,*p_a_codec=NULL,*p_buffer=NULL,*p_tmp=NULL; int s_width=0,s_height=0,s_channel=0,s_bits=0,s_buff_size=0,s_audio_size=0,s_video_size=0,s_sample=0; int s_cont,s_frames; double s_fps=0; long s_audio_rate,s_qt_pos; uint16_t *p_mask1, *p_mask2; char msgbuf[TC_BUF_MIN]; qt_handle = quicktime_open((char * )decode->name, 1, 0); if (qt_handle == NULL) { QT_ABORT("can't open quicktime!"); } quicktime_set_preload(qt_handle, 10240000); s_fps = quicktime_frame_rate(qt_handle, 0); if (decode->format == TC_CODEC_PCM) { if (quicktime_audio_tracks(qt_handle) == 0) { QT_ABORT("no audio track in quicktime found!"); } s_channel = quicktime_track_channels(qt_handle, 0); s_audio_rate = quicktime_sample_rate(qt_handle, 0); s_bits = quicktime_audio_bits(qt_handle, 0); s_audio_size = quicktime_audio_length(qt_handle,0); p_a_codec = quicktime_audio_compressor(qt_handle, 0); if (decode->frame_limit[1] < s_audio_size) { s_audio_size = decode->frame_limit[1] - decode->frame_limit[0]; } else { s_audio_size -= decode->frame_limit[0]; } if (decode->verbose) { tc_log_info(__FILE__, "Audio codec=%s, rate=%ld Hz, bits=%d, channels=%d", p_a_codec, s_audio_rate, s_bits, s_channel); } if ((s_bits != 8) && (s_bits != 16)) { tc_snprintf(msgbuf, sizeof(msgbuf), "unsupported %d bit rate" " in quicktime!", s_bits); QT_ABORT(msgbuf); } if (s_channel > 2) { tc_snprintf(msgbuf, sizeof(msgbuf), "too many audio tracks " "(%d) found in quicktime!", s_channel); QT_ABORT(msgbuf); } if (strlen(p_a_codec) == 0) { QT_ABORT("unsupported codec (empty!) in quicktime!"); } if (quicktime_supported_audio(qt_handle, 0) != 0) { s_qt_pos = quicktime_audio_position(qt_handle,0); s_sample = (1.00 * s_channel * s_bits *s_audio_rate)/(s_fps * 8); s_buff_size = s_sample * sizeof(uint16_t); p_buffer = tc_malloc(s_buff_size); if (s_bits == 16) s_sample /= 2; if (s_channel == 1) { p_mask1=(uint16_t *)p_buffer; quicktime_set_audio_position(qt_handle, s_qt_pos + decode->frame_limit[0], 0); for (; s_audio_size > 0; s_audio_size -= s_sample) { if (quicktime_decode_audio(qt_handle, p_mask1, NULL, s_sample, 0) < 0) { QT_ABORT("error reading quicktime audio frame"); } QT_WRITE(decode->fd_out, p_buffer, s_buff_size); } } else { s_sample /= 2; p_mask1 = (uint16_t *)p_buffer; p_mask2 = tc_malloc(s_sample * sizeof(uint16_t)); s_qt_pos += decode->frame_limit[0]; quicktime_set_audio_position(qt_handle, s_qt_pos, 0); for (; s_audio_size > 0; s_audio_size -= s_sample) { if (quicktime_decode_audio(qt_handle, p_mask1, NULL, s_sample, 0) < 0) { QT_ABORT("error reading quicktime audio frame"); } quicktime_set_audio_position(qt_handle, s_qt_pos, 0); if (quicktime_decode_audio(qt_handle,p_mask2, NULL,s_sample, 1) < 0) { QT_ABORT("error reading quicktime audio frame"); } for (s_cont = s_sample - 1; s_cont >= 0; s_cont--) p_mask1[s_cont<<1] = p_mask1[s_cont]; for (s_cont = 0; s_cont < s_sample; s_cont++) p_mask1[1+(s_cont<<1)] = p_mask2[s_cont]; s_qt_pos += s_sample; QT_WRITE(decode->fd_out, p_buffer, s_buff_size >> 1); } free(p_mask2); } free(p_buffer); } #if !defined(LIBQUICKTIME_000904) else if ((strcasecmp(p_a_codec, QUICKTIME_RAW) == 0)
void probe_mov(info_t *ipipe) { quicktime_t *qt_file=NULL; char *codec=NULL; int j, tracks; /* open movie for video probe */ if(qt_file==NULL) if(NULL == (qt_file = quicktime_open((char *)ipipe->name,1,0))){ tc_log_error(__FILE__,"can't open quicktime!"); ipipe->error=1; return; } // extract audio parameters tracks=quicktime_audio_tracks(qt_file); if(tracks>TC_MAX_AUD_TRACKS) { tc_log_warn(__FILE__, "only %d of %d audio tracks scanned", TC_MAX_AUD_TRACKS, tracks); tracks=TC_MAX_AUD_TRACKS; } for(j=0; j<tracks; ++j) { ipipe->probe_info->track[j].samplerate = quicktime_sample_rate(qt_file, j); ipipe->probe_info->track[j].chan = quicktime_track_channels(qt_file, j); ipipe->probe_info->track[j].bits = quicktime_audio_bits(qt_file, j); codec = quicktime_audio_compressor(qt_file, j); if(strcasecmp(codec,QUICKTIME_RAW)==0 || strcasecmp(codec,QUICKTIME_TWOS)==0) ipipe->probe_info->track[j].format = CODEC_PCM; else if(strcasecmp(codec,QUICKTIME_IMA4)==0) ipipe->probe_info->track[j].format = CODEC_IMA4; else /* XXX not right but works */ ipipe->probe_info->track[j].format = CODEC_PCM; if (! binary_dump) tc_log_info(__FILE__, "audio codec=%s", codec); if(ipipe->probe_info->track[j].chan>0) ++ipipe->probe_info->num_tracks; } // read all video parameter from input file ipipe->probe_info->width = quicktime_video_width(qt_file, 0); ipipe->probe_info->height = quicktime_video_height(qt_file, 0); ipipe->probe_info->fps = quicktime_frame_rate(qt_file, 0); ipipe->probe_info->frames = quicktime_video_length(qt_file, 0); codec = quicktime_video_compressor(qt_file, 0); //check for supported codecs if(codec!=NULL) { if(strlen(codec)==0) { ipipe->probe_info->codec=TC_CODEC_RGB; } else { if(strcasecmp(codec,QUICKTIME_DV)==0) ipipe->probe_info->codec=TC_CODEC_DV; if(strcasecmp(codec,"dvsd")==0) ipipe->probe_info->codec=TC_CODEC_DV; if(strcasecmp(codec,"DIV3")==0) ipipe->probe_info->codec=TC_CODEC_DIVX3; if(strcasecmp(codec,"DIVX")==0) ipipe->probe_info->codec=TC_CODEC_DIVX4; if(strcasecmp(codec,"DX50")==0) ipipe->probe_info->codec=TC_CODEC_DIVX5; if(strcasecmp(codec,"MJPG")==0 || strcasecmp(codec,"JPEG")==0) ipipe->probe_info->codec=TC_CODEC_MJPEG; if(strcasecmp(codec,"YUV2")==0) ipipe->probe_info->codec=TC_CODEC_YUV2; if(strcasecmp(codec,"SVQ1")==0) ipipe->probe_info->codec=TC_CODEC_SVQ1; if(strcasecmp(codec,"SVQ3")==0) ipipe->probe_info->codec=TC_CODEC_SVQ3; } } else ipipe->probe_info->codec=TC_CODEC_UNKNOWN; if (! binary_dump) tc_log_info(__FILE__, "video codec=%s", codec); ipipe->probe_info->magic=TC_MAGIC_MOV; tc_frc_code_from_value(&(ipipe->probe_info->frc), ipipe->probe_info->fps); return; }