omv/img/jpeg.c understanding

I try to solve high resolution picture jpeg encoder. I need to confirm whether jpeg.c is support the requirement.

In jpeg_compress

bool jpeg_compress(image_t *src, image_t *dst, int quality, bool realloc)
{
int DCY=0, DCU=0, DCV=0;
_t0=read_cycle();

// JPEG buffer
jpeg_buf_t  jpeg_buf = {
    .idx =0,
    .buf = dst->pixels,
    .length = dst->bpp,
    .bitc = 0,
    .bitb = 0,
    .realloc = realloc,
    .overflow = false,
};

jpeg_buf_t jpeg_buf1 = {
.idx =0,
.buf = dst->pixels+1024*512,
.length = dst->bpp/2,
.bitc = 0,
.bitb = 0,
.realloc = realloc,
.overflow = false,
};

what the hardcode offset means: buf=dst->pixels+1024*512?

what the jpeg_buf1 is used for?

The following code is also strange

    switch (jpeg_subsample) {
        case JPEG_SUBSAMPLE_1x1: {
  		jpg_bpp2_init();
            DBG_TIME
  		dual_func=&jpg_bpp2_1x1;DBG_TIME
  		jpg_bpp2_1x1(0);DBG_TIME
  		//jpg_bpp2_1x1(1);DBG_TIME
  		while(dual_func){};DBG_TIME
  		jpg_bpp2_end(&jpeg_buf, &jpeg_buf1);DBG_TIME
            break;
        }

while(dual_func){} seems loop for ever.

typedef int (*dual_func_t)(int);
extern volatile dual_func_t dual_func;

Am I misunderstood?

dual_func is declared volatile, so it can change at any time through the intervention of another thread. So even if the dual_func function pointer is non-NULL upon entry into the while(dual_func){}; loop, it can become NULL and the loop can terminate.

I think the explanation is here in maixpy_main.c:

void core2_task(void* arg)
{
	while(1)
	{
		if(dual_func)
		{//corelock_lock(&lock);
			(*dual_func)(1);
			dual_func=0;
			//corelock_unlock(&lock);
		}
		
		//usleep(1);
	}
}

The dual_func function pointer is used to run a task on the second core. The while(dual_func){}; loop waits until the task on the second core has terminated.

1 Like

Your answer is very helpful. Thank you. I never thought the encodding process will use mutithread. So did ignore the volatile. (I think this may be copied from other code.)

It seems it encoder try to use multi-core to give the better performance.

I still have question

  		dual_func=&jpg_bpp2_1x1;DBG_TIME
  		jpg_bpp2_1x1(0);DBG_TIME
  		//jpg_bpp2_1x1(1);DBG_TIME
  		while(dual_func){};DBG_TIME

I think dual_fun(1) should be called after jpg_bpp2_1x1(0),

  		jpg_bpp2_1x1(0);DBG_TIME
  		dual_func=&jpg_bpp2_1x1;DBG_TIME
  		//jpg_bpp2_1x1(1);DBG_TIME
  		while(dual_func){};DBG_TIME

I think this is better. (It is answered in next post, my suggestion here is wrong.)

The code I feel has some potentional problem, the jpeg_buf1 is not always valid.

I try to understand the code, but not fully understand yet.

It seems the solution is consider the multi-core performance, it manully seperated the calculate task into two parts: one is for core 0, another is for core1. It is no strictly which one need to run first. My previous changing call position is no use, but lost the parallel computing. It should not change.

After parallel finished, the last setp: xxx_end, combine two results into one.

From the code, I could guss this. But I have not fully understant the detail .

The risk for the current algorithm is It assumed the 512k memory address is accessable. The default configure has two choices, 700K and 300K, and the reallocate will happen at any time, I think the problem will happen.

The jpeg.c code could not work in the OMV_MINIMUM envirnomentļ¼Œbecause of the 512k pointer offset is beyond the total 300K memory.

The jpeg.c is safty to work under 700k preallocate memory, because the maxium 640x480 resolution, the rgb565 will only take 600K for the rgb buffer, so the encode 700K size is safty to work. If for the high resulution (it is not suggested), there will be OOM first before the code could work.

The code is not correct only in the concept.