yuv colorspace/range + prefs, ffmpeg colorrange probe, x11 direct force colormodel...
[goodguy/history.git] / cinelerra-5.1 / guicast / vframe.C
index fdd24ce02a35f85e8a6b46552961c9272a203057..eaa1f078cb826c063f27880296de0b507d4dfb90 100644 (file)
@@ -131,6 +131,7 @@ 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);
        copy_from(&frame);
@@ -139,6 +140,8 @@ VFrame::VFrame(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);
@@ -499,27 +502,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",
@@ -834,7 +840,7 @@ int VFrame::write_png(const char *path)
                        bc_cmodel = BC_RGBA8888;
                        png_cmodel = PNG_COLOR_TYPE_RGB_ALPHA;
                }
-               vframe = new VFrame(get_w(), get_h(), bc_cmodel, -1);
+               vframe = new VFrame(get_w(), get_h(), bc_cmodel, 0);
                vframe->transfer_from(this);
                break;
        }
@@ -1050,6 +1056,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;
@@ -1660,6 +1678,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);
@@ -1668,6 +1687,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));