Changeset 236
Legend:
- Unmodified
- Added
- Removed
-
trunk/chdkptp.c
r234 r236 1082 1082 } 1083 1083 if ( !ptp_chdk_call_handler(params,¶ms->deviceinfo,handler,harg1,harg2,&data,&data_size) ) { 1084 lua_pushboolean(L,0); 1085 lua_pushstring(L,"ptp error"); 1086 return 2; 1087 } 1088 if(!data) { 1089 lua_pushboolean(L,0); 1090 lua_pushstring(L,"no data"); 1091 return 2; 1092 } 1093 if(!data_size) { 1094 lua_pushboolean(L,0); 1095 lua_pushstring(L,"zero data size"); 1096 return 2; 1097 } 1098 if(buf) { 1099 if(buf->flags & LBUF_FL_FREE) { 1100 free(buf->bytes); 1101 } 1102 buf->bytes = data; 1103 buf->len = data_size; 1104 buf->flags = LBUF_FL_FREE; 1105 lua_pushvalue(L,2); // copy it to stack top for return 1106 } else { 1107 lbuf_create(L,data,data_size,LBUF_FL_FREE); 1108 } 1109 return 1; 1110 } 1111 /* 1112 lbuf[,errmsg]=con:get_live_data(lbuf,flags) 1113 lbuf - lbuf to re-use, will be created if nil 1114 */ 1115 static int chdk_get_live_data(lua_State *L) { 1116 CHDK_CONNECTION_METHOD; 1117 lBuf_t *buf = lbuf_getlbuf(L,2); 1118 int flags=lua_tonumber(L,3); 1119 char *data=NULL; 1120 unsigned data_size = 0; 1121 if ( !ptp_usb->connected ) { 1122 lua_pushboolean(L,0); 1123 lua_pushstring(L,"not connected"); 1124 return 2; 1125 } 1126 if ( !ptp_chdk_get_live_data(params,¶ms->deviceinfo,flags,&data,&data_size) ) { 1084 1127 lua_pushboolean(L,0); 1085 1128 lua_pushstring(L,"ptp error"); … … 1421 1464 {"get_handler",chdk_get_handler}, 1422 1465 {"call_handler",chdk_call_handler}, 1466 {"get_live_data",chdk_get_live_data}, 1423 1467 #endif 1424 1468 {NULL, NULL} -
trunk/liveimg.c
r235 r236 426 426 } 427 427 428 /* 429 check framebuffer desc values, and return a descriptive error or NULL 430 TODO can't check total size without bpp 431 */ 432 static const char * check_fb_desc(lv_framebuffer_desc *desc) { 433 if(desc->visible_height + desc->visible_buffer_yoffset > desc->buffer_height) { 434 return "height + yoffset > buffer_height"; 435 } 436 437 if(desc->visible_width + desc->visible_buffer_xoffset > desc->buffer_width) { 438 return "vp_width + vp_xoffset > vp_buffer_width"; 439 } 440 // sanity check, this should actually be harmless 441 if(desc->visible_width > desc->logical_width) { 442 return "visible_width > logical_width"; 443 } 444 if(desc->visible_height > desc->logical_height) { 445 return "visible_height > logical_height"; 446 } 447 return NULL; 448 } 449 450 /* 451 convert viewport data to RGB pimg 452 pimg=liveimg.get_viewport2_pimg(pimg,live_frame,skip) 453 pimg: pimg to re-use, created if nil, replaced if size doesn't match 454 live_fream: from get_live_data 455 skip: boolean - if true, each U Y V Y Y Y is converted to 2 pixels, otherwise 4 456 returns nil if info does not contain a live view 457 */ 458 static int liveimg_get_viewport2_pimg(lua_State *L) { 459 lv_data_header *frame; 460 liveimg_pimg_t *im = pimg_get(L,1); 461 lBuf_t *frame_lb = luaL_checkudata(L,2,LBUF_META); 462 int skip = lua_toboolean(L,3); 463 // pixel aspect ratio 464 int par = (skip == 1)?2:1; 465 466 frame = (lv_data_header *)frame_lb->bytes; 467 468 // this is not currently an error, if sent live data without viewport selected, just return nil image 469 if(!frame->vp.data_start) { 470 lua_pushnil(L); 471 return 1; 472 } 473 474 unsigned vwidth = frame->vp.visible_width/par; 475 unsigned dispsize = vwidth*frame->vp.visible_height; 476 477 // sanity check size - depends on type 478 if(frame->vp.data_start + (frame->vp.buffer_width*frame->vp.buffer_height*12)/8 > frame_lb->len) { 479 return luaL_error(L,"data < buffer_width*buffer_height"); 480 } 481 const char *fb_desc_err = check_fb_desc(&frame->vp); 482 if(fb_desc_err) { 483 return luaL_error(L,fb_desc_err); 484 } 485 486 if(im && dispsize != im->width*im->height) { 487 pimg_destroy(im); 488 im = NULL; 489 } 490 if(im) { 491 lua_pushvalue(L, 1); // copy im onto top for return 492 // set width and height, could have changed without changing byte count 493 im->width = vwidth; 494 im->height = frame->vp.visible_height; 495 } else { // create an new im 496 pimg_create(L); 497 im = luaL_checkudata(L,-1,LIVEIMG_PIMG_META); 498 if(!pimg_init_rgb(im,vwidth,frame->vp.visible_height)) { 499 return luaL_error(L,"failed to create image"); 500 } 501 } 502 503 yuv_live_to_cd_rgb(frame_lb->bytes+frame->vp.data_start, 504 frame->vp.buffer_width, 505 frame->vp.buffer_height, 506 frame->vp.visible_buffer_xoffset, 507 frame->vp.visible_buffer_yoffset, 508 frame->vp.visible_width, 509 frame->vp.visible_height, 510 skip, 511 im->r,im->g,im->b); 512 return 1; 513 } 514 428 515 static void convert_palette(palette_entry_rgba_t *pal_rgba,lv_vid_info *vi) { 429 516 const char *pal=NULL; … … 512 599 for(y=0;y<height;y++,p-=y_inc) { 513 600 for(x=0;x<bi->bm_max_width;x+=x_inc) { 601 palette_entry_rgba_t *c =&pal_rgba[*(p+x)]; 602 *r++ = c->r; 603 *g++ = c->g; 604 *b++ = c->b; 605 *a++ = c->a; 606 } 607 } 608 return 1; 609 } 610 611 static void convert_palette2(palette_entry_rgba_t *pal_rgba,lv_data_header *frame) { 612 const char *pal=NULL; 613 palette_convert_t *convert=get_palette_convert(frame->palette_type); 614 if(!convert || !frame->palette_data_start) { 615 convert = get_palette_convert(1); 616 pal = palette_type1_default; 617 } else { 618 pal = ((char *)frame + frame->palette_data_start); 619 } 620 yuv_palette_to_rgba_fn fn = convert->to_rgba; 621 int i; 622 for(i=0;i<256;i++) { 623 fn(pal,i,&pal_rgba[i]); 624 } 625 } 626 627 /* 628 convert bitmap data to RGBA pimg 629 pimg=liveimg.get_bitmap2_pimg(pimg,frame,skip) 630 pimg: pimg to re-use, created if nil, replaced if size doesn't match 631 frame: from live_get_data 632 skip: boolean - if true, every other pixel in the x axis is discarded (for viewports with a 1:2 par) 633 returns nil if info does not contain a bitmap 634 */ 635 static int liveimg_get_bitmap2_pimg(lua_State *L) { 636 palette_entry_rgba_t pal_rgba[256]; 637 638 lv_data_header *frame; 639 liveimg_pimg_t *im = pimg_get(L,1); 640 lBuf_t *frame_lb = luaL_checkudata(L,2,LBUF_META); 641 int skip = lua_toboolean(L,3); 642 // pixel aspect ratio 643 int par = (skip == 1)?2:1; 644 645 frame = (lv_data_header *)frame_lb->bytes; 646 647 if(!frame->bm.data_start) { 648 lua_pushnil(L); 649 return 1; 650 } 651 652 // sanity check size - depends on type 653 if(frame->bm.data_start + frame->bm.buffer_width*frame->bm.buffer_height > frame_lb->len) { 654 return luaL_error(L,"data < buffer_width*buffer_height"); 655 } 656 657 const char *fb_desc_err = check_fb_desc(&frame->bm); 658 if(fb_desc_err) { 659 return luaL_error(L,fb_desc_err); 660 } 661 662 if(get_palette_size(frame->palette_type) + frame->palette_data_start > frame_lb->len) { 663 return luaL_error(L,"data < palette size"); 664 } 665 666 convert_palette2(pal_rgba,frame); 667 668 unsigned vwidth = frame->bm.visible_width/par; 669 unsigned dispsize = vwidth*frame->bm.visible_height; 670 671 672 if(im && dispsize != im->width*im->height) { 673 pimg_destroy(im); 674 im = NULL; 675 } 676 if(im) { 677 lua_pushvalue(L, 1); // copy im onto top for return 678 } else { // create an new im 679 pimg_create(L); 680 im = luaL_checkudata(L,-1,LIVEIMG_PIMG_META); 681 if(!pimg_init_rgba(im,vwidth,frame->bm.visible_height)) { 682 return luaL_error(L,"failed to create image"); 683 } 684 } 685 686 int y_inc = frame->bm.buffer_width; 687 int x_inc = par; 688 int x,y; 689 int height = frame->bm.visible_height; 690 691 uint8_t *p=((uint8_t *)frame_lb->bytes + frame->bm.data_start) + (height-1)*y_inc; 692 693 uint8_t *r = im->r; 694 uint8_t *g = im->g; 695 uint8_t *b = im->b; 696 uint8_t *a = im->a; 697 698 // TODO we don't actually check the various offsets 699 for(y=0;y<height;y++,p-=y_inc) { 700 for(x=0;x<frame->bm.visible_width;x+=x_inc) { 514 701 palette_entry_rgba_t *c =&pal_rgba[*(p+x)]; 515 702 *r++ = c->r; … … 588 775 static const luaL_Reg liveimg_funcs[] = { 589 776 {"get_bitmap_pimg", liveimg_get_bitmap_pimg}, 777 {"get_bitmap2_pimg", liveimg_get_bitmap2_pimg}, 590 778 {"get_viewport_pimg", liveimg_get_viewport_pimg}, 779 {"get_viewport2_pimg", liveimg_get_viewport2_pimg}, 591 780 {NULL, NULL} 592 781 }; -
trunk/lua/chdku.lua
r226 r236 881 881 'palette_buffer_size', -- Size of palette data sent (in bytes) 882 882 } 883 884 chdku.live2_fields={ 885 'lcd_aspect_ratio', 886 'palette_type', 887 'palette_data_start', 888 } 889 890 chdku.live2_fb_desc_fields={ 891 'logical_width', 892 'logical_height', 893 894 'buffer_width', 895 'buffer_height', 896 897 'buffer_logical_xoffset', 898 'buffer_logical_yoffset', 899 900 'visible_width', 901 'visible_height', 902 903 'visible_buffer_xoffset', 904 'visible_buffer_yoffset', 905 906 'data_start', 907 } 908 883 909 chdku.live_frame_map={} 910 chdku.live2_frame_map={} 911 chdku.live2_field_names={} 884 912 885 913 --[[ … … 893 921 chdku.live_frame_map[name] = (i-1)*4 894 922 end 923 for i,name in ipairs(chdku.live2_fields) do 924 chdku.live2_frame_map[name] = (i-1)*4 925 table.insert(chdku.live2_field_names,name) 926 end 927 local off = #chdku.live2_fields * 4 928 for i,pfx in ipairs({'vp','bm'}) do 929 for j,name in ipairs(chdku.live2_fb_desc_fields) do 930 chdku.live2_frame_map[pfx .. '_' .. name] = off 931 table.insert(chdku.live2_field_names,pfx .. '_' .. name) 932 off = off + 4; 933 end 934 end 895 935 end 896 936 live_init_maps() 937 938 function chdku.live2_get_frame_field(frame,field) 939 if not frame then 940 return nil 941 end 942 return frame:get_i32(chdku.live2_frame_map[field]) 943 end 944 local live2_info_meta={ 945 __index=function(t,key) 946 local frame = rawget(t,'_frame') 947 if frame and chdku.live2_frame_map[key] then 948 return chdku.live2_get_frame_field(frame,key) 949 end 950 end 951 } 952 function chdku.live2_wrap(frame) 953 local t={ _frame = frame} 954 setmetatable(t,live2_info_meta) 955 return t 956 end 897 957 898 958 function chdku.live_get_base_field(base,field) … … 984 1044 end 985 1045 return true 1046 end 1047 1048 function con_methods:live2_get_frame(what) 1049 if not self.live2 then 1050 self.live2 = chdku.live2_wrap() 1051 end 1052 1053 local frame, err = self:get_live_data(self.live2._frame,what) 1054 if frame then 1055 self.live2._frame = frame 1056 return true 1057 end 1058 return false, err 986 1059 end 987 1060 -
trunk/lua/gui_live.lua
r230 r236 106 106 m.vp_aspect_factor = 1 107 107 vp_h = m.li.vp_max_height 108 end 109 110 local w,h = gui.parsesize(m.icnv.rastersize) 111 112 local update 113 if w ~= vp_w then 114 update = true 115 end 116 if h ~= vp_h then 117 update = true 118 end 119 if update then 120 m.icnv.rastersize = vp_w.."x"..vp_h 121 iup.Refresh(m.container) 122 gui.resize_for_content() 123 end 124 end 125 126 local function update_canvas_size2() 127 if not con.live2 then 128 return 129 end 130 local vp_w = con.live2.vp_logical_width/m.vp_par 131 local vp_h 132 if aspect_toggle.value == 'ON' then 133 vp_h = vp_w/screen_aspects[con.live2.lcd_aspect_ratio] 134 m.vp_aspect_factor = vp_h/con.live2.vp_logical_height 135 else 136 m.vp_aspect_factor = 1 137 vp_h = con.live2.vp_logical_height 108 138 end 109 139 … … 218 248 end 219 249 250 local palette_size_for_type={ 251 16*4, 252 16*4, 253 256*4, 254 } 255 local function update_frame_data2(frame) 256 local dirty 257 for i,f in ipairs(chdku.live2_field_names) do 258 local v = chdku.live2_get_frame_field(frame,f) 259 if v ~= last_frame_fields[f] then 260 dirty = true 261 end 262 end 263 if dirty then 264 printf('update_frame_data: changed\n') 265 for i,f in ipairs(chdku.live2_field_names) do 266 local v = chdku.live2_get_frame_field(frame,f) 267 printf("%s:%s->%s\n",f,tostring(last_frame_fields[f]),v) 268 last_frame_fields[f]=v 269 end 270 if last_frame_fields.palette_data_start > 0 then 271 printf('palette:\n') 272 local c=0 273 ---[[ 274 local bytes = {frame:byte(last_frame_fields.palette_data_start+1, 275 last_frame_fields.palette_data_start+palette_size_for_type[last_frame_fields.palette_type])} 276 for i,v in ipairs(bytes) do 277 printf("0x%02x,",v) 278 c = c + 1 279 if c == 16 then 280 printf('\n') 281 c=0 282 else 283 printf(' ') 284 end 285 end 286 end 287 end 288 end 289 220 290 -- TODO this is just to allow us to read/write a binary integer record size 221 291 local dump_recsize = lbuf.new(4) … … 348 418 end 349 419 stats:start_xfer() 350 local status,err = con:live_get_frame(what) 420 --local status,err = con:live_get_frame(what) 421 local status,err = con:live2_get_frame(what) 351 422 if not status then 352 423 end_dump() … … 355 426 stats:stop() 356 427 else 357 stats:end_xfer(con.live.frame:len()) 358 update_frame_data(con.live.frame) 359 record_dump() 360 update_canvas_size() 428 --stats:end_xfer(con.live.frame:len()) 429 stats:end_xfer(con.live2._frame:len()) 430 update_frame_data2(con.live2._frame) 431 --update_frame_data(con.live.frame) 432 --record_dump() 433 update_canvas_size2() 361 434 end 362 435 m.icnv:action() … … 412 485 ccnv:Activate() 413 486 ccnv:Clear() 487 local lv = con.live2 488 if lv and lv._frame then 489 if m.vp_active then 490 m.vp_img = liveimg.get_viewport2_pimg(m.vp_img,lv._frame,m.vp_par == 2) 491 if m.vp_img then 492 if aspect_toggle.value == "ON" then 493 m.vp_img:put_to_cd_canvas(ccnv, 494 lv.vp_buffer_logical_xoffset/m.vp_par, 495 (lv.vp_logical_height - lv.vp_visible_height - lv.vp_buffer_logical_yoffset)*m.vp_aspect_factor, 496 m.vp_img:width(), 497 m.vp_img:height()*m.vp_aspect_factor) 498 else 499 m.vp_img:put_to_cd_canvas(ccnv, 500 lv.vp_buffer_logical_xoffset/m.vp_par, 501 lv.vp_logical_height - lv.vp_visible_height - lv.vp_buffer_logical_yoffset) 502 end 503 end 504 end 505 if m.bm_active then 506 m.bm_img = liveimg.get_bitmap2_pimg(m.bm_img,lv._frame,m.bm_par == 2) 507 if m.bm_img then 508 if bm_fit_toggle.value == "ON" then 509 m.bm_img:blend_to_cd_canvas(ccnv, 0, 0, lv.vp_logical_width/m.vp_par, lv.vp_logical_height*m.vp_aspect_factor) 510 else 511 m.bm_img:blend_to_cd_canvas(ccnv, 0, lv.vp_logical_height - lv.bm_visible_height) 512 end 513 else 514 print('no bm') 515 end 516 end 517 end 518 --[[ 414 519 if m.get_current_frame_data() then 415 520 if m.vp_active then … … 442 547 end 443 548 end 549 --]] 444 550 ccnv:Flush() 445 551 stats:end_frame() … … 584 690 return 585 691 end 586 update_base_data(con.live.base)692 --update_base_data(con.live.base) 587 693 m.live_con_valid = true 588 694 end -
trunk/ptp.c
r145 r236 1982 1982 1983 1983 } 1984 int ptp_chdk_get_live_data(PTPParams* params, PTPDeviceInfo* deviceinfo,int flags,char **data,int *data_size) { 1985 uint16_t r; 1986 PTPContainer ptp; 1987 1988 PTP_CNT_INIT(ptp); 1989 ptp.Code=PTP_OC_CHDK; 1990 ptp.Nparam=2; 1991 ptp.Param1=PTP_CHDK_GetLiveData; 1992 ptp.Param2=flags; 1993 *data = NULL; 1994 *data_size = 0; 1995 1996 r=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data); 1997 if ( r != 0x2001 ) 1998 { 1999 ptp_error(params,"unexpected return code 0x%x",r); 2000 free(*data); 2001 *data = NULL; 2002 return 0; 2003 } 2004 *data_size = ptp.Param1; 2005 return 1; 2006 2007 } 1984 2008 #endif 1985 2009 -
trunk/ptp.h
r145 r236 897 897 int ptp_chdk_get_handler(PTPParams* params, PTPDeviceInfo* deviceinfo,int id,int *handler); 898 898 int ptp_chdk_call_handler(PTPParams* params, PTPDeviceInfo* deviceinfo,int handler,int harg1,int harg2,char **data,int *data_size); 899 int ptp_chdk_get_live_data(PTPParams* params, PTPDeviceInfo* deviceinfo,int flags,char **data,int *data_size); 899 900 #endif 900 901
Note: See TracChangeset
for help on using the changeset viewer.