From 425f9eab2f37d52e16e7ebdcd4b78f6de7ed68e7 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Thu, 20 Aug 2015 15:54:56 -0600 Subject: [PATCH] fixed for v4l2 captures, add colormodel uyuv --- cinelerra-5.0/cinelerra/cwindowgui.C | 6 ++--- cinelerra-5.0/cinelerra/devicev4l2base.C | 9 +++++--- cinelerra-5.0/cinelerra/edit.C | 20 ++++++++--------- cinelerra-5.0/cinelerra/resourcepixmap.C | 4 ++-- cinelerra-5.0/cinelerra/vdevicev4l2.C | 13 ++++++++--- cinelerra-5.0/cinelerra/videodevice.C | 1 - cinelerra-5.0/guicast/bcbitmap.C | 5 +++-- cinelerra-5.0/guicast/bccmdl.py | 20 ++++++++++++++--- cinelerra-5.0/guicast/bccmodels.C | 3 +++ cinelerra-5.0/guicast/bccmodels.h | 6 +++-- cinelerra-5.0/guicast/test4.C | 6 ++--- cinelerra-5.0/guicast/vframe.C | 28 ++++++++++++++++++++++++ cinelerra-5.0/guicast/xfer.C | 5 ++++- cinelerra-5.0/quicktime/colormodels.h | 6 +++-- 14 files changed, 97 insertions(+), 35 deletions(-) diff --git a/cinelerra-5.0/cinelerra/cwindowgui.C b/cinelerra-5.0/cinelerra/cwindowgui.C index a0762595..470d0b02 100644 --- a/cinelerra-5.0/cinelerra/cwindowgui.C +++ b/cinelerra-5.0/cinelerra/cwindowgui.C @@ -902,7 +902,7 @@ void CWindowCanvas::draw_refresh(int flush) if(get_canvas() && !get_canvas()->get_video_on()) { - if(refresh_frame) + if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0) { float in_x1, in_y1, in_x2, in_y2; float out_x1, out_y1, out_x2, out_y2; @@ -2118,7 +2118,7 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) - if(refresh_frame) + if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0) { if(draw) @@ -2174,7 +2174,7 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) // Get color out of frame. // Doesn't work during playback because that bypasses the refresh frame. - if(refresh_frame) + if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0) { float cursor_x = get_cursor_x(); float cursor_y = get_cursor_y(); diff --git a/cinelerra-5.0/cinelerra/devicev4l2base.C b/cinelerra-5.0/cinelerra/devicev4l2base.C index d78bd35c..53c11722 100644 --- a/cinelerra-5.0/cinelerra/devicev4l2base.C +++ b/cinelerra-5.0/cinelerra/devicev4l2base.C @@ -304,7 +304,7 @@ int DeviceV4L2Base::v4l2_open(int color_model) int best_height = config_height; unsigned int best_format = 0; int best_merit = 0; - //int best_color_model = -1; + int best_color_model = -1; int best_area = 1; int driver = video_device->in_config->driver; @@ -322,6 +322,7 @@ int DeviceV4L2Base::v4l2_open(int color_model) int cmodel = -1; switch(fmt.pixelformat) { + case V4L2_PIX_FMT_UYVY: cmodel = BC_UVY422; merit = 4; break; case V4L2_PIX_FMT_YUYV: cmodel = BC_YUV422; merit = 4; break; case V4L2_PIX_FMT_Y41P: cmodel = BC_YUV411P; merit = 1; break; case V4L2_PIX_FMT_YVU420: cmodel = BC_YUV420P; merit = 3; break; @@ -340,7 +341,7 @@ int DeviceV4L2Base::v4l2_open(int color_model) { best_merit = merit; best_format = fmt.pixelformat; - //best_color_model = cmodel; + best_color_model = cmodel; } for( int n=0; n<20; ++n ) { @@ -379,6 +380,7 @@ int DeviceV4L2Base::v4l2_open(int color_model) best_format = V4L2_PIX_FMT_MPEG; break; default: + best_color_model = color_model; best_format = cmodel_to_device(color_model); break; } @@ -588,7 +590,7 @@ int DeviceV4L2Base::v4l2_open(int color_model) perror("DeviceV4L2Base::v4l2_open VIDIOC_S_JPEGCOMP"); } - this->color_model = color_model; + this->color_model = best_color_model; return 0; } @@ -739,6 +741,7 @@ unsigned int DeviceV4L2Base::cmodel_to_device(int color_model) { case BC_COMPRESSED: return V4L2_PIX_FMT_MJPEG; case BC_YUV422: return V4L2_PIX_FMT_YUYV; + case BC_UVY422: return V4L2_PIX_FMT_UYVY; case BC_YUV411P: return V4L2_PIX_FMT_Y41P; case BC_YUV420P: return V4L2_PIX_FMT_YVU420; case BC_YUV422P: return V4L2_PIX_FMT_YUV422P; diff --git a/cinelerra-5.0/cinelerra/edit.C b/cinelerra-5.0/cinelerra/edit.C index 6bf265d7..d1421020 100644 --- a/cinelerra-5.0/cinelerra/edit.C +++ b/cinelerra-5.0/cinelerra/edit.C @@ -340,16 +340,16 @@ double Edit::frame_w() double Edit::picon_w() { - if(asset) - return (double)edl->local_session->zoom_track * - asset->width / - asset->height; - if(nested_edl) - return (double)edl->local_session->zoom_track * - nested_edl->session->output_w / - nested_edl->session->output_h; - - return 0; + int w = 0, h = 0; + if(asset) { + w = asset->width; + h = asset->height; + } + else if(nested_edl) { + w = nested_edl->session->output_w; + h = nested_edl->session->output_h; + } + return w>0 && h>0 ? ((double)edl->local_session->zoom_track*w)/h : 0; } int Edit::picon_h() diff --git a/cinelerra-5.0/cinelerra/resourcepixmap.C b/cinelerra-5.0/cinelerra/resourcepixmap.C index 4cfea843..a8c0f8a7 100644 --- a/cinelerra-5.0/cinelerra/resourcepixmap.C +++ b/cinelerra-5.0/cinelerra/resourcepixmap.C @@ -851,8 +851,8 @@ void ResourcePixmap::draw_video_resource(TrackCanvas *canvas, int64_t picon_h = edit->picon_h(); -// Don't draw video if picon is bigger than edit - if(picon_w > edit_w) return; +// Don't draw video if picon is empty or bigger than edit + if( picon_w <= 0 || picon_w > edit_w ) return; // pixels spanned by a frame double frame_w = edit->frame_w(); diff --git a/cinelerra-5.0/cinelerra/vdevicev4l2.C b/cinelerra-5.0/cinelerra/vdevicev4l2.C index 49c23340..c2ca9e97 100644 --- a/cinelerra-5.0/cinelerra/vdevicev4l2.C +++ b/cinelerra-5.0/cinelerra/vdevicev4l2.C @@ -52,8 +52,15 @@ int VDeviceV4L2::open_input() int result = get_sources(); if( !result ) { - device->channel->use_frequency = 1; - device->channel->use_fine = 1; + ArrayList *inputs = device->get_inputs(); + for( int i=0; isize(); ++i ) { + if( inputs->get(i)->tuner ) { + device->channel->use_frequency = 1; + device->channel->use_fine = 1; + } + else + device->channel->use_input = 1; + } } return result; } @@ -99,7 +106,7 @@ int VDeviceV4L2::read_buffer(VFrame *frame) VFrame *buffer = device_buffer(bfr); //printf("VDeviceV4L2::read_buffer %d %p %p\n", // __LINE__, frame->get_data(), buffer->get_data()); - frame->copy_from(buffer); + frame->transfer_from(buffer); put_buffer(bfr); } else diff --git a/cinelerra-5.0/cinelerra/videodevice.C b/cinelerra-5.0/cinelerra/videodevice.C index eceb75c8..104f11fb 100644 --- a/cinelerra-5.0/cinelerra/videodevice.C +++ b/cinelerra-5.0/cinelerra/videodevice.C @@ -360,7 +360,6 @@ int VideoDevice::is_compressed(int driver, int use_file, int use_fixed) // FileMOV needs to have write_frames called so the start codes get scanned. return ((driver == CAPTURE_BUZ && use_fixed) || (driver == VIDEO4LINUX2JPEG && use_fixed) || - (driver == VIDEO4LINUX2MPEG && use_fixed) || (driver == CAPTURE_JPEG_WEBCAM && use_fixed) || driver == CAPTURE_LML || driver == CAPTURE_FIREWIRE || diff --git a/cinelerra-5.0/guicast/bcbitmap.C b/cinelerra-5.0/guicast/bcbitmap.C index 6515d185..8289c599 100644 --- a/cinelerra-5.0/guicast/bcbitmap.C +++ b/cinelerra-5.0/guicast/bcbitmap.C @@ -150,7 +150,7 @@ BC_XvShmImage::BC_XvShmImage(BC_Bitmap *bitmap, int index, h = xv_image->height; if(!XShmAttach(top_level->display, &shm_info)) perror("BC_XvShmImage::BC_XvShmImage XShmAttach"); - if( color_model == BC_YUV422 ) { + if( color_model == BC_YUV422 || color_model == BC_UVY422 ) { bytesPerLine = w*2; bitsPerPixel = 12; row_data = new unsigned char*[h]; @@ -223,7 +223,7 @@ BC_XvImage::BC_XvImage(BC_Bitmap *bitmap, int index, xv_image->data = (char *) data; w = xv_image->width; h = xv_image->height; - if( color_model == BC_YUV422 ) { + if( color_model == BC_YUV422 || color_model == BC_UVY422 ) { int bytesPerLine = w*2; row_data = new unsigned char*[h]; for( int i=0; iget_data(), w * h + w * h); break; } diff --git a/cinelerra-5.0/guicast/bccmdl.py b/cinelerra-5.0/guicast/bccmdl.py index bc5138d1..2850fe50 100755 --- a/cinelerra-5.0/guicast/bccmdl.py +++ b/cinelerra-5.0/guicast/bccmdl.py @@ -192,6 +192,19 @@ base = { }, }, + "uyvy8888": { + "i8": { + "r": " int32_t u = inp[0], iy = inp[((i&1)<<1)+1], y = iy*0x010101u, v = inp[2];", + "w": " if( !(j&1) ) { *out++ = u; *out++ = y; *out++ = v; *out = y; }\n" + + " else { *out++= y; }", + }, + "i16": { + "r": " int32_t u = inp[0]<<8, iy = inp[((i&1)<<1)+1], y = iy*0x010101u, v = inp[2]<<8;", + "w": " if( !(j&1) ) { *out++ = u>>8; *out++ = y>>8; *out++ = v>>8; *out = y>>8; }\n" + + " else { *out++= y>>8; }", + }, + }, + "yuv10101010": { "i8": { "r": " uint32_t it = *(uint32_t*)inp;\n" + @@ -414,6 +427,7 @@ add_cmodel("bc_yuv161616", "i16", "yuv161616") add_cmodel("bc_yuva16161616", "i16", "yuv161616", "a16") add_cmodel("bc_yuv422", "i8", "yuyv8888") +add_cmodel("bc_uvy422", "i8", "uyvy8888") add_cmodel("bc_a8") add_cmodel("bc_a16") add_cmodel("bc_a_float") @@ -468,9 +482,9 @@ def is_rgb(nm): def is_yuv(nm): return nm in [ "bc_yuv888", "bc_yuva8888", "bc_yuv161616", \ - "bc_yuva16161616", "bc_yuv422", "bc_yuv101010", "bc_vyu888", \ - "bc_uyva8888", "bc_yuv420p", "bc_yuv422p", "bc_yuv444p", \ - "bc_yuv411p", "bc_yuv410p", ] + "bc_yuva16161616", "bc_yuv422", "bc_uvy422", "bc_yuv101010", \ + "bc_vyu888", "bc_uyva8888", "bc_yuv420p", "bc_yuv422p", \ + "bc_yuv444p", "bc_yuv411p", "bc_yuv410p", ] def is_planar(nm): return nm in [ "bc_yuv420p", "bc_yuv422p", "bc_yuv444p", \ diff --git a/cinelerra-5.0/guicast/bccmodels.C b/cinelerra-5.0/guicast/bccmodels.C index 0d92551f..6abfe00f 100644 --- a/cinelerra-5.0/guicast/bccmodels.C +++ b/cinelerra-5.0/guicast/bccmodels.C @@ -94,6 +94,7 @@ int BC_CModels::calculate_pixelsize(int colormodel) case BC_YUV422P: return 1; case BC_YUV444P: return 1; case BC_YUV422: return 2; + case BC_UVY422: return 2; case BC_YUV411P: return 1; case BC_YUV410P: return 1; case BC_RGB_FLOATP: return 4; @@ -146,6 +147,7 @@ int BC_CModels::bc_to_x(int color_model) switch(color_model) { case BC_YUV420P: return FOURCC_YV12; case BC_YUV422: return FOURCC_YUV2; + case BC_UVY422: return FOURCC_UYVY; } return -1; } @@ -225,6 +227,7 @@ int BC_CModels::is_yuv(int colormodel) case BC_YUV161616: case BC_YUVA16161616: case BC_YUV422: + case BC_UVY422: case BC_YUV101010: case BC_VYU888: case BC_UYVA8888: diff --git a/cinelerra-5.0/guicast/bccmodels.h b/cinelerra-5.0/guicast/bccmodels.h index 92f4cf38..e4e1cba4 100644 --- a/cinelerra-5.0/guicast/bccmodels.h +++ b/cinelerra-5.0/guicast/bccmodels.h @@ -42,6 +42,7 @@ #define BC_YUVA8888 14 #define BC_YUV161616 15 #define BC_YUVA16161616 16 +#define BC_UVY422 18 #define BC_YUV422 19 #define BC_A8 22 #define BC_A16 23 @@ -53,9 +54,9 @@ #define BC_RGBA_FLOAT 30 // Planar #define BC_YUV420P 7 -#define BC_YUV422P 17 +#define BC_YUV422P 8 #define BC_YUV444P 27 -#define BC_YUV411P 18 +#define BC_YUV411P 17 #define BC_YUV410P 28 #define BC_RGB_FLOATP 32 #define BC_RGBA_FLOATP 33 @@ -65,6 +66,7 @@ // For communication with the X Server #define FOURCC_YV12 0x32315659 /* YV12 YUV420P */ #define FOURCC_YUV2 0x32595559 /* YUV2 YUV422 */ +#define FOURCC_UYVY 0x59565955 /* UYVY UVY422 */ #define FOURCC_I420 0x30323449 /* I420 Intel Indeo 4 */ diff --git a/cinelerra-5.0/guicast/test4.C b/cinelerra-5.0/guicast/test4.C index 09237a76..e28ec10b 100644 --- a/cinelerra-5.0/guicast/test4.C +++ b/cinelerra-5.0/guicast/test4.C @@ -78,10 +78,10 @@ void TestWindow::show_text(int tx, int ty, const char *fmt, ...) const char *cmdl[] = { "transparency", "compressed", "rgb8", "rgb565", "bgr565", "bgr888", "bgr8888", "yuv420p", - "none", "rgb888", "rgba8888", "rgb161616", "rgba16161616", "yuv888", "yuva8888", "yuv161616", - "yuva16161616", "yuv422p", "yuv411p", "yuv422", "argb8888", "abgr8888", "a8", "a16", + "yuv422p", "rgb888", "rgba8888", "rgb161616", "rgba16161616", "yuv888", "yuva8888", "yuv161616", + "yuva16161616", "yuv411p", "uvy422", "yuv422", "argb8888", "abgr8888", "a8", "a16", "yuv101010", "vyu888", "uyva8888", "yuv444p", "yuv410p", "rgb_float", "rgba_float", "a_float", - "rgb_floatp", + "rgb_floatp", "rgba_floatp", }; void write_pbm(uint8_t *tp, int w, int h, const char *fmt, ...) diff --git a/cinelerra-5.0/guicast/vframe.C b/cinelerra-5.0/guicast/vframe.C index a3b09324..e3f5bf0a 100644 --- a/cinelerra-5.0/guicast/vframe.C +++ b/cinelerra-5.0/guicast/vframe.C @@ -1042,6 +1042,7 @@ int VFrame::transfer_from(VFrame *that, int bg_color) return this->copy_from(that); timestamp = that->timestamp; +#if 0 BC_CModels::transfer( this->get_rows(), that->get_rows(), // Packed data out/in this->get_y(), this->get_u(), this->get_v(), // Planar data out/in @@ -1051,6 +1052,33 @@ int VFrame::transfer_from(VFrame *that, int bg_color) that->get_color_model(), this->get_color_model(), // Color models in/out bg_color, // alpha blend bg_color that->get_w(), this->get_w()); // rowspans (of luma for YUV) +#else + unsigned char *in_ptrs[4], *out_ptrs[4]; + unsigned char **inp, **outp; + if( BC_CModels::is_planar(that->get_color_model()) ) { + in_ptrs[0] = that->get_y(); + in_ptrs[1] = that->get_u(); + in_ptrs[2] = that->get_v(); + in_ptrs[3] = that->get_a(); + inp = in_ptrs; + } + else + inp = that->get_rows(); + if( BC_CModels::is_planar(this->get_color_model()) ) { + out_ptrs[0] = this->get_y(); + out_ptrs[1] = this->get_u(); + out_ptrs[2] = this->get_v(); + out_ptrs[3] = this->get_a(); + outp = out_ptrs; + } + else + outp = this->get_rows(); + BC_CModels::transfer(outp, this->get_color_model(), + 0, 0, this->get_w(), this->get_h(), this->get_w(), + inp, that->get_color_model(), + 0, 0, that->get_w(), that->get_h(), that->get_w(), + bg_color); +#endif return 0; } diff --git a/cinelerra-5.0/guicast/xfer.C b/cinelerra-5.0/guicast/xfer.C index 3e0e3bd2..c689b6b6 100644 --- a/cinelerra-5.0/guicast/xfer.C +++ b/cinelerra-5.0/guicast/xfer.C @@ -104,6 +104,7 @@ void BC_Xfer::init( { // prevent bounds errors on poorly dimensioned macro pixel formats switch( in_colormodel ) { + case BC_UVY422: case BC_YUV422: in_w &= ~1; break; // 2x1 case BC_YUV420P: in_w &= ~1; in_h &= ~1; break; // 2x2 case BC_YUV422P: in_w &= ~1; break; // 2x1 @@ -111,6 +112,7 @@ void BC_Xfer::init( case BC_YUV411P: in_w &= ~3; break; // 4x1 } switch( out_colormodel ) { + case BC_UVY422: case BC_YUV422: out_w &= ~1; break; case BC_YUV420P: out_w &= ~1; out_h &= ~1; break; case BC_YUV422P: out_w &= ~1; break; @@ -165,7 +167,8 @@ void BC_Xfer::init( double hscale = (double)in_w/out_w; for( int i=0; i