[MPlayer-dev-eng] [PATCH] Fix capture width/height selection in tvi_dshow
Reimar Döffinger
Reimar.Doeffinger at gmx.de
Sat Mar 2 11:03:46 CET 2013
On Sat, Mar 02, 2013 at 10:46:09AM +0700, Vladimir Voroshilov wrote:
> + case TVI_CONTROL_VID_SET_WIDTH_HEIGHT:
> + {
> + VIDEO_STREAM_CONFIG_CAPS *pCaps;
> + VIDEOINFOHEADER *Vhdr;
> + int width = ((int*)arg)[0];
> + int height = ((int*)arg)[1];
> + int i;
> + if (priv->state)
> + return TVI_CONTROL_FALSE;
> +
> + if(!priv->chains[0]->arpmt)
> + return TVI_CONTROL_FALSE;
> + /* Loop over all detected formats... */
> + for (i = 0; priv->chains[0]->arpmt[i]; i++) {
> + /* same FourCC as previously specified */
> + if (!check_video_format
> + (priv->chains[0]->arpmt[i], priv->fcc, width, height))
> + continue;
> + pCaps = priv->chains[0]->arStreamCaps[i];
> + if (!pCaps)
> + continue;
> +
> + /* requested width fits to min/max range */
> + if (width < pCaps->MinOutputSize.cx
> + || width > pCaps->MaxOutputSize.cx)
> + continue;
> +
> + /* requested height fits to min/max range */
> + if (height < pCaps->MinOutputSize.cy
> + || height > pCaps->MaxOutputSize.cy)
> + continue;
> +
> + /* switch format if found suitable one */
> + priv->chains[0]->nFormatUsed = i;
> + break;
> + }
I think the behaviour would be more consistent if this was a function
and also used from SET_WIDTH and SET_HEIGHT, in the way that
SET_WIDTH would call it with (new width, old height)
> + 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 (height < pCaps->MinOutputSize.cy
> + || height > pCaps->MaxOutputSize.cy)
> + return TVI_CONTROL_FALSE;
> +
> + if (width % pCaps->OutputGranularityX)
> + return TVI_CONTROL_FALSE;
> + if (height % pCaps->OutputGranularityY)
> + return TVI_CONTROL_FALSE;
> +
> + if (priv->chains[0]->pmt)
> + DeleteMediaType(priv->chains[0]->pmt);
> + priv->chains[0]->pmt =
> + CreateMediaType(priv->chains[0]->arpmt[priv->chains[0]->nFormatUsed]);
> + DisplayMediaType("VID_SET_WIDTH_HEIGHT", priv->chains[0]->pmt);
> +
> + 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;
> + 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->width = width;
> + priv->height = height;
You can probably even put all of this code into that function, and
thus avoid having things like the Min/Max size validation duplicated
between those different SET_ functions.
Or alternatively, if the SET_WIDTH and SET_HEIGHT are actually
not used at all any more after this change (I didn't double-check
how all this works) then just removing them might be an option, too.
Still, I am a fan of using lots of functions, they tend to make
the code much easier to understand.
More information about the MPlayer-dev-eng
mailing list