static pixmap_t * rpi_pixmap_decode(pixmap_t *pm, const image_meta_t *im, char *errbuf, size_t errlen) { if(pm->pm_type != PIXMAP_JPEG) return NULL; #ifdef TIMING int64_t ts = showtime_get_ts(), ts2; #endif rpi_pixmap_decoder_t *rpd = pixmap_decoder_create(OMX_IMAGE_CodingJPEG); if(rpd == NULL) return NULL; rpd->rpd_im = im; #ifdef NOCOPY #error check rpd->rpd_decoder->oc_stream_corrupt OMX_PARAM_PORTDEFINITIONTYPE portdef; memset(&portdef, 0, sizeof(portdef)); portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion.nVersion = OMX_VERSION; portdef.nPortIndex = rpd->rpd_decoder->oc_inport; omxchk(OMX_GetParameter(rpd->rpd_decoder->oc_handle, OMX_IndexParamPortDefinition, &portdef)); omx_send_command(rpd->rpd_decoder, OMX_CommandPortEnable, rpd->rpd_decoder->oc_inport, NULL, 0); OMX_BUFFERHEADERTYPE *buf; for(int i = 0; i < portdef.nBufferCountActual; i++) { omxchk(OMX_UseBuffer(rpd->rpd_decoder->oc_handle, &buf, rpd->rpd_decoder->oc_inport, NULL, pm->pm_size, pm->pm_data)); } // Waits for the OMX_CommandPortEnable command omx_wait_command(rpd->rpd_decoder); omx_set_state(rpd->rpd_decoder, OMX_StateExecuting); CHECKPOINT("Initialized"); buf->nOffset = 0; buf->nFilledLen = pm->pm_size; buf->nFlags |= OMX_BUFFERFLAG_EOS; rpd->rpd_decoder->oc_inflight_buffers++; omxchk(OMX_EmptyThisBuffer(rpd->rpd_decoder->oc_handle, buf)); hts_mutex_lock(&rpd->rpd_mtx); while(rpd->rpd_change == 0) hts_cond_wait(&rpd->rpd_cond, &rpd->rpd_mtx); hts_mutex_unlock(&rpd->rpd_mtx); CHECKPOINT("Setup tunnel"); setup_tunnel(rpd); #else const void *data = pm->pm_data; size_t len = pm->pm_size; hts_mutex_lock(&rpd->rpd_mtx); while(len > 0) { OMX_BUFFERHEADERTYPE *buf; if(rpd->rpd_decoder->oc_stream_corrupt) break; if(rpd->rpd_change == 1) { rpd->rpd_change = 2; hts_mutex_unlock(&rpd->rpd_mtx); setup_tunnel(rpd); hts_mutex_lock(&rpd->rpd_mtx); continue; } if(rpd->rpd_decoder->oc_avail == NULL) { hts_cond_wait(&rpd->rpd_cond, &rpd->rpd_mtx); continue; } buf = rpd->rpd_decoder->oc_avail; rpd->rpd_decoder->oc_avail = buf->pAppPrivate; rpd->rpd_decoder->oc_inflight_buffers++; hts_mutex_unlock(&rpd->rpd_mtx); buf->nOffset = 0; buf->nFilledLen = MIN(len, buf->nAllocLen); memcpy(buf->pBuffer, data, buf->nFilledLen); buf->nFlags = 0; if(len <= buf->nAllocLen) buf->nFlags |= OMX_BUFFERFLAG_EOS; data += buf->nFilledLen; len -= buf->nFilledLen; omxchk(OMX_EmptyThisBuffer(rpd->rpd_decoder->oc_handle, buf)); hts_mutex_lock(&rpd->rpd_mtx); } if(rpd->rpd_decoder->oc_stream_corrupt) { hts_mutex_unlock(&rpd->rpd_mtx); goto err; } if(rpd->rpd_change != 2) { while(rpd->rpd_change == 0 && !rpd->rpd_decoder->oc_stream_corrupt) hts_cond_wait(&rpd->rpd_cond, &rpd->rpd_mtx); hts_mutex_unlock(&rpd->rpd_mtx); if(rpd->rpd_decoder->oc_stream_corrupt) goto err; setup_tunnel(rpd); } else { hts_mutex_unlock(&rpd->rpd_mtx); } #endif omx_wait_fill_buffer(rpd->rpd_resizer, rpd->rpd_buf); CHECKPOINT("Got buffer"); err: omx_flush_port(rpd->rpd_decoder, rpd->rpd_decoder->oc_inport); omx_flush_port(rpd->rpd_decoder, rpd->rpd_decoder->oc_outport); omx_flush_port(rpd->rpd_resizer, rpd->rpd_resizer->oc_inport); omx_flush_port(rpd->rpd_resizer, rpd->rpd_resizer->oc_outport); if(rpd->rpd_tunnel != NULL) { omx_tunnel_destroy(rpd->rpd_tunnel); rpd->rpd_tunnel = NULL; } omx_set_state(rpd->rpd_decoder, OMX_StateIdle); omx_set_state(rpd->rpd_resizer, OMX_StateIdle); if(rpd->rpd_buf != NULL) { omxchk(OMX_FreeBuffer(rpd->rpd_resizer->oc_handle, rpd->rpd_resizer->oc_outport, rpd->rpd_buf)); } omx_release_buffers(rpd->rpd_decoder, rpd->rpd_decoder->oc_inport); omx_set_state(rpd->rpd_resizer, OMX_StateLoaded); omx_set_state(rpd->rpd_decoder, OMX_StateLoaded); omx_component_destroy(rpd->rpd_resizer); omx_component_destroy(rpd->rpd_decoder); hts_cond_destroy(&rpd->rpd_cond); hts_mutex_destroy(&rpd->rpd_mtx); pixmap_t *out = rpd->rpd_pm; if(out) { pixmap_release(pm); } else { snprintf(errbuf, errlen, "Load error"); } free(rpd); CHECKPOINT("All done"); return out; }
void attach_ue(MME &mme) { recv_req_from_ue(mme); authenticate_ue(mme); setup_tunnel(mme); }