x393_cmprs.py 13.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
from __future__ import division
from __future__ import print_function

'''
# Copyright (C) 2015, Elphel.inc.
# Class to control JPEG/JP4 compressor  
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http:#www.gnu.org/licenses/>.

@author:     Andrey Filippov
@copyright:  2015 Elphel, Inc.
@license:    GPLv3.0+
@contact:    andrey@elphel.coml
@deffield    updated: Updated
'''
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2015, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
#import sys
#import pickle
from x393_mem                import X393Mem
import x393_axi_control_status

import x393_utils

#import time
import vrlg
class X393Cmprs(object):
    DRY_MODE= True # True
    DEBUG_MODE=1
    x393_mem=None
    x393_axi_tasks=None #x393X393AxiControlStatus
    x393_utils=None
    verbose=1
    def __init__(self, debug_mode=1,dry_mode=True, saveFileName=None):
        self.DEBUG_MODE=  debug_mode
        self.DRY_MODE=    dry_mode
        self.x393_mem=            X393Mem(debug_mode,dry_mode)
        self.x393_axi_tasks=      x393_axi_control_status.X393AxiControlStatus(debug_mode,dry_mode)
        self.x393_utils=          x393_utils.X393Utils(debug_mode,dry_mode, saveFileName) # should not overwrite save file path
        try:
            self.verbose=vrlg.VERBOSE
        except:
            pass
    
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
    def program_status_compressor(self,
                                  cmprs_chn,
                                  mode,     # input [1:0] mode;
                                  seq_num): # input [5:0] seq_num;
        """
        Set status generation mode for selected compressor channel
        @param cmprs_chn - number of the compressor channel (0..3)
        @param mode -       status generation mode:
                                  0: disable status generation,
                                  1: single status request,
                                  2: auto status, keep specified seq number,
                                  4: auto, inc sequence number 
        @param seq_number - 6-bit sequence number of the status message to be sent
        """

        self.x393_axi_tasks.program_status (
                             vrlg.CMPRS_GROUP_ADDR  + cmprs_chn * vrlg.CMPRS_BASE_INC,
                             vrlg.CMPRS_STATUS_CNTRL,
                             mode,
                             seq_num)# //MCONTR_PHY_STATUS_REG_ADDR=          'h0,
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
    def func_compressor_format (self,
                                num_macro_cols_m1,
                                num_macro_rows_m1,
                                left_margin):
        """
        @param num_macro_cols_m1 - number of macroblock colums minus 1
        @param num_macro_rows_m1 - number of macroblock rows minus 1
        @param left_margin - left margin of the first pixel (0..31) for 32-pixel wide colums in memory access
        @return combined compressor format data word
        """
        data = 0;
        data |=(num_macro_cols_m1 & ((1 << vrlg.CMPRS_FRMT_MBCM1_BITS) - 1))  << vrlg.CMPRS_FRMT_MBCM1
        data |=(num_macro_rows_m1 & ((1 << vrlg.CMPRS_FRMT_MBRM1_BITS) - 1))  << vrlg.CMPRS_FRMT_MBRM1
        data |=(left_margin &       ((1 << vrlg.CMPRS_FRMT_LMARG_BITS) - 1))  << vrlg.CMPRS_FRMT_LMARG
        return data
        
    def func_compressor_color_saturation (self,
                                colorsat_blue,
                                colorsat_red):
        """
        @param colorsat_blue - color saturation for blue (10 bits), 0x90 for 100%
        @param colorsat_red -  color saturation for red (10 bits), 0xb6 for 100%
        @return combined compressor format data word
        """
        data = 0;
        data |=(colorsat_blue & ((1 << vrlg.CMPRS_CSAT_CB_BITS) - 1))  << vrlg.CMPRS_CSAT_CB
        data |=(colorsat_red &  ((1 << vrlg.CMPRS_CSAT_CR_BITS) - 1))  << vrlg.CMPRS_CSAT_CR
        return data
    def func_compressor_control (self,
                                 run_mode =    None,
                                 qbank =       None,
                                 dc_sub =      None,
                                 cmode =       None,
                                 multi_frame = None,
                                 bayer =       None,
                                 focus_mode =  None):
        """
        Combine compressor control parameters into a single word. None value preserves old setting for the parameter
        @param run_mode -    0 - reset, 2 - run single from memory, 3 - run repetitive
        @param qbank -       quantization table page (0..15)
        @param dc_sub -      True - subtract DC before running DCT, False - no subtraction, convert as is,
        @param cmode -       color mode:
                                CMPRS_CBIT_CMODE_JPEG18 =          0 - color 4:2:0
                                CMPRS_CBIT_CMODE_MONO6 =           1 - mono 4:2:0 (6 blocks)
                                CMPRS_CBIT_CMODE_JP46 =            2 - jp4, 6 blocks, original
                                CMPRS_CBIT_CMODE_JP46DC =          3 - jp4, 6 blocks, dc -improved
                                CMPRS_CBIT_CMODE_JPEG20 =          4 - mono, 4 blocks (but still not actual monochrome JPEG as the blocks are scanned in 2x2 macroblocks)
                                CMPRS_CBIT_CMODE_JP4 =             5 - jp4,  4 blocks, dc-improved
                                CMPRS_CBIT_CMODE_JP4DC =           6 - jp4,  4 blocks, dc-improved
                                CMPRS_CBIT_CMODE_JP4DIFF =         7 - jp4,  4 blocks, differential
                                CMPRS_CBIT_CMODE_JP4DIFFHDR =      8 - jp4,  4 blocks, differential, hdr
                                CMPRS_CBIT_CMODE_JP4DIFFDIV2 =     9 - jp4,  4 blocks, differential, divide by 2
                                CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2 = 10 - jp4,  4 blocks, differential, hdr,divide by 2
                                CMPRS_CBIT_CMODE_MONO1 =          11 -  mono JPEG (not yet implemented)
                                CMPRS_CBIT_CMODE_MONO4 =          14 -  mono 4 blocks
        @param multi_frame -  False - single-frame buffer, True - multi-frame video memory buffer,
        @param bayer -        Bayer shift (0..3)
        @param focus_mode -   focus mode - how to combine image with "focus quality" in the result image 
        @return               combined data word
        """
        data = 0;
        if not run_mode is None:
            data |= (1 << vrlg.CMPRS_CBIT_RUN_BITS)
            data |= (run_mode & ((1 << vrlg.CMPRS_CBIT_RUN_BITS) - 1)) << (vrlg.CMPRS_CBIT_RUN - vrlg.CMPRS_CBIT_RUN_BITS)
                     
        if not qbank is None:
            data |= (1 << vrlg.CMPRS_CBIT_QBANK_BITS)
            data |= (qbank & ((1 << vrlg.CMPRS_CBIT_QBANK_BITS) - 1)) << (vrlg.CMPRS_CBIT_QBANK - vrlg.CMPRS_CBIT_QBANK_BITS)

        if not dc_sub is None:
            data |= (1 << vrlg.CMPRS_CBIT_DCSUB_BITS)
            data |= (dc_sub & ((1 << vrlg.CMPRS_CBIT_DCSUB_BITS) - 1)) << (vrlg.CMPRS_CBIT_DCSUB - vrlg.CMPRS_CBIT_DCSUB_BITS)

        if not cmode is None:
            data |= (1 << vrlg.CMPRS_CBIT_CMODE_BITS)
            data |= (cmode & ((1 << vrlg.CMPRS_CBIT_CMODE_BITS) - 1)) << (vrlg.CMPRS_CBIT_CMODE - vrlg.CMPRS_CBIT_CMODE_BITS)
                     
        if not multi_frame is None:
            data |= (1 << vrlg.CMPRS_CBIT_FRAMES_BITS)
            data |= (multi_frame & ((1 << vrlg.CMPRS_CBIT_FRAMES_BITS) - 1)) << (vrlg.CMPRS_CBIT_FRAMES - vrlg.CMPRS_CBIT_FRAMES_BITS)
                     
        if not bayer is None:
            data |= (1 << vrlg.CMPRS_CBIT_BAYER_BITS)
            data |= (bayer & ((1 << vrlg.CMPRS_CBIT_BAYER_BITS) - 1)) << (vrlg.CMPRS_CBIT_BAYER - vrlg.CMPRS_CBIT_BAYER_BITS)
                     
        if not focus_mode is None:
            data |= (1 << vrlg.CMPRS_CBIT_FOCUS_BITS)
            data |= (focus_mode & ((1 << vrlg.CMPRS_CBIT_FOCUS_BITS) - 1)) << (vrlg.CMPRS_CBIT_FOCUS - vrlg.CMPRS_CBIT_FOCUS_BITS)
        return data
    
    def compressor_format (self,
                           chn,
                           num_macro_cols_m1,
                           num_macro_rows_m1,
                           left_margin):
        """
        @param chn -               compressor channel number
        @param num_macro_cols_m1 - number of macroblock colums minus 1
        @param num_macro_rows_m1 - number of macroblock rows minus 1
        @param left_margin - left margin of the first pixel (0..31) for 32-pixel wide colums in memory access
        """
        data = self.func_compressor_format (num_macro_cols_m1 = num_macro_cols_m1,
                                            num_macro_rows_m1 = num_macro_rows_m1,
                                            left_margin =       left_margin)
        self.x393_axi_tasks.write_contol_register(vrlg.CMPRS_GROUP_ADDR +  chn * vrlg.CMPRS_BASE_INC + vrlg.CMPRS_FORMAT,
                                                  data)

    def compressor_color_saturation (self,
                                     chn,
                                     colorsat_blue,
                                     colorsat_red):
        """
        @param chn -           compressor channel number
        @param colorsat_blue - color saturation for blue (10 bits), 0x90 for 100%
        @param colorsat_red -  color saturation for red (10 bits), 0xb6 for 100%
        """
        data = self.func_compressor_color_saturation (colorsat_blue = colorsat_blue,
                                                      colorsat_red = colorsat_red)
        self.x393_axi_tasks.write_contol_register(vrlg.CMPRS_GROUP_ADDR +  chn * vrlg.CMPRS_BASE_INC + vrlg.CMPRS_COLOR_SATURATION,
                                                  data)

    def compressor_coring (self,
                           chn,
                           coring):
        """
        @param chn -    compressor channel number
        @param coring - coring value
        """
        data = coring & ((1 << vrlg.CMPRS_CORING_BITS) - 1)
        self.x393_axi_tasks.write_contol_register(vrlg.CMPRS_GROUP_ADDR +  chn * vrlg.CMPRS_BASE_INC + vrlg.CMPRS_CORING_MODE,
                                                  data)

    def compressor_control (self,
                            chn,
                            run_mode =    None,
                            qbank =       None,
                            dc_sub =      None,
                            cmode =       None,
                            multi_frame = None,
                            bayer =       None,
                            focus_mode =  None):
        """
        Combine compressor control parameters into a single word. None value preserves old setting for the parameter
        @param chn -           compressor channel number
        @param run_mode -    0 - reset, 2 - run single from memory, 3 - run repetitive
        @param qbank -       quantization table page (0..15)
        @param dc_sub -      True - subtract DC before running DCT, False - no subtraction, convert as is,
        @param cmode -       color mode:
                                CMPRS_CBIT_CMODE_JPEG18 =          0 - color 4:2:0
                                CMPRS_CBIT_CMODE_MONO6 =           1 - mono 4:2:0 (6 blocks)
                                CMPRS_CBIT_CMODE_JP46 =            2 - jp4, 6 blocks, original
                                CMPRS_CBIT_CMODE_JP46DC =          3 - jp4, 6 blocks, dc -improved
                                CMPRS_CBIT_CMODE_JPEG20 =          4 - mono, 4 blocks (but still not actual monochrome JPEG as the blocks are scanned in 2x2 macroblocks)
                                CMPRS_CBIT_CMODE_JP4 =             5 - jp4,  4 blocks, dc-improved
                                CMPRS_CBIT_CMODE_JP4DC =           6 - jp4,  4 blocks, dc-improved
                                CMPRS_CBIT_CMODE_JP4DIFF =         7 - jp4,  4 blocks, differential
                                CMPRS_CBIT_CMODE_JP4DIFFHDR =      8 - jp4,  4 blocks, differential, hdr
                                CMPRS_CBIT_CMODE_JP4DIFFDIV2 =     9 - jp4,  4 blocks, differential, divide by 2
                                CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2 = 10 - jp4,  4 blocks, differential, hdr,divide by 2
                                CMPRS_CBIT_CMODE_MONO1 =          11 -  mono JPEG (not yet implemented)
                                CMPRS_CBIT_CMODE_MONO4 =          14 -  mono 4 blocks
        @param multi_frame -  False - single-frame buffer, True - multi-frame video memory buffer,
        @param bayer -        Bayer shift (0..3)
        @param focus_mode -   focus mode - how to combine image with "focus quality" in the result image 
        """
        data = self.func_compressor_control(
                            run_mode =    run_mode,
                            qbank =       qbank,
                            dc_sub =      dc_sub,
                            cmode =       cmode,
                            multi_frame = multi_frame,
                            bayer =       bayer,
                            focus_mode =  focus_mode)
        self.x393_axi_tasks.write_contol_register(vrlg.CMPRS_GROUP_ADDR +  chn * vrlg.CMPRS_BASE_INC + vrlg.CMPRS_CONTROL_REG,
                                                  data)