X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fvframe.C;h=041887702435f4028f605bf07ebdfbb1720fb610;hp=aadd6a721dc540205f1fb018bc6727219d51bd47;hb=c279e21fc2394a7908bbd1ba8c79b116fe9fb14a;hpb=624f99bd6dccb2af28fdbef8fbb3ae41c19fcbd2 diff --git a/cinelerra-5.1/guicast/vframe.C b/cinelerra-5.1/guicast/vframe.C index aadd6a72..04188770 100644 --- a/cinelerra-5.1/guicast/vframe.C +++ b/cinelerra-5.1/guicast/vframe.C @@ -127,20 +127,22 @@ VFrame *VFramePng::vframe_png(const char *png_path, double xs, double ys) return vframe; } - VFrame::VFrame(VFrame &frame) { reset_parameters(1); params = new BC_Hash; + use_shm = frame.use_shm; allocate_data(0, -1, 0, 0, 0, frame.w, frame.h, frame.color_model, frame.bytes_per_line); - memcpy(data, frame.data, bytes_per_line * h); - copy_stacks(&frame); + copy_vframe(&frame); } + VFrame::VFrame(int w, int h, int color_model, long bytes_per_line) { reset_parameters(1); +// use bytes_per_line == 0 to allocate default unshared + if( !bytes_per_line ) { bytes_per_line = -1; use_shm = 0; } params = new BC_Hash; allocate_data(data, -1, 0, 0, 0, w, h, color_model, bytes_per_line); @@ -278,7 +280,8 @@ int VFrame::reset_parameters(int do_opengl) timestamp = -1.; is_keyframe = 0; draw_point = 0; - set_pixel_color(BLACK); + pixel_rgb = 0x000000; // BLACK + pixel_yuv = 0x008080; stipple = 0; if(do_opengl) @@ -306,6 +309,11 @@ int VFrame::clear_objects(int do_opengl) pbuffer = 0; } +#ifdef LEAKER +if( memory_type != VFrame::SHARED ) + printf("==del %p from %p\n", data, __builtin_return_address(0)); +#endif + // Delete data switch(memory_type) { @@ -347,6 +355,7 @@ int VFrame::clear_objects(int do_opengl) case BC_YUV444P: case BC_RGB_FLOATP: case BC_RGBA_FLOATP: + case BC_GBRP: break; default: @@ -438,6 +447,12 @@ void VFrame::create_row_pointers() this->u_offset = sz; this->v_offset = sz + sz; break; + case BC_GBRP: + if( this->v_offset ) break; + this->y_offset = 0; + this->u_offset = sz * sizeof(uint8_t); + this->v_offset = 2 * sz * sizeof(uint8_t); + break; case BC_RGBA_FLOATP: if( this->v_offset || a ) break; a = this->data + 3 * sz * sizeof(float); @@ -496,27 +511,30 @@ int VFrame::allocate_data(unsigned char *data, int shmid, } else { memory_type = VFrame::PRIVATE; + this->data = 0; int size = calculate_data_size(this->w, this->h, this->bytes_per_line, this->color_model); - if(BC_WindowBase::get_resources()->use_vframe_shm() && use_shm) { + if( use_shm && size >= SHM_MIN_SIZE && + BC_WindowBase::get_resources()->use_vframe_shm() ) { this->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777); - if(this->shmid < 0) { - printf("VFrame::allocate_data %d could not allocate shared memory\n", __LINE__); - } - - this->data = (unsigned char*)shmat(this->shmid, NULL, 0); -//printf("VFrame::allocate_data %d %d %d\n", __LINE__, size, this->shmid); - -//printf("VFrame::allocate_data %d %p\n", __LINE__, this->data); + if( this->shmid >= 0 ) { + this->data = (unsigned char*)shmat(this->shmid, NULL, 0); +//printf("VFrame::allocate_data %d %d %d %p\n", __LINE__, size, this->shmid, this->data); // This causes it to automatically delete when the program exits. - shmctl(this->shmid, IPC_RMID, 0); + shmctl(this->shmid, IPC_RMID, 0); + } + else { + printf("VFrame::allocate_data %d could not allocate" + " shared memory, %dx%d (model %d) size=0x%08x\n", + __LINE__, w, h, color_model, size); + BC_Trace::dump_shm_stats(stdout); + } } - else { // Have to use malloc for libpng -//printf("==vframe %d from %p\n", size, __builtin_return_address(0)); + if( !this->data ) { this->data = (unsigned char *)malloc(size); + this->shmid = -1; } - // Memory check // if(this->w * this->h > 1500 * 1100) // printf("VFrame::allocate_data 2 this=%p w=%d h=%d this->data=%p\n", @@ -524,6 +542,9 @@ int VFrame::allocate_data(unsigned char *data, int shmid, if(!this->data) printf("VFrame::allocate_data %dx%d: memory exhausted.\n", this->w, this->h); +#ifdef LEAKER +printf("==new %p from %p sz %d\n", this->data, __builtin_return_address(0), size); +#endif //printf("VFrame::allocate_data %d %p data=%p %d %d\n", __LINE__, this, this->data, this->w, this->h); //if(size > 1000000) printf("VFrame::allocate_data %d\n", size); @@ -807,49 +828,41 @@ int VFramePng::read_png(const unsigned char *data, long sz, double xscale, doubl int VFrame::write_png(const char *path) { + VFrame *vframe = this; png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); png_infop info_ptr = png_create_info_struct(png_ptr); FILE *out_fd = fopen(path, "w"); - if(!out_fd) - { + if(!out_fd) { printf("VFrame::write_png %d %s %s\n", __LINE__, path, strerror(errno)); return 1; } int png_cmodel = PNG_COLOR_TYPE_RGB; - switch(get_color_model()) - { - case BC_RGB888: - case BC_YUV888: - png_cmodel = PNG_COLOR_TYPE_RGB; - break; - - case BC_RGBA8888: - case BC_YUVA8888: + int bc_cmodel = get_color_model(); + switch( bc_cmodel ) { + case BC_RGB888: break; + case BC_RGBA8888: png_cmodel = PNG_COLOR_TYPE_RGB_ALPHA; break; + case BC_A8: png_cmodel = PNG_COLOR_TYPE_GRAY; break; + default: + bc_cmodel = BC_RGB888; + if( BC_CModels::has_alpha(bc_cmodel) ) { + bc_cmodel = BC_RGBA8888; png_cmodel = PNG_COLOR_TYPE_RGB_ALPHA; - break; - - case BC_A8: - png_cmodel = PNG_COLOR_TYPE_GRAY; - break; + } + vframe = new VFrame(get_w(), get_h(), bc_cmodel, 0); + vframe->transfer_from(this); + break; } - png_init_io(png_ptr, out_fd); png_set_compression_level(png_ptr, 9); - png_set_IHDR(png_ptr, - info_ptr, - get_w(), - get_h(), - 8, - png_cmodel, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); + png_set_IHDR(png_ptr, info_ptr, get_w(), get_h(), 8, png_cmodel, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); - png_write_image(png_ptr, get_rows()); + png_write_image(png_ptr, vframe->get_rows()); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(out_fd); + if( vframe != this ) delete vframe; return 0; } @@ -879,27 +892,33 @@ int VFrame::clear_frame() case BC_YUV410P: bzero(get_y(), sz); - bzero(get_u(), w / 4 * h / 4); - bzero(get_v(), w / 4 * h / 4); + memset(get_u(), 0x80, w / 4 * h / 4); + memset(get_v(), 0x80, w / 4 * h / 4); break; case BC_YUV411P: case BC_YUV420P: case BC_YUV420PI: bzero(get_y(), sz); - bzero(get_u(), sz / 4); - bzero(get_v(), sz / 4); + memset(get_u(), 0x80, sz / 4); + memset(get_v(), 0x80, sz / 4); break; case BC_YUV422P: bzero(get_y(), sz); - bzero(get_u(), sz / 2); - bzero(get_v(), sz / 2); + memset(get_u(), 0x80, sz / 2); + memset(get_v(), 0x80, sz / 2); + break; + + case BC_GBRP: + bzero(get_y(), sz); + bzero(get_u(), sz); + bzero(get_b(), sz); break; case BC_RGBA_FLOATP: if( a ) { float *ap = (float *)a; - for( int i=sz; --i>=0; ++ap ) *ap = 1.f; } + for( int i=sz; --i>=0; ++ap ) *ap = 0.f; } case BC_RGB_FLOATP: { float *rp = (float *)y; for( int i=sz; --i>=0; ++rp ) *rp = 0.f; @@ -910,8 +929,8 @@ int VFrame::clear_frame() break; } case BC_YUV444P: bzero(get_y(), sz); - bzero(get_u(), sz); - bzero(get_v(), sz); + memset(get_u(), 0x80, sz); + memset(get_v(), 0x80, sz); break; case BC_YUV888: @@ -940,12 +959,9 @@ int VFrame::clear_frame() void VFrame::rotate90() { // Allocate new frame - int new_w = h, new_h = w, new_bytes_per_line = bytes_per_pixel * new_w; - unsigned char *new_data = new unsigned char[calculate_data_size(new_w, new_h, new_bytes_per_line, color_model)]; - unsigned char **new_rows = new unsigned char*[new_h]; - for(int i = 0; i < new_h; i++) - new_rows[i] = &new_data[new_bytes_per_line * i]; - + int new_w = h, new_h = w; + VFrame new_frame(new_w, new_h, color_model); + unsigned char **new_rows = new_frame.get_rows(); // Copy data for(int in_y = 0, out_x = new_w - 1; in_y < h; in_y++, out_x--) { @@ -960,23 +976,34 @@ void VFrame::rotate90() } // Swap frames - clear_objects(0); +// swap memory + unsigned char *new_data = new_frame.data; + new_frame.data = data; data = new_data; +// swap rows + new_rows = new_frame.rows; + new_frame.rows = rows; rows = new_rows; - bytes_per_line = new_bytes_per_line; - w = new_w; - h = new_h; +// swap shmid + int new_shmid = new_frame.shmid; + new_frame.shmid = shmid; + shmid = new_shmid; +// swap bytes_per_line + int new_bpl = new_frame.bytes_per_line; + new_frame.bytes_per_line = bytes_per_line; + bytes_per_line = new_bpl; + new_frame.clear_objects(0); + + w = new_frame.w; + h = new_frame.h; } void VFrame::rotate270() { // Allocate new frame - int new_w = h, new_h = w, new_bytes_per_line = bytes_per_pixel * new_w; - unsigned char *new_data = new unsigned char[calculate_data_size(new_w, new_h, new_bytes_per_line, color_model)]; - unsigned char **new_rows = new unsigned char*[new_h]; - for(int i = 0; i < new_h; i++) - new_rows[i] = &new_data[new_bytes_per_line * i]; - + int new_w = h, new_h = w; + VFrame new_frame(new_w, new_h, color_model); + unsigned char **new_rows = new_frame.get_rows(); // Copy data for(int in_y = 0, out_x = 0; in_y < h; in_y++, out_x++) { @@ -991,24 +1018,36 @@ void VFrame::rotate270() } // Swap frames - clear_objects(0); +// swap memory + unsigned char *new_data = new_frame.data; + new_frame.data = data; data = new_data; +// swap rows + new_rows = new_frame.rows; + new_frame.rows = rows; rows = new_rows; - bytes_per_line = new_bytes_per_line; - w = new_w; - h = new_h; +// swap shmid + int new_shmid = new_frame.shmid; + new_frame.shmid = shmid; + shmid = new_shmid; +// swap bytes_per_line + int new_bpl = new_frame.bytes_per_line; + new_frame.bytes_per_line = bytes_per_line; + bytes_per_line = new_bpl; + new_frame.clear_objects(0); + + w = new_frame.w; + h = new_frame.h; } void VFrame::flip_vert() { - unsigned char *temp = new unsigned char[bytes_per_line]; - for(int i = 0, j = h - 1; i < j; i++, j--) - { + unsigned char temp[bytes_per_line]; + for( int i=0, j=h; --j>i; ++i ) { memcpy(temp, rows[j], bytes_per_line); memcpy(rows[j], rows[i], bytes_per_line); memcpy(rows[i], temp, bytes_per_line); } - delete [] temp; } void VFrame::flip_horiz() @@ -1030,6 +1069,18 @@ void VFrame::flip_horiz() int VFrame::copy_from(VFrame *frame) { + if(this->w != frame->get_w() || + this->h != frame->get_h()) + { + printf("VFrame::copy_from %d sizes differ src %dx%d != dst %dx%d\n", + __LINE__, + frame->get_w(), + frame->get_h(), + get_w(), + get_h()); + return 1; + } + int w = MIN(this->w, frame->get_w()); int h = MIN(this->h, frame->get_h()); timestamp = frame->timestamp; @@ -1085,12 +1136,14 @@ int VFrame::copy_from(VFrame *frame) int VFrame::transfer_from(VFrame *that, int bg_color, int in_x, int in_y, int in_w, int in_h) { + timestamp = that->timestamp; + copy_params(that); + if( this->get_color_model() == that->get_color_model() && this->get_w() == that->get_w() && this->get_h() == that->get_h() && this->get_bytes_per_line() == that->get_bytes_per_line() ) return this->copy_from(that); - timestamp = that->timestamp; #if 0 BC_CModels::transfer( this->get_rows(), that->get_rows(), // Packed data out/in @@ -1229,22 +1282,20 @@ void VFrame::copy_stacks(VFrame *src) { clear_stacks(); - for(int i = 0; i < src->next_effects.total; i++) - { - char *ptr; - next_effects.append(ptr = new char[strlen(src->next_effects.values[i]) + 1]); - strcpy(ptr, src->next_effects.values[i]); - } - for(int i = 0; i < src->prev_effects.total; i++) - { - char *ptr; - prev_effects.append(ptr = new char[strlen(src->prev_effects.values[i]) + 1]); - strcpy(ptr, src->prev_effects.values[i]); - } + for( int i=0; i < src->next_effects.total; ++i ) + next_effects.append(cstrdup(src->next_effects[i])); + for( int i=0; i < src->prev_effects.total; ++i ) + prev_effects.append(cstrdup(src->prev_effects[i])); copy_params(src); } +int VFrame::copy_vframe(VFrame *frame) +{ + copy_stacks(frame); + return copy_from(frame); +} + int VFrame::equal_stacks(VFrame *src) { for(int i = 0; i < src->next_effects.total && i < next_effects.total; i++) @@ -1297,7 +1348,7 @@ void VFrame::set_pixel_color(int rgb) int ir = 0xff & (pixel_rgb >> 16); int ig = 0xff & (pixel_rgb >> 8); int ib = 0xff & (pixel_rgb >> 0); - bc_rgb2yuv(ir,ig,ib, ir,ig,ib); + YUV::yuv.rgb_to_yuv_8(ir, ig, ib); pixel_yuv = (ir<<16) | (ig<<8) | (ib<<0); } @@ -1638,6 +1689,7 @@ void VFrame::smooth_draw(int x1, int y1, int x2, int y2, int x3, int y3) } } + void VFrame::draw_rect(int x1, int y1, int x2, int y2) { draw_line(x1, y1, x2, y1); @@ -1646,6 +1698,52 @@ void VFrame::draw_rect(int x1, int y1, int x2, int y2) draw_line(x1, y2 - 1, x1, y1 + 1); } + +void VFrame::draw_oval(int x1, int y1, int x2, int y2) +{ + int w = x2 - x1; + int h = y2 - y1; + int center_x = (x2 + x1) / 2; + int center_y = (y2 + y1) / 2; + int x_table[h / 2]; + +//printf("VFrame::draw_oval %d %d %d %d %d\n", __LINE__, x1, y1, x2, y2); + + for(int i = 0; i < h / 2; i++) { +// A^2 = -(B^2) + C^2 + x_table[i] = (int)(sqrt(-SQR(h / 2 - i) + SQR(h / 2)) * w / h); +//printf("VFrame::draw_oval %d i=%d x=%d\n", __LINE__, i, x_table[i]); + } + + for(int i = 0; i < h / 2 - 1; i++) { + int x3 = x_table[i]; + int x4 = x_table[i + 1]; + + if(x4 > x3 + 1) { + for(int j = x3; j < x4; j++) { + draw_pixel(center_x + j, y1 + i); + draw_pixel(center_x - j, y1 + i); + draw_pixel(center_x + j, y2 - i - 1); + draw_pixel(center_x - j, y2 - i - 1); + } + } + else { + draw_pixel(center_x + x3, y1 + i); + draw_pixel(center_x - x3, y1 + i); + draw_pixel(center_x + x3, y2 - i - 1); + draw_pixel(center_x - x3, y2 - i - 1); + } + } + + draw_pixel(center_x, y1); + draw_pixel(center_x, y2 - 1); + draw_pixel(x1, center_y); + draw_pixel(x2 - 1, center_y); + draw_pixel(x1, center_y - 1); + draw_pixel(x2 - 1, center_y - 1); +} + + void VFrame::draw_arrow(int x1, int y1, int x2, int y2, int sz) { double angle = atan((float)(y2 - y1) / (float)(x2 - x1));