omap24xxvout.c
来自「omap3 linux 2.6 用nocc去除了冗余代码」· C语言 代码 · 共 2,498 行 · 第 1/5 页
C
2,498 行
omap24xxvout_default_crop (&vout->pix, &vout->fbuf, &cropcap->defrect); cropcap->pixelaspect.numerator = 1; cropcap->pixelaspect.denominator = 1; return 0; } default: return -EINVAL; } } case VIDIOC_G_CROP: { struct v4l2_crop *crop = (struct v4l2_crop *) arg; switch (crop->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT: { crop->c = vout->crop; return 0; } default: return -EINVAL; } } case VIDIOC_S_CROP: { struct v4l2_crop *crop = (struct v4l2_crop *) arg; if (vout->streaming) return -EBUSY; omap2_disp_get_dss(); /* get the framebuffer parameters */ if(vout->rotation == 90 || vout->rotation == 270){ omap2_disp_get_panel_size ( omap2_disp_get_output_dev (vout->vid), &(vout->fbuf.fmt.height), &(vout->fbuf.fmt.width)); } else { omap2_disp_get_panel_size ( omap2_disp_get_output_dev (vout->vid), &(vout->fbuf.fmt.width), &(vout->fbuf.fmt.height)); } omap2_disp_put_dss(); switch (crop->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT: { err = omap24xxvout_new_crop (&vout->pix, &vout->crop, &vout->win, &vout->fbuf, &crop->c); return err; } default: return -EINVAL; } } case VIDIOC_REQBUFS: { struct v4l2_requestbuffers *req = (struct v4l2_requestbuffers *) arg; struct videobuf_queue *q = &fh->vbq; unsigned int i, ret, num_buffers=0; struct videobuf_dmabuf *dmabuf=NULL; /* don't allow to buffer request for the linked layer */ if (vout->vid == vout_linked) { return -EINVAL; } if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || (req->count < 0)) { return -EINVAL; } /* if memory is not mmp or userptr return error */ if ((V4L2_MEMORY_MMAP != req->memory) && (V4L2_MEMORY_USERPTR != req->memory)) { return -EINVAL; } /* Cannot be requested when streaming is on */ if (vout->streaming) { return -EBUSY; } /* If buffers are already allocated free them */ if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) { if (vout->mmap_count) { return -EBUSY; } num_buffers = (vout->vid == OMAP2_VIDEO1) ? video1_numbuffers : video2_numbuffers; for(i = num_buffers;i < vout->buffer_allocated;i++) { dmabuf = videobuf_to_dma(q->bufs[i]); omap35xvout_free_buffer((u32)dmabuf->vmalloc, dmabuf->bus_addr, vout->buffer_size); vout->buf_virt_addr[i] = 0; vout->buf_phy_addr[i] = 0; } vout->buffer_allocated = num_buffers; videobuf_mmap_free(q); } else if(q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) { if(vout->buffer_allocated) { videobuf_mmap_free(q); for(i = 0 ; i < vout->buffer_allocated ; i ++){ if(q->bufs[i]) kfree(q->bufs[i]); q->bufs[i] = NULL; } vout->buffer_allocated = 0; } } fh->io_allowed = 1; /*store the memory type in data structure*/ vout->memory = req->memory; INIT_LIST_HEAD(&vout->dma_queue); /* call videobuf_reqbufs api */ ret = videobuf_reqbufs(q, req); if(ret < 0) { break; } vout->buffer_allocated = req->count; for(i = 0 ; i < req->count ; i ++) { dmabuf = videobuf_to_dma(q->bufs[i]); dmabuf->vmalloc = (void *)vout->buf_virt_addr[i]; dmabuf->bus_addr = (dma_addr_t)vout->buf_phy_addr[i]; dmabuf->sglen = 1; } return 0; } case VIDIOC_QUERYBUF: return videobuf_querybuf (&fh->vbq, arg); case VIDIOC_QBUF: { struct v4l2_buffer *buffer = (struct v4l2_buffer *) arg; struct videobuf_queue *q = &fh->vbq; struct omap24xxvout_device *dest; int output_dev = omap2_disp_get_output_dev(vout->vid); int streaming_on = STREAMING_IS_ON(), ret=0, rotation=-1; if(!fh->io_allowed) { return -EINVAL; } timeout = HZ / 5; timeout += jiffies; omap2_disp_get_tvlcd(&tvlcd_status); if (!streaming_on) omap2_disp_get_dss(); if (tvlcd_status.status == TVLCD_STOP) { if (tvlcd_status.ltype == vout->vid) { omap2_disp_disable_layer (vout->vid); vout->streaming = NULL; } else if (vout_linked != -1 && vout_linked != vout->vid){ omap2_disp_disable_layer ( (vout->vid == OMAP2_VIDEO1) ? OMAP2_VIDEO2 : OMAP2_VIDEO1); } while(omap2_disp_reg_sync_bit(output_dev ) && time_before(jiffies, timeout)) { if ((!in_interrupt()) && (!irqs_disabled())) { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); } else { udelay(10); } } if(vout->rotation == 90 || vout->rotation == 270){ omap2_disp_get_panel_size( omap2_disp_get_output_dev (vout->vid), &(vout->fbuf.fmt.height), &(vout->fbuf.fmt.width)); } else { omap2_disp_get_panel_size( omap2_disp_get_output_dev (vout->vid), &(vout->fbuf.fmt.width), &(vout->fbuf.fmt.height)); } /* set default crop and win */ omap24xxvout_new_format (&vout->pix, &vout->fbuf, &vout->crop, &vout->win); omap2_disp_set_output_dev(tvlcd_status.ltype, tvlcd_status.output_dev); omap2_disp_set_tvlcd(TVLCD_CONTINUE); if (!streaming_on) omap2_disp_put_dss(); omap2_disp_get_tvlcd(&tvlcd_status); } if (tvlcd_status.status == TVLCD_CONTINUE) { if (tvlcd_status.ltype == vout->vid) { rotation = (vout->rotation > 0) ? vout->rotation:-1; vout->streaming = fh; omap2_disp_config_vlayer(vout->vid, &vout->pix, &vout->crop, &vout->win, rotation, vout->mirror); } else if (vout_linked != -1 && vout_linked != vout->vid) { dest = (vout_linked == OMAP2_VIDEO1) ? saved_v1out : saved_v2out; rotation = (dest->rotation > 0) ? dest->rotation:-1; omap2_disp_config_vlayer (dest->vid, &dest->pix, &dest-> crop, &dest->win, rotation, dest->mirror); } omap2_disp_set_tvlcd(0); } /* don't allow to queue buffer for the linked layer */ if (vout->vid == vout_linked) { if (!streaming_on) omap2_disp_put_dss(); return -EINVAL; } if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) || (buffer->index >= vout->buffer_allocated) || (q->bufs[buffer->index]->memory != buffer->memory)) { if (!streaming_on) omap2_disp_put_dss(); return -EINVAL; } if(V4L2_MEMORY_USERPTR == buffer->memory) { if((buffer->length < vout->pix.sizeimage) || (0 == buffer->m.userptr)) { if (!streaming_on) omap2_disp_put_dss(); return -EINVAL; } } if (vout->rotation > 0 && vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) { if (!streaming_on) omap2_disp_put_dss(); return -EINVAL; } ret = videobuf_qbuf(q, buffer); if (!streaming_on) omap2_disp_put_dss(); return ret; } case VIDIOC_DQBUF: { struct videobuf_queue *q = &fh->vbq; int ret = 0; /* don't allow to dequeue buffer for the linked layer */ if (vout->vid == vout_linked) return -EINVAL; if(!vout->streaming || !fh->io_allowed) return -EINVAL; if (file->f_flags & O_NONBLOCK) /* Call videobuf_dqbuf for non blocking mode */ ret = videobuf_dqbuf(q, (struct v4l2_buffer *)arg, 1); else /* Call videobuf_dqbuf for blocking mode */ ret = videobuf_dqbuf(q, (struct v4l2_buffer *)arg, 0); break; } case VIDIOC_STREAMON: { struct videobuf_queue *q = &fh->vbq; struct omap24xxvout_device *dest; int ret=0, rotation=-1; u32 addr=0; if(!fh->io_allowed) { return -EINVAL; } if(vout->streaming) return -EBUSY; ret = videobuf_streamon(q); if(ret < 0) { break; } if(list_empty(&vout->dma_queue)) { ret = -EIO; return ret; } /* Get the next frame from the buffer queue */ vout->nextFrm = vout->curFrm = list_entry(vout->dma_queue.next, struct videobuf_buffer, queue); /* Remove buffer from the buffer queue */ list_del(&vout->curFrm->queue); /* Mark state of the current frame to active */ vout->curFrm->state = VIDEOBUF_ACTIVE; /* Initialize field_id and started member */ vout->field_id = 0; /* set flag here. Next QBUF will start DMA */ vout->streaming = fh; vout->first_int = 1; omap2_disp_get_dss(); rotation = (vout->rotation > 0)?vout->rotation:-1; omap2_disp_config_vlayer (vout->vid, &vout->pix, &vout->crop, &vout->win, rotation, vout->mirror); /* Configure also linked layer */ if (vout_linked != -1 && vout_linked != vout->vid){ rotation = (vout->rotation > 0)?vout->rotation:-1; dest = (vout_linked == OMAP2_VIDEO1) ? saved_v1out : saved_v2out; omap2_disp_config_vlayer (dest->vid, &dest->pix, &dest->crop, &dest->win, rotation, dest->mirror); } omap35xvout_calculate_offset(vout); addr = (unsigned long)vout->queued_buf_addr[vout->curFrm->i] + vout->cropped_offset; omap2_disp_set_addr(vout->vid, addr, addr, addr+vout->tv_field1_offset); omap2_disp_start_video_layer(vout->vid); return 0; } case VIDIOC_STREAMOFF: { struct videobuf_queue *q = &fh->vbq; int ret = 0; if(!fh->io_allowed) { return -EINVAL; } if(!vout->streaming) { return -EINVAL; } if (vout->streaming == fh){ omap2_disp_disable_layer (vout->vid); vout->streaming = NULL; /* stop the slave layer */ if (vout_linked != -1 && vout_linked != vout->vid){ omap2_disp_disable_layer ( (vout->vid == OMAP2_VIDEO1) ? OMAP2_VIDEO2 : OMAP2_VIDEO1); } omap2_disp_put_dss(); ret = videobuf_streamoff(q); return 0; } return -EINVAL; } case VIDIOC_S_OMAP2_LINK: { int *link = arg; spin_lock (&vout_link_lock); if ((*link == 0) && (vout_linked == vout->vid)) vout_linked = -1; omap2_disp_get_dss(); if ((*link == 1) && (vout_linked == -1 || vout_linked == vout->vid)){ vout_linked = vout->vid; if (vout_linked == OMAP2_VIDEO2){ /* sync V2 to V1 for img and crop */ omap24xxvout_sync (saved_v2out, saved_v1out); } else { /* sync V1 to V2 */ omap24xxvout_sync (saved_v1out, saved_v2out); } } omap2_disp_put_dss(); spin_unlock (&vout_link_lock); return 0; } case VIDIOC_G_OMAP2_LINK: { int *link = arg; spin_lock (&vout_link_lock); if (vout_linked == vout->vid) *link = 1; else *link = 0; spin_unlock (&vout_link_lock); return 0; } case VIDIOC_S_OMAP2_MIRROR: { int *mirror = arg; if ((*mirror == 0) && (vout->mirror == 1)) { vout->mirror = 0; return 0; } else if ((*mirror == 1) && (vout->mirror == 0)) { vout->mirror = 1; return 0; } return -EINVAL; } case VIDIOC_G_OMAP2_MIRROR: { int *mirror = arg; *mirror = vout->mirror; return 0; } case VIDIOC_S_OMAP2_ROTATION: { int *rotation = arg; if ((*rotation == 0) || (*rotation == 90) || (*rotation == 180) || (*rotation == 270) || (*rotation == -1)) { vout->rotation = (*rotation == 90) ? 270 : (*rotation == 270) ? 90 : *rotation; rotation_support = vout->rotation; return 0; } else { return -EINVAL; } } case VIDIOC_G_OMAP2_ROTATION: { int *rotation = arg; *rotation = (vout->rotation == 90) ? 270 : (vout->rotation == 270) ? 90 : vout->rotation; return 0; } case VIDIOC_S_OMAP2_COLORKEY: { struct omap24xxvout_colorkey *colorkey = (struct omap24xxvout_colorkey *) arg; if ((colorkey->output_dev != OMAP2_OUTPUT_LCD && colorkey->output_dev != OMAP2_OUTPUT_TV) || (colorkey->key_type != OMAP2_GFX_DESTINATION && colorkey->key_type != OMAP2_VIDEO_SOURCE)) return -EINVAL; omap2_disp_get_dss(); omap2_disp_set_colorkey (colorkey->output_dev, colorkey->key_type, colorkey->key_val); omap2_disp_put_dss(); return 0; } case VIDIOC_G_OMAP2_COLORKEY: { struct omap24xxvout_colorkey *colorkey =
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?