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; }
static int encode(quicktime_t *file, unsigned char **row_pointers, int track) { int bytes; quicktime_video_map_t *vtrack = &(file->vtracks[track]); quicktime_trak_t *trak = vtrack->track; quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv; int result = 1; int width = vtrack->track->tkhd.track_width; int height = vtrack->track->tkhd.track_height; quicktime_atom_t chunk_atom; initialize(vtrack, codec, width, height); bytes = height * codec->bytes_per_line; cmodel_transfer(codec->rows, row_pointers, 0, 0, 0, row_pointers[0], row_pointers[1], row_pointers[2], 0, 0, width, height, 0, 0, width, height, file->color_model, BC_YUV422, 0, width, codec->coded_w); if( codec->is_2vuy ) convert_encode_2vuy(codec); else convert_encode_yuv2(codec); quicktime_write_chunk_header(file, trak, &chunk_atom); result = !quicktime_write_data(file, (char*)codec->work_buffer, bytes); quicktime_write_chunk_footer(file, trak, vtrack->current_chunk, &chunk_atom, 1); vtrack->current_chunk++; return result; }
static int encode(quicktime_t *file, unsigned char **row_pointers, int track) { int64_t offset = quicktime_position(file); quicktime_video_map_t *vtrack = &(file->vtracks[track]); quicktime_v308_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv; quicktime_trak_t *trak = vtrack->track; int width = vtrack->track->tkhd.track_width; int height = vtrack->track->tkhd.track_height; int bytes = width * height * 3; int result = 0; unsigned char **output_rows; int i; quicktime_atom_t chunk_atom; if(!codec->work_buffer) codec->work_buffer = malloc(vtrack->track->tkhd.track_width * vtrack->track->tkhd.track_height * 3); output_rows = malloc(sizeof(unsigned char*) * height); for(i = 0; i < height; i++) output_rows[i] = codec->work_buffer + i * width * 3; cmodel_transfer(output_rows, row_pointers, 0, 0, 0, row_pointers[0], row_pointers[1], row_pointers[2], 0, 0, width, height, 0, 0, width, height, file->color_model, BC_VYU888, 0, width, width); quicktime_write_chunk_header(file, trak, &chunk_atom); result = !quicktime_write_data(file, codec->work_buffer, bytes); quicktime_write_chunk_footer(file, trak, vtrack->current_chunk, &chunk_atom, 1); vtrack->current_chunk++; free(output_rows); return result; }
static int encode(quicktime_t *file, unsigned char **row_pointers, int track) { quicktime_video_map_t *vtrack = &(file->vtracks[track]); initialize(vtrack); quicktime_jpeg_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv; quicktime_trak_t *trak = vtrack->track; mjpeg_set_quality(codec->mjpeg, codec->quality); mjpeg_set_float(codec->mjpeg, codec->use_float); //int64_t offset = quicktime_position(file); int result = 0; long field2_offset; quicktime_atom_t chunk_atom; //printf("encode 1\n"); mjpeg_set_cpus(codec->mjpeg, file->cpus); mjpeg_compress(codec->mjpeg, row_pointers, row_pointers[0], row_pointers[1], row_pointers[2], file->color_model, file->cpus); if(codec->jpeg_type == JPEG_MJPA) { if(file->use_avi) { mjpeg_insert_avi_markers(&codec->mjpeg->output_data, &codec->mjpeg->output_size, &codec->mjpeg->output_allocated, 2, &field2_offset); } else { mjpeg_insert_quicktime_markers(&codec->mjpeg->output_data, &codec->mjpeg->output_size, &codec->mjpeg->output_allocated, 2, &field2_offset); } } quicktime_write_chunk_header(file, trak, &chunk_atom); result = !quicktime_write_data(file, (char*)mjpeg_output_buffer(codec->mjpeg), mjpeg_output_size(codec->mjpeg)); quicktime_write_chunk_footer(file, trak, vtrack->current_chunk, &chunk_atom, 1); vtrack->current_chunk++; //printf("encode 100\n"); return result; }
int quicktime_write_frame(quicktime_t *file, unsigned char *video_buffer, int64_t bytes, int track) { int64_t offset = quicktime_position(file); int result = 0; quicktime_atom_t chunk_atom; quicktime_video_map_t *vtrack = &file->vtracks[track]; quicktime_trak_t *trak = vtrack->track; quicktime_write_chunk_header(file, trak, &chunk_atom); result = !quicktime_write_data(file, video_buffer, bytes); quicktime_write_chunk_footer(file, trak, vtrack->current_chunk, &chunk_atom, 1); file->vtracks[track].current_position++; file->vtracks[track].current_chunk++; return result; }
static int encode(quicktime_t *file, int16_t **input_i, float **input_f, int track, long samples) { int result = 0; int64_t i, j, step; int64_t chunk_bytes; int64_t overflow_start; int64_t chunk_samples; /* Samples in the current chunk to be written */ 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; unsigned char *output_ptr; quicktime_atom_t chunk_atom; /* Get buffer sizes */ if(codec->work_buffer && codec->work_size < (samples + codec->work_overflow + 1) * track_map->channels) { /* Create new buffer */ int64_t new_size = (samples + codec->work_overflow + 1) * track_map->channels; int16_t *new_buffer = malloc(sizeof(int16_t) * new_size); /* Copy overflow */ for(i = 0; i < codec->work_overflow * track_map->channels; i++) new_buffer[i] = codec->work_buffer[i]; /* Swap pointers. */ free(codec->work_buffer); codec->work_buffer = new_buffer; codec->work_size = new_size; } else if(!codec->work_buffer) { /* No buffer in the first place. */ codec->work_size = (samples + codec->work_overflow) * track_map->channels; /* Make the allocation enough for at least the flush routine. */ if(codec->work_size < SAMPLES_PER_BLOCK * track_map->channels) codec->work_size = SAMPLES_PER_BLOCK * track_map->channels; codec->work_buffer = malloc(sizeof(int16_t) * codec->work_size); } /* Get output size */ chunk_bytes = ima4_samples_to_bytes(samples + codec->work_overflow, track_map->channels); if(codec->read_buffer && codec->read_size < chunk_bytes) { free(codec->read_buffer); codec->read_buffer = 0; } if(!codec->read_buffer) { codec->read_buffer = malloc(chunk_bytes); codec->read_size = chunk_bytes; } if(!codec->last_samples) { codec->last_samples = malloc(sizeof(int) * track_map->channels); for(i = 0; i < track_map->channels; i++) { codec->last_samples[i] = 0; } } if(!codec->last_indexes) { codec->last_indexes = malloc(sizeof(int) * track_map->channels); for(i = 0; i < track_map->channels; i++) { codec->last_indexes[i] = 0; } } /* Arm the input buffer after the last overflow */ step = track_map->channels; for(j = 0; j < track_map->channels; j++) { input_ptr = codec->work_buffer + codec->work_overflow * track_map->channels + j; if(input_i) { for(i = 0; i < samples; i++) { *input_ptr = input_i[j][i]; input_ptr += step; } } else if(input_f) { for(i = 0; i < samples; i++) { *input_ptr = (int16_t)(input_f[j][i] * 32767); input_ptr += step; } } } /* Encode from the input buffer to the read_buffer up to a multiple of */ /* blocks. */ input_ptr = codec->work_buffer; output_ptr = codec->read_buffer; for(i = 0; i + SAMPLES_PER_BLOCK <= samples + codec->work_overflow; i += SAMPLES_PER_BLOCK) { for(j = 0; j < track_map->channels; j++) { ima4_encode_block(track_map, output_ptr, input_ptr + j, track_map->channels, j); output_ptr += BLOCK_SIZE; } input_ptr += SAMPLES_PER_BLOCK * track_map->channels; } /* Write to disk */ chunk_samples = (int64_t)((samples + codec->work_overflow) / SAMPLES_PER_BLOCK) * SAMPLES_PER_BLOCK; /*printf("quicktime_encode_ima4 1 %ld\n", chunk_samples); */ /* The block division may result in 0 samples getting encoded. */ /* Don't write 0 samples. */ if(chunk_samples) { quicktime_write_chunk_header(file, trak, &chunk_atom); result = quicktime_write_data(file, (char*)codec->read_buffer, chunk_bytes); quicktime_write_chunk_footer(file, trak, track_map->current_chunk, &chunk_atom, chunk_samples); if(result) result = 0; else result = 1; /* defeat fwrite's return */ track_map->current_chunk++; } /* Move the last overflow to the front */ overflow_start = i; input_ptr = codec->work_buffer; for(i = overflow_start * track_map->channels ; i < (samples + codec->work_overflow) * track_map->channels; i++) { *input_ptr++ = codec->work_buffer[i]; } codec->work_overflow = samples + codec->work_overflow - overflow_start; return result; }
static int encode(quicktime_t *file, unsigned char **row_pointers, int track) { //int64_t offset = quicktime_position(file); quicktime_video_map_t *vtrack = &(file->vtracks[track]); quicktime_dv_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv; quicktime_trak_t *trak = vtrack->track; int width = trak->tkhd.track_width; int height = trak->tkhd.track_height; int width_i = 720; int height_i = (height <= 480) ? 480 : 576; int i; unsigned char **input_rows; int is_pal = (height_i == 480) ? 0 : 1; int data_length = is_pal ? DV_PAL_SIZE : DV_NTSC_SIZE; int result = 0; dv_color_space_t encode_dv_colormodel = 0; quicktime_atom_t chunk_atom; if( codec->dv_encoder != NULL && codec->parameters_changed ) { dv_encoder_free( codec->dv_encoder ); codec->dv_encoder = NULL; codec->parameters_changed = 0; } if( ! codec->dv_encoder ) { pthread_mutex_lock( &libdv_init_mutex ); //printf( "dv.c encode: Alloc'ing encoder\n" ); codec->dv_encoder = dv_encoder_new( codec->rem_ntsc_setup, codec->clamp_luma, codec->clamp_chroma ); codec->parameters_changed = 0; pthread_mutex_unlock( &libdv_init_mutex ); } if(codec->dv_encoder) { int is_sequential = check_sequentiality( row_pointers, width_i * cmodel_calculate_pixelsize(file->color_model), height ); if( ( file->color_model == BC_YUV422 || file->color_model == BC_RGB888 ) && width == width_i && height == height_i && is_sequential ) { input_rows = row_pointers; switch( file->color_model ) { case BC_YUV422: encode_dv_colormodel = e_dv_color_yuv; //printf( "dv.c encode: e_dv_color_yuv\n" ); break; case BC_RGB888: encode_dv_colormodel = e_dv_color_rgb; //printf( "dv.c encode: e_dv_color_rgb\n" ); break; default: return 0; break; } } else { // The best colormodel for encoding is YUV 422 if(!codec->temp_frame) { codec->temp_frame = malloc(720 * 576 * 2); codec->temp_rows = malloc(sizeof(unsigned char*) * 576); for(i = 0; i < 576; i++) codec->temp_rows[i] = codec->temp_frame + 720 * 2 * i; } cmodel_transfer(codec->temp_rows, /* Leave NULL if non existent */ row_pointers, codec->temp_rows[0], /* Leave NULL if non existent */ codec->temp_rows[1], codec->temp_rows[2], row_pointers[0], /* Leave NULL if non existent */ row_pointers[1], row_pointers[2], 0, /* Dimensions to capture from input frame */ 0, MIN(width, width_i), MIN(height, height_i), 0, /* Dimensions to project on output frame */ 0, MIN(width, width_i), MIN(height, height_i), file->color_model, BC_YUV422, 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */ width, /* For planar use the luma rowspan */ width_i); input_rows = codec->temp_rows; encode_dv_colormodel = e_dv_color_yuv; } // Setup the encoder codec->dv_encoder->is16x9 = codec->anamorphic16x9; codec->dv_encoder->vlc_encode_passes = codec->vlc_encode_passes; codec->dv_encoder->static_qno = 0; codec->dv_encoder->force_dct = DV_DCT_AUTO; codec->dv_encoder->isPAL = is_pal; //printf("dv.c encode: 1 %d %d %d\n", width_i, height_i, encode_dv_colormodel); dv_encode_full_frame( codec->dv_encoder, input_rows, encode_dv_colormodel, codec->data ); //printf("dv.c encode: 2 %d %d\n", width_i, height_i); quicktime_write_chunk_header(file, trak, &chunk_atom); result = !quicktime_write_data(file, (char*)codec->data, data_length); quicktime_write_chunk_footer(file, trak, vtrack->current_chunk, &chunk_atom, 1); vtrack->current_chunk++; //printf("encode 3\n"); } return result; }