void CSTmV29IFrames::UpdateFrame(void) { stm_meta_data_t *m; if(!m_pCurrentMode) return; DEBUGF2(4,("%s\n",__PRETTY_FUNCTION__)); if(m_pGamutQueue && ((m = m_pGamutQueue->Pop()) != 0)) { stm_hdmi_info_frame_t *i = (stm_hdmi_info_frame_t*)&m->data[0]; WriteInfoFrameHelper(0,i); /* * Note: the hardware slots are numbered from 1 not zero. */ m_ulConfig &= ~STM_HDMI_IFRAME_CFG_DI_n(STM_HDMI_IFRAME_MASK,1); m_ulConfig |= STM_HDMI_IFRAME_CFG_DI_n(STM_HDMI_IFRAME_FIELD,1); stm_meta_data_release(m); } /* * Color gamut and ISRC packets should be mutually exclusive, if they are * both present then the following call will overwrite the gamut data we * have just set. */ CSTmIFrameManager::UpdateFrame(); }
void CSTmV29IFrames::ProcessInfoFrameComplete(ULONG interruptStatus) { stm_meta_data_t *m; /* * If we got a completion interrupt after being stopped, ignore it */ if(!m_pCurrentMode) return; /* * If the first slot isn't setup to update each field we haven't started any * gamut packets, so nothing more to do. */ if((m_ulConfig & STM_HDMI_IFRAME_MASK) != STM_HDMI_IFRAME_FIELD) return; if(m_pGamutQueue && ((m = m_pGamutQueue->Pop()) != 0)) { stm_hdmi_info_frame_t *i = (stm_hdmi_info_frame_t*)&m->data[0]; WriteInfoFrameHelper(0,i); stm_meta_data_release(m); } }
static int stmfb_set_picture_configuration(struct stmfbio_picture_configuration *cfg, struct stmfb_info *i) { stm_meta_data_result_t res; stm_meta_data_t *metadata; stm_picture_format_info_t *pic_info; unsigned long flags; int ret = 0; if((cfg->flags & STMFBIO_PICTURE_FLAGS_PICUTRE_ASPECT) && (cfg->picture_aspect > STMFBIO_PIC_PICTURE_ASPECT_16_9)) return -EINVAL; if((cfg->flags & STMFBIO_PICTURE_FLAGS_VIDEO_ASPECT) && (cfg->video_aspect > STMFBIO_PIC_VIDEO_ASPECT_GT_16_9)) return -EINVAL; if((cfg->flags & STMFBIO_PICTURE_FLAGS_LETTERBOX) && (cfg->letterbox_style > STMFBIO_PIC_LETTERBOX_SAP_4_3)) return -EINVAL; if((cfg->flags & STMFBIO_PICTURE_FLAGS_RESCALE_INFO) && (cfg->picture_rescale > STMFBIO_PIC_RESCALE_BOTH)) return -EINVAL; if((metadata = kzalloc(sizeof(stm_meta_data_t)+sizeof(stm_picture_format_info_t),GFP_KERNEL)) == 0) return -ENOMEM; metadata->size = sizeof(stm_meta_data_t)+sizeof(stm_picture_format_info_t); metadata->type = STM_METADATA_TYPE_PICTURE_INFO; /* * We need to hold a reference for the metadata as we need to queue * the same thing twice (to analogue and HDMI outputs) and need to ensure we * do not get any race conditions in the lifetime of the object. We use the * metadata addref/release internal helpers to manage this. We must use * the release under interrupt lock once a queue has been successful to * ensure it is atomic with the VTG interrupt processing, but we actually do * this all the time to make the point and stop the code from * breaking in future changes. */ spin_lock_irqsave(&i->framebufferSpinLock,flags); stm_meta_data_addref(metadata); spin_unlock_irqrestore(&i->framebufferSpinLock,flags); metadata->release = (void(*)(struct stm_meta_data_s*))kfree; metadata->presentationTime = ((TIME64)cfg->timestamp.tv_sec * USEC_PER_SEC) + (TIME64)cfg->timestamp.tv_usec; pic_info = (stm_picture_format_info_t*)&metadata->data[0]; pic_info->flags = cfg->flags; pic_info->pictureAspect = (stm_wss_t)cfg->picture_aspect; pic_info->videoAspect = (stm_wss_t)cfg->video_aspect; pic_info->letterboxStyle = (stm_letterbox_t)cfg->letterbox_style; pic_info->pictureRescale = (stm_picture_rescale_t)cfg->picture_rescale; pic_info->barEnable = cfg->bar_enable; pic_info->topEndLine = cfg->top_bar_end; pic_info->bottomStartLine = cfg->bottom_bar_start; pic_info->leftEndPixel = cfg->left_bar_end; pic_info->rightStartPixel = cfg->right_bar_start; if(stm_display_output_queue_metadata(i->pFBMainOutput, metadata, &res)<0) { ret = signal_pending(current)?-EINTR:-EIO; goto exit; } /* * Set first stab at the wanted return value, this is likely to be revised * below. */ ret = stmfb_convert_metadata_result_to_errno(res); if(i->hdmi == NULL) { /* * Display pipeline has no HDMI transmitter so just return this result. */ goto exit; } switch(res) { case STM_METADATA_RES_OK: case STM_METADATA_RES_QUEUE_UNAVAILABLE: /* * If the DENC isn't in use the queue will not be available, * but that is fine we can continue to HDMI. */ break; default: goto exit; } if(mutex_lock_interruptible(&i->hdmi->lock)) { ret = -EINTR; goto exit; } /* * DVI or undetermined sink does not have InfoFrames. */ if(i->hdmi->edid_info.display_type != STM_DISPLAY_HDMI) goto mutex_exit; if((i->hdmi->status != STM_DISPLAY_CONNECTED) && (metadata->presentationTime == 0LL)) { /* * This is a slight of hand for the usual case that a change * is required immediately but the HDMI output is currently * stopped and will not process its metadata queues. Flush the queue * because we know this request will be the valid data as soon * as the HDMI output is started again. */ stm_display_output_flush_metadata(i->hdmi->hdmi_output,STM_METADATA_TYPE_PICTURE_INFO); } if(stm_display_output_queue_metadata(i->hdmi->hdmi_output, metadata, &res)<0) { ret = signal_pending(current)?-EINTR:-EIO; goto mutex_exit; } ret = stmfb_convert_metadata_result_to_errno(res); mutex_exit: mutex_unlock(&i->hdmi->lock); exit: spin_lock_irqsave(&i->framebufferSpinLock,flags); stm_meta_data_release(metadata); spin_unlock_irqrestore(&i->framebufferSpinLock,flags); return ret; }