From 7d4bf1f857d0ec6e3a3dc4e08d46e2c8d3d94320 Mon Sep 17 00:00:00 2001 From: Vladimir Voroshilov Date: Fri, 3 May 2013 15:27:20 +0700 Subject: [PATCH 3/3] implement single routine for setting width/height --- stream/tvi_dshow.c | 121 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 53 deletions(-) diff --git a/stream/tvi_dshow.c b/stream/tvi_dshow.c index ba00862..b2b38f5 100644 --- a/stream/tvi_dshow.c +++ b/stream/tvi_dshow.c @@ -3152,6 +3152,65 @@ static tvi_handle_t *tvi_init_dshow(tv_param_t* tv_param) } /** + * \brief search supported formats for given width/height + * + * \param priv driver's private data structure + * \param fcc FourCC (compression) + * \param width new picture width + * \param height new picture height + * + * \return index of format in supported formats array, or -1 if + * nothing suitable found. + */ +static int find_suitable_format(priv_t *priv, int fcc, int width, int height) +{ + int i; + + if(!priv->chains[0]->arpmt) + return -1; + for (i = 0; priv->chains[0]->arpmt[i]; i++) { + if (!check_video_format(priv->chains[0]->arpmt[i], fcc)) + continue; + if (!check_picture_width(priv->chains[0]->arStreamCaps[i], width)) + continue; + if (!check_picture_height(priv->chains[0]->arStreamCaps[i], height)) + continue; + return i; + } + return -1; +} +/** + * \brief set new width/height + * + * \param priv driver's private data structure + * \param width new width + * \param height new height + * + * \return TVI_CONTROL_TRUE on success, TVI_CONTROL_FALSE - otherwise + */ +static int set_width_height(priv_t *priv, int width, int height) +{ + int idx; + + if (priv->state) + return TVI_CONTROL_FALSE; + + idx = find_suitable_format(priv, priv->fcc, width, height); + if (idx < 0) + return TVI_CONTROL_FALSE; + + priv->chains[0]->nFormatUsed = idx; + priv->width = width; + priv->height = height; + + if (priv->chains[0]->pmt) + DeleteMediaType(priv->chains[0]->pmt); + priv->chains[0]->pmt = create_video_format(priv->fcc, priv->width, priv->height, 0); + + return TVI_CONTROL_TRUE; +} + +/** * \brief driver's ioctl handler * * \param priv driver's private data structure @@ -3253,35 +3312,18 @@ static int control(priv_t * priv, int cmd, void *arg) } else return TVI_CONTROL_FALSE; } + case TVI_CONTROL_VID_SET_WIDTH_HEIGHT: + { + int width = ((int*)arg)[0]; + int height = ((int*)arg)[1]; + + return set_width_height(priv, width, height); + } case TVI_CONTROL_VID_SET_WIDTH: { - VIDEO_STREAM_CONFIG_CAPS *pCaps; - VIDEOINFOHEADER *Vhdr; int width = *(int *) arg; - if (priv->state) - return TVI_CONTROL_FALSE; - - pCaps = priv->chains[0]->arStreamCaps[priv->chains[0]->nFormatUsed]; - if (!pCaps) - return TVI_CONTROL_FALSE; - if (width < pCaps->MinOutputSize.cx - || width > pCaps->MaxOutputSize.cx) - return TVI_CONTROL_FALSE; - if (width % pCaps->OutputGranularityX) - return TVI_CONTROL_FALSE; - - if (!priv->chains[0]->pmt || !priv->chains[0]->pmt->pbFormat) - return TVI_CONTROL_FALSE; - Vhdr = (VIDEOINFOHEADER *) priv->chains[0]->pmt->pbFormat; - Vhdr->bmiHeader.biWidth = width; - priv->chains[0]->pmt->lSampleSize = Vhdr->bmiHeader.biSizeImage = - labs(Vhdr->bmiHeader.biBitCount * Vhdr->bmiHeader.biWidth * - Vhdr->bmiHeader.biHeight) >> 3; - - priv->width = width; - - return TVI_CONTROL_TRUE; + return set_width_height(priv, width, priv->height); } case TVI_CONTROL_VID_GET_WIDTH: { @@ -3300,36 +3342,9 @@ static int control(priv_t * priv, int cmd, void *arg) } case TVI_CONTROL_VID_SET_HEIGHT: { - VIDEO_STREAM_CONFIG_CAPS *pCaps; - VIDEOINFOHEADER *Vhdr; int height = *(int *) arg; - if (priv->state) - return TVI_CONTROL_FALSE; - - pCaps = priv->chains[0]->arStreamCaps[priv->chains[0]->nFormatUsed]; - if (!pCaps) - return TVI_CONTROL_FALSE; - if (height < pCaps->MinOutputSize.cy - || height > pCaps->MaxOutputSize.cy) - return TVI_CONTROL_FALSE; - - if (height % pCaps->OutputGranularityY) - return TVI_CONTROL_FALSE; - - if (!priv->chains[0]->pmt || !priv->chains[0]->pmt->pbFormat) - return TVI_CONTROL_FALSE; - Vhdr = (VIDEOINFOHEADER *) priv->chains[0]->pmt->pbFormat; - if (Vhdr->bmiHeader.biHeight < 0) - Vhdr->bmiHeader.biHeight = -height; - else - Vhdr->bmiHeader.biHeight = height; - priv->chains[0]->pmt->lSampleSize = Vhdr->bmiHeader.biSizeImage = - labs(Vhdr->bmiHeader.biBitCount * Vhdr->bmiHeader.biWidth * - Vhdr->bmiHeader.biHeight) >> 3; - - priv->height = height; - return TVI_CONTROL_TRUE; + return set_width_height(priv, priv->width, height); } case TVI_CONTROL_VID_GET_HEIGHT: { -- 1.8.0.msysgit.0