static void rpi_codec_decode(struct media_codec *mc, struct video_decoder *vd, struct media_queue *mq, struct media_buf *mb, int reqsize) { media_pipe_t *mp = vd->vd_mp; rpi_video_codec_t *rvc = mc->opaque; const void *data = mb->mb_data; size_t len = mb->mb_size; while(len > 0) { OMX_BUFFERHEADERTYPE *buf = omx_get_buffer(rvc->rvc_decoder); buf->nOffset = 0; buf->nFilledLen = MIN(len, buf->nAllocLen); memcpy(buf->pBuffer, data, buf->nFilledLen); buf->nFlags = 0; if(rvc->rvc_last_epoch != mb->mb_epoch) { buf->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY; rvc->rvc_last_epoch = mb->mb_epoch; } if(len <= buf->nAllocLen) buf->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; data += buf->nFilledLen; len -= buf->nFilledLen; if(mb->mb_pts != PTS_UNSET) buf->nTimeStamp = omx_ticks_from_s64(mb->mb_pts); else { buf->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; buf->nTimeStamp = omx_ticks_from_s64(0); } if(mb->mb_skip) buf->nFlags |= OMX_BUFFERFLAG_DECODEONLY; if(rvc->rvc_decoder->oc_port_settings_changed) { rvc->rvc_decoder->oc_port_settings_changed = 0; frame_info_t fi; memset(&fi, 0, sizeof(fi)); fi.fi_type = 'omx'; fi.fi_data[0] = (void *)rvc->rvc_decoder; mp->mp_video_frame_deliver(&fi, mp->mp_video_frame_opaque); } omxchk(OMX_EmptyThisBuffer(rvc->rvc_decoder->oc_handle, buf)); } frame_info_t fi; memset(&fi, 0, sizeof(fi)); fi.fi_drive_clock = mb->mb_drive_clock; fi.fi_epoch = mb->mb_epoch; fi.fi_pts = PTS_UNSET; fi.fi_delta = mb->mb_delta; fi.fi_type = 'omx'; mp->mp_video_frame_deliver(&fi, mp->mp_video_frame_opaque); }
void mmalil_buffer_header_to_omx(OMX_BUFFERHEADERTYPE *omx, MMAL_BUFFER_HEADER_T *mmal) { omx->pBuffer = mmal->data; omx->nAllocLen = mmal->alloc_size; omx->nFilledLen = mmal->length; omx->nOffset = mmal->offset; omx->nFlags = mmalil_buffer_flags_to_omx(mmal->flags); omx->nTimeStamp = omx_ticks_from_s64(mmal->pts); if (mmal->pts == MMAL_TIME_UNKNOWN) { omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; omx->nTimeStamp = omx_ticks_from_s64(0); } }