long quicktime_read_frame(quicktime_t *file, unsigned char *video_buffer, int track) { long bytes; int result = 0; quicktime_trak_t *trak = file->vtracks[track].track; bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track); if(!file->vtracks[track].frames_cached) { quicktime_set_video_position(file, file->vtracks[track].current_position, track); result = quicktime_read_data(file, video_buffer, bytes); } else { int i; unsigned char *cached_frame; if(file->vtracks[track].current_position >= file->vtracks[track].frames_cached) result = 1; if(!result) { cached_frame = file->vtracks[track].frame_cache[file->vtracks[track].current_position]; for(i = 0; i < bytes; i++) video_buffer[i] = cached_frame[i]; } } file->vtracks[track].current_position++; if(!result) return 0; return bytes; }
static int decode(quicktime_t *file, unsigned char **row_pointers, int track) { int bytes; quicktime_video_map_t *vtrack = &(file->vtracks[track]); quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv; int width = quicktime_video_width(file, track); int height = quicktime_video_height(file, track); int result = 0; initialize(vtrack, codec, width, height); quicktime_set_video_position(file, vtrack->current_position, track); bytes = quicktime_frame_size(file, vtrack->current_position, track); result = !quicktime_read_data(file, (char*)codec->work_buffer, bytes); if(codec->is_2vuy) convert_decode_2vuy(codec); else convert_decode_yuv2(codec); cmodel_transfer(row_pointers, codec->rows, row_pointers[0], row_pointers[1], row_pointers[2], 0, 0, 0, file->in_x, file->in_y, file->in_w, file->in_h, 0, 0, file->out_w, file->out_h, BC_YUV422, file->color_model, 0, codec->coded_w, file->out_w); return result; }
static int decode(quicktime_t *file, unsigned char **row_pointers, int track) { int i; int64_t bytes; int result = 0; quicktime_video_map_t *vtrack = &(file->vtracks[track]); quicktime_v308_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv; int width = vtrack->track->tkhd.track_width; int height = vtrack->track->tkhd.track_height; unsigned char **input_rows; if(!codec->work_buffer) codec->work_buffer = malloc(vtrack->track->tkhd.track_width * vtrack->track->tkhd.track_height * 3); quicktime_set_video_position(file, vtrack->current_position, track); bytes = quicktime_frame_size(file, vtrack->current_position, track); result = !quicktime_read_data(file, codec->work_buffer, bytes); input_rows = malloc(sizeof(unsigned char*) * height); for(i = 0; i < height; i++) input_rows[i] = codec->work_buffer + i * width * 3; cmodel_transfer(row_pointers, input_rows, row_pointers[0], row_pointers[1], row_pointers[2], 0, 0, 0, file->in_x, file->in_y, file->in_w, file->in_h, 0, 0, file->out_w, file->out_h, BC_VYU888, file->color_model, 0, width, file->out_w); free(input_rows); return result; }
long quicktime_read_frame(quicktime_t *file, unsigned char *video_buffer, int track) { int64_t bytes; int result = 0; quicktime_trak_t *trak = file->vtracks[track].track; bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track); quicktime_set_video_position(file, file->vtracks[track].current_position, track); result = quicktime_read_data(file, video_buffer, bytes); file->vtracks[track].current_position++; if(!result) return 0; return bytes; }
long quicktime_read_frame(quicktime_t *file, unsigned char *video_buffer, int track) { int result = 0; int64_t bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track); quicktime_set_video_position(file, file->vtracks[track].current_position, track); /* * printf("quicktime_read_frame 0x%llx %lld\n", * quicktime_ftell(file), * bytes); */ result = quicktime_read_data(file, (char*)video_buffer, bytes); file->vtracks[track].current_position++; if(!result) return 0; return bytes; }
/* * read_frame for video - this will try to read the next frame */ void CQTVideoByteStream::read_frame (uint32_t frame_to_read) { uint32_t next_frame_size; if (m_frame_in_buffer == frame_to_read) { #ifdef DEBUG_QTIME_VIDEO_FRAME player_debug_message("frame in buffer %u %u", m_byte_on, m_this_frame_size); #endif m_byte_on = 0; return; } // Haven't already read the next frame, so - get the size, see if // it fits, then read it into the appropriate buffer m_parent->lock_file_mutex(); next_frame_size = quicktime_frame_size(m_parent->get_file(), frame_to_read, m_track); if (next_frame_size > m_max_frame_size) { m_max_frame_size = next_frame_size + 4; m_buffer = (uint8_t *)realloc(m_buffer, (next_frame_size + 4) * sizeof(char)); } m_this_frame_size = next_frame_size; quicktime_set_video_position(m_parent->get_file(), frame_to_read, m_track); m_frame_in_buffer = frame_to_read; #ifdef DEBUG_QTIME_VIDEO_FRAME player_debug_message("reading into buffer %u", m_this_frame_size); #endif quicktime_read_frame(m_parent->get_file(), (unsigned char *)m_buffer, m_track); #ifdef DEBUG_QTIME_VIDEO_FRAME player_debug_message("Buffer %d %02x %02x %02x %02x", frame_to_read, m_buffer[0], m_buffer[1], m_buffer[2], m_buffer[3]); #endif m_parent->unlock_file_mutex(); m_byte_on = 0; }
int main(int argc, char *argv[]) { quicktime_t *file; FILE *output; int result = 0; int i, j; int64_t length; char string[1024], *prefix = 0, *input = 0; char *data = 0; int bytes = 0, old_bytes = 0; float output_rate = 0; float input_rate; int64_t input_frame; int64_t new_length; int width, height; int rgb_to_ppm = 0; if(argc < 3) { usage(); } for(i = 1, j = 0; i < argc; i++) { if(!strcmp(argv[i], "-f")) { if(i + 1 < argc) { output_rate = atof(argv[++i]); } else usage(); } else if(j == 0) { input = argv[i]; j++; } else if(j == 1) { prefix = argv[i]; j++; } } if(!prefix || !input) usage(); if(!(file = quicktime_open(input, 1, 0))) { printf("Open failed\n"); exit(1); } if(!quicktime_video_tracks(file)) { printf("No video tracks.\n"); exit(1); } if(quicktime_match_32(quicktime_video_compressor(file, 0), QUICKTIME_RAW)) { printf("Converting to ppm.\n"); rgb_to_ppm = 1; } length = quicktime_video_length(file, 0); input_rate = quicktime_frame_rate(file, 0); if(!output_rate) output_rate = input_rate; new_length = output_rate / input_rate * length; width = quicktime_video_width(file, 0); height = quicktime_video_height(file, 0); for(i = 0; i < new_length; i++) { /* Get output file */ sprintf(string, "%s%06d", prefix, i); if(!(output = fopen(string, "wb"))) { perror("Open failed"); exit(1); } /* Get input frame */ input_frame = (int64_t)(input_rate / output_rate * i); bytes = quicktime_frame_size(file, input_frame, 0); if(data) { if(bytes > old_bytes) { free(data); data = 0; } } if(!data) { old_bytes = bytes; data = malloc(bytes); } quicktime_set_video_position(file, input_frame, 0); quicktime_read_data(file, data, bytes); if(rgb_to_ppm) { fprintf(output, "P6\n%d %d\n%d\n", width, height, 0xff); } if(!fwrite(data, bytes, 1, output)) { perror("write failed"); } fclose(output); } quicktime_close(file); }
static int decode(quicktime_t *file, unsigned char **row_pointers, int track) { long bytes; quicktime_video_map_t *vtrack = &(file->vtracks[track]); quicktime_dv_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv; int width = vtrack->track->tkhd.track_width; int height = vtrack->track->tkhd.track_height; int result = 0; int i; int decode_colormodel = 0; int pitches[3] = { 720 * 2, 0, 0 }; quicktime_set_video_position(file, vtrack->current_position, track); bytes = quicktime_frame_size(file, vtrack->current_position, track); result = !quicktime_read_data(file, (char*)codec->data, bytes); if( codec->dv_decoder && codec->parameters_changed ) { dv_decoder_free( codec->dv_decoder ); codec->dv_decoder = NULL; codec->parameters_changed = 0; } if( ! codec->dv_decoder ) { pthread_mutex_lock( &libdv_init_mutex ); codec->dv_decoder = dv_decoder_new( codec->add_ntsc_setup, codec->clamp_luma, codec->clamp_chroma ); codec->dv_decoder->prev_frame_decoded = 0; codec->parameters_changed = 0; pthread_mutex_unlock( &libdv_init_mutex ); } if(codec->dv_decoder) { int is_sequential = check_sequentiality( row_pointers, 720 * cmodel_calculate_pixelsize(file->color_model), file->out_h ); codec->dv_decoder->quality = codec->decode_quality; dv_parse_header( codec->dv_decoder, codec->data ); // Libdv improperly decodes RGB colormodels. if((file->color_model == BC_YUV422 || file->color_model == BC_RGB888) && file->in_x == 0 && file->in_y == 0 && file->in_w == width && file->in_h == height && file->out_w == width && file->out_h == height && is_sequential) { if( file->color_model == BC_YUV422 ) { pitches[0] = 720 * 2; dv_decode_full_frame( codec->dv_decoder, codec->data, e_dv_color_yuv, row_pointers, pitches ); } else if( file->color_model == BC_RGB888) { pitches[0] = 720 * 3; dv_decode_full_frame( codec->dv_decoder, codec->data, e_dv_color_rgb, row_pointers, pitches ); } } else { 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; } decode_colormodel = BC_YUV422; pitches[0] = 720 * 2; dv_decode_full_frame( codec->dv_decoder, codec->data, e_dv_color_yuv, codec->temp_rows, pitches ); cmodel_transfer(row_pointers, codec->temp_rows, row_pointers[0], row_pointers[1], row_pointers[2], codec->temp_rows[0], codec->temp_rows[1], codec->temp_rows[2], file->in_x, file->in_y, file->in_w, file->in_h, 0, 0, file->out_w, file->out_h, decode_colormodel, file->color_model, 0, width, file->out_w); } } //printf(__FUNCTION__ " 2\n"); return result; }
static int decode(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_t *mjpeg = codec->mjpeg; long size, field2_offset = 0; int track_height = trak->tkhd.track_height; int track_width = trak->tkhd.track_width; int result = 0; int field_dominance = trak->mdia.minf.stbl.stsd.table[0].field_dominance; mjpeg_set_cpus(codec->mjpeg, file->cpus); if(file->row_span) mjpeg_set_rowspan(codec->mjpeg, file->row_span); else mjpeg_set_rowspan(codec->mjpeg, 0); quicktime_set_video_position(file, vtrack->current_position, track); size = quicktime_frame_size(file, vtrack->current_position, track); codec->buffer_size = size; if(size > codec->buffer_allocated) { codec->buffer_allocated = size; codec->buffer = realloc(codec->buffer, codec->buffer_allocated); } result = !quicktime_read_data(file, (char*)codec->buffer, size); /* * printf("decode 1 %02x %02x %02x %02x %02x %02x %02x %02x\n", * codec->buffer[0], * codec->buffer[1], * codec->buffer[2], * codec->buffer[3], * codec->buffer[4], * codec->buffer[5], * codec->buffer[6], * codec->buffer[7] * ); */ if(!result) { if(mjpeg_get_fields(mjpeg) == 2) { if(file->use_avi) { field2_offset = mjpeg_get_avi_field2(codec->buffer, size, &field_dominance); } else { field2_offset = mjpeg_get_quicktime_field2(codec->buffer, size); // Sanity check if(!field2_offset) { printf("decode: FYI field2_offset=0\n"); field2_offset = mjpeg_get_field2(codec->buffer, size); } } } else field2_offset = 0; //printf("decode 2 %d\n", field2_offset); /* * printf("decode result=%d field1=%llx field2=%llx size=%d %02x %02x %02x %02x\n", * result, * quicktime_position(file) - size, * quicktime_position(file) - size + field2_offset, * size, * codec->buffer[0], * codec->buffer[1], * codec->buffer[field2_offset + 0], * codec->buffer[field2_offset + 1]); */ if(file->in_x == 0 && file->in_y == 0 && file->in_w == track_width && file->in_h == track_height && file->out_w == track_width && file->out_h == track_height) { mjpeg_decompress(codec->mjpeg, codec->buffer, size, field2_offset, row_pointers, row_pointers[0], row_pointers[1], row_pointers[2], file->color_model, file->cpus); } else { int i; unsigned char **temp_rows; int temp_cmodel = BC_YUV888; int temp_rowsize = cmodel_calculate_pixelsize(temp_cmodel) * track_width; if(!codec->temp_video) codec->temp_video = malloc(temp_rowsize * track_height); temp_rows = malloc(sizeof(unsigned char*) * track_height); for(i = 0; i < track_height; i++) temp_rows[i] = codec->temp_video + i * temp_rowsize; //printf("decode 10\n"); mjpeg_decompress(codec->mjpeg, codec->buffer, size, field2_offset, temp_rows, temp_rows[0], temp_rows[1], temp_rows[2], temp_cmodel, file->cpus); cmodel_transfer(row_pointers, temp_rows, row_pointers[0], row_pointers[1], row_pointers[2], temp_rows[0], temp_rows[1], temp_rows[2], file->in_x, file->in_y, file->in_w, file->in_h, 0, 0, file->out_w, file->out_h, temp_cmodel, file->color_model, 0, track_width, file->out_w); //printf("decode 30\n"); free(temp_rows); //printf("decode 40\n"); } } //printf("decode 2 %d\n", result); return result; }