Changeset 236


Ignore:
Timestamp:
04/22/2012 05:21:34 AM (13 months ago)
Author:
reyalp
Message:

work in progress live view matching chdk reyalp-ptp-live rev 1817

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/chdkptp.c

    r234 r236  
    10821082        } 
    10831083        if ( !ptp_chdk_call_handler(params,&params->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/* 
     1112lbuf[,errmsg]=con:get_live_data(lbuf,flags) 
     1113lbuf - lbuf to re-use, will be created if nil 
     1114*/ 
     1115static 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,&params->deviceinfo,flags,&data,&data_size) ) { 
    10841127                lua_pushboolean(L,0); 
    10851128                lua_pushstring(L,"ptp error"); 
     
    14211464  {"get_handler",chdk_get_handler}, 
    14221465  {"call_handler",chdk_call_handler}, 
     1466  {"get_live_data",chdk_get_live_data}, 
    14231467#endif 
    14241468  {NULL, NULL} 
  • trunk/liveimg.c

    r235 r236  
    426426} 
    427427 
     428/* 
     429check framebuffer desc values, and return a descriptive error or NULL 
     430TODO can't check total size without bpp 
     431*/ 
     432static 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/* 
     451convert viewport data to RGB pimg 
     452pimg=liveimg.get_viewport2_pimg(pimg,live_frame,skip) 
     453pimg: pimg to re-use, created if nil, replaced if size doesn't match 
     454live_fream: from get_live_data 
     455skip: boolean - if true, each U Y V Y Y Y is converted to 2 pixels, otherwise 4 
     456returns nil if info does not contain a live view 
     457*/ 
     458static 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 
    428515static void convert_palette(palette_entry_rgba_t *pal_rgba,lv_vid_info *vi) { 
    429516        const char *pal=NULL; 
     
    512599        for(y=0;y<height;y++,p-=y_inc) { 
    513600                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 
     611static 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/* 
     628convert bitmap data to RGBA pimg 
     629pimg=liveimg.get_bitmap2_pimg(pimg,frame,skip) 
     630pimg: pimg to re-use, created if nil, replaced if size doesn't match 
     631frame: from live_get_data 
     632skip: boolean - if true, every other pixel in the x axis is discarded (for viewports with a 1:2 par) 
     633returns nil if info does not contain a bitmap 
     634*/ 
     635static 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) { 
    514701                        palette_entry_rgba_t *c =&pal_rgba[*(p+x)]; 
    515702                        *r++ = c->r; 
     
    588775static const luaL_Reg liveimg_funcs[] = { 
    589776  {"get_bitmap_pimg", liveimg_get_bitmap_pimg}, 
     777  {"get_bitmap2_pimg", liveimg_get_bitmap2_pimg}, 
    590778  {"get_viewport_pimg", liveimg_get_viewport_pimg}, 
     779  {"get_viewport2_pimg", liveimg_get_viewport2_pimg}, 
    591780  {NULL, NULL} 
    592781}; 
  • trunk/lua/chdku.lua

    r226 r236  
    881881        'palette_buffer_size',    -- Size of palette data sent (in bytes) 
    882882} 
     883 
     884chdku.live2_fields={ 
     885        'lcd_aspect_ratio', 
     886        'palette_type', 
     887        'palette_data_start', 
     888} 
     889 
     890chdku.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 
    883909chdku.live_frame_map={} 
     910chdku.live2_frame_map={} 
     911chdku.live2_field_names={} 
    884912 
    885913--[[ 
     
    893921                chdku.live_frame_map[name] = (i-1)*4 
    894922        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 
    895935end 
    896936live_init_maps() 
     937 
     938function 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]) 
     943end 
     944local 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} 
     952function chdku.live2_wrap(frame) 
     953        local t={ _frame = frame} 
     954        setmetatable(t,live2_info_meta) 
     955        return t 
     956end 
    897957 
    898958function chdku.live_get_base_field(base,field) 
     
    9841044        end 
    9851045        return true 
     1046end 
     1047 
     1048function 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 
    9861059end 
    9871060 
  • trunk/lua/gui_live.lua

    r230 r236  
    106106                m.vp_aspect_factor = 1 
    107107                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 
     124end 
     125 
     126local 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 
    108138        end 
    109139 
     
    218248end 
    219249 
     250local palette_size_for_type={ 
     251        16*4, 
     252        16*4, 
     253        256*4, 
     254} 
     255local 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 
     288end 
     289 
    220290-- TODO this is just to allow us to read/write a binary integer record size 
    221291local dump_recsize = lbuf.new(4) 
     
    348418                end 
    349419                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) 
    351422                if not status then 
    352423                        end_dump() 
     
    355426                        stats:stop() 
    356427                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() 
    361434                end 
    362435                m.icnv:action() 
     
    412485        ccnv:Activate() 
    413486        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        --[[ 
    414519        if m.get_current_frame_data() then 
    415520                if m.vp_active then 
     
    442547                end 
    443548        end 
     549        --]] 
    444550        ccnv:Flush() 
    445551        stats:end_frame() 
     
    584690                        return 
    585691                end 
    586                 update_base_data(con.live.base) 
     692                --update_base_data(con.live.base) 
    587693                m.live_con_valid = true 
    588694        end 
  • trunk/ptp.c

    r145 r236  
    19821982 
    19831983} 
     1984int 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} 
    19842008#endif 
    19852009 
  • trunk/ptp.h

    r145 r236  
    897897int ptp_chdk_get_handler(PTPParams* params, PTPDeviceInfo* deviceinfo,int id,int *handler); 
    898898int ptp_chdk_call_handler(PTPParams* params, PTPDeviceInfo* deviceinfo,int handler,int harg1,int harg2,char **data,int *data_size); 
     899int ptp_chdk_get_live_data(PTPParams* params, PTPDeviceInfo* deviceinfo,int flags,char **data,int *data_size); 
    899900#endif 
    900901 
Note: See TracChangeset for help on using the changeset viewer.