// This is the entry_point for the encode function, and will make sure the result // sane. xyuv::frame encode_frame(const xyuv::yuv_image &yuva_in, const xyuv::format &format) { bool dimensions_match = yuva_in.image_w == format.image_w && yuva_in.image_h == format.image_h; // Short path. if (dimensions_match && yuva_in.siting == format.chroma_siting) { return internal_encode_frame(yuva_in, format); } // Otherwise we will need to do some conversion. const yuv_image *image = &yuva_in; yuv_image temp; if (!dimensions_match) { if (!is_444(image->siting.subsampling)) { temp = up_sample(*image); image = &temp; } temp = scale_yuv_image(*image, format.image_w, format.image_h); image = &temp; } if (!(image->siting == format.chroma_siting)) { if (image->siting.subsampling.macro_px_w > 1 || image->siting.subsampling.macro_px_h > 1) { temp = up_sample(*image); image = &temp; } // At this point *image is 444 if (format.chroma_siting.subsampling.macro_px_w > 1 || format.chroma_siting.subsampling.macro_px_h > 1) { temp = down_sample(*image, format.chroma_siting); image = &temp; } } return internal_encode_frame(*image, format); }
void rgb_image::from_yuv_image(const xyuv::yuv_image & image_in, const xyuv::conversion_matrix & conversion_matrix ) { const yuv_image * img = &image_in; try { if (!is_444(image_in.siting.subsampling)) { img = new yuv_image(up_sample(image_in)); } xyuv_from_yuv_image_444(*img, conversion_matrix); if (img != &image_in) { delete img; } } catch (...) { if (img != &image_in) { delete img; } throw; } }
static ssize_t up_read(FAR struct file *filep, FAR char *buffer, size_t len) { FAR struct inode *inode; FAR struct up_dev_s *priv; FAR struct touch_sample_s *report; struct up_sample_s sample; int ret; ivdbg("len=%d\n", len); DEBUGASSERT(filep); inode = filep->f_inode; DEBUGASSERT(inode && inode->i_private); priv = (FAR struct up_dev_s *)inode->i_private; /* Verify that the caller has provided a buffer large enough to receive * the touch data. */ if (len < SIZEOF_TOUCH_SAMPLE_S(1)) { /* We could provide logic to break up a touch report into segments and * handle smaller reads... but why? */ return -ENOSYS; } /* Get exclusive access to the driver data structure */ ret = sem_wait(&priv->devsem); if (ret < 0) { /* This should only happen if the wait was canceled by an signal */ DEBUGASSERT(errno == EINTR); return -EINTR; } /* Try to read sample data. */ ret = up_sample(priv, &sample); if (ret < 0) { /* Sample data is not available now. We would ave to wait to get * receive sample data. If the user has specified the O_NONBLOCK * option, then just return an error. */ if (filep->f_oflags & O_NONBLOCK) { ret = -EAGAIN; goto errout; } /* Wait for sample data */ ret = up_waitsample(priv, &sample); if (ret < 0) { /* We might have been awakened by a signal */ goto errout; } } /* In any event, we now have sampled touchscreen data that we can report * to the caller. */ report = (FAR struct touch_sample_s *)buffer; memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1)); report->npoints = 1; report->point[0].id = priv->id; report->point[0].x = sample.x; report->point[0].y = sample.y; report->point[0].h = 1; report->point[0].w = 1; report->point[0].pressure = 42; /* Report the appropriate flags */ if (sample.contact == CONTACT_UP) { /* Pen is now up */ report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID; } else if (sample.contact == CONTACT_DOWN) { /* First contact */ report->point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID | TOUCH_PRESSURE_VALID; } else /* if (sample->contact == CONTACT_MOVE) */ { /* Movement of the same contact */ report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID | TOUCH_PRESSURE_VALID; } ret = SIZEOF_TOUCH_SAMPLE_S(1); errout: ivdbg("Returning %d\n", ret); sem_post(&priv->devsem); return ret; }
static int up_waitsample(FAR struct up_dev_s *priv, FAR struct up_sample_s *sample) { irqstate_t flags; int ret; /* Interrupts me be disabled when this is called to (1) prevent posting * of semphores from interrupt handlers, and (2) to prevent sampled data * from changing until it has been reported. * * In addition, we will also disable pre-emption to prevent other threads * from getting control while we muck with the semaphores. */ sched_lock(); flags = irqsave(); /* Now release the semaphore that manages mutually exclusive access to * the device structure. This may cause other tasks to become ready to * run, but they cannot run yet because pre-emption is disabled. */ sem_post(&priv->devsem); /* Try to get the a sample... if we cannot, then wait on the semaphore * that is posted when new sample data is available. */ while (up_sample(priv, sample) < 0) { /* Wait for a change in the touchscreen state */ ivdbg("Waiting...\n"); priv->nwaiters++; ret = sem_wait(&priv->waitsem); priv->nwaiters--; ivdbg("Awakened...\n"); if (ret < 0) { /* If we are awakened by a signal, then we need to return * the failure now. */ DEBUGASSERT(errno == EINTR); ret = -EINTR; goto errout; } } /* Re-acquire the the semaphore that manages mutually exclusive access to * the device structure. We may have to wait here. But we have our sample. * Interrupts and pre-emption will be re-enabled while we wait. */ ret = sem_wait(&priv->devsem); errout: /* Then re-enable interrupts. We might get interrupt here and there * could be a new sample. But no new threads will run because we still * have pre-emption disabled. */ irqrestore(flags); /* Restore pre-emption. We might get suspended here but that is okay * because we already have our sample. Note: this means that if there * were two threads reading from the touchscreen for some reason, the data * might be read out of order. */ sched_unlock(); return ret; }