Mercurial > mplayer.hg
comparison stream/tvi_dshow.c @ 25063:29260745e4fa
Pass all available formats to chain building routine and
establish connection with first of available formats.
This will make further format negotiation patch slightly
simpler.
To avoid pins connection error due to unsuported format
at top of the list, put requested video format to the
top of list. This will also useful with upcoming patch -
negotiation will be started from requested format.
author | voroshil |
---|---|
date | Sun, 18 Nov 2007 10:51:22 +0000 |
parents | 1f0eb7aa3206 |
children | f9a966f36dae |
comparison
equal
deleted
inserted
replaced
25062:25ee4d06a2df | 25063:29260745e4fa |
---|---|
1301 * | 1301 * |
1302 * \note routine does not frees memory, allocated for grabber_rinbuffer_s structure | 1302 * \note routine does not frees memory, allocated for grabber_rinbuffer_s structure |
1303 */ | 1303 */ |
1304 static HRESULT build_sub_graph(priv_t * priv, IBaseFilter * pCaptureFilter, | 1304 static HRESULT build_sub_graph(priv_t * priv, IBaseFilter * pCaptureFilter, |
1305 grabber_ringbuffer_t * pbuf, | 1305 grabber_ringbuffer_t * pbuf, |
1306 AM_MEDIA_TYPE * pmt, const GUID* ppin_category) | 1306 AM_MEDIA_TYPE ** arpmt, |
1307 AM_MEDIA_TYPE* pmt, const GUID* ppin_category) | |
1307 { | 1308 { |
1308 HRESULT hr; | 1309 HRESULT hr; |
1309 | 1310 int nFormatProbed = 0; |
1310 AM_MEDIA_TYPE conn_mt; //Media type of established connection | |
1311 | 1311 |
1312 IPin *pSGIn; | 1312 IPin *pSGIn; |
1313 IPin *pSGOut; | 1313 IPin *pSGOut; |
1314 IPin *pNRIn=NULL; | 1314 IPin *pNRIn=NULL; |
1315 IPin *pCapturePin; | 1315 IPin *pCapturePin; |
1318 IBaseFilter *pSGF = NULL; | 1318 IBaseFilter *pSGF = NULL; |
1319 | 1319 |
1320 ISampleGrabber *pSG = NULL; | 1320 ISampleGrabber *pSG = NULL; |
1321 | 1321 |
1322 hr=S_OK; | 1322 hr=S_OK; |
1323 CopyMediaType(&conn_mt, pmt); | 1323 |
1324 //No supported formats | |
1325 if(!arpmt[0]) | |
1326 return E_FAIL; | |
1327 | |
1324 do{ | 1328 do{ |
1325 hr = OLE_CALL_ARGS(priv->pBuilder, FindPin, | 1329 hr = OLE_CALL_ARGS(priv->pBuilder, FindPin, |
1326 (IUnknown *) pCaptureFilter, | 1330 (IUnknown *) pCaptureFilter, |
1327 PINDIR_OUTPUT, ppin_category, | 1331 PINDIR_OUTPUT, ppin_category, |
1328 &(pmt->majortype), FALSE, 0, &pCapturePin); | 1332 &(arpmt[nFormatProbed]->majortype), FALSE, 0, &pCapturePin); |
1329 if(FAILED(hr)){ | 1333 if(FAILED(hr)){ |
1330 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: FindPin(pCapturePin) call failed. Error:0x%x\n", (unsigned int)hr); | 1334 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: FindPin(pCapturePin) call failed. Error:0x%x\n", (unsigned int)hr); |
1331 break; | 1335 break; |
1332 } | 1336 } |
1333 /* Addinf SampleGrabber filter for video stream */ | 1337 /* Addinf SampleGrabber filter for video stream */ |
1363 hr = OLE_QUERYINTERFACE(pSGF, IID_ISampleGrabber, pSG); | 1367 hr = OLE_QUERYINTERFACE(pSGF, IID_ISampleGrabber, pSG); |
1364 if(FAILED(hr)){ | 1368 if(FAILED(hr)){ |
1365 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: QueryInterface(IID_ISampleGrabber) call failed. Error:0x%x\n", (unsigned int)hr); | 1369 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: QueryInterface(IID_ISampleGrabber) call failed. Error:0x%x\n", (unsigned int)hr); |
1366 break; | 1370 break; |
1367 } | 1371 } |
1368 hr = OLE_CALL_ARGS(pSG, SetMediaType, pmt); //set desired mediatype | 1372 hr = OLE_CALL_ARGS(pSG, SetMediaType, arpmt[nFormatProbed]); //set desired mediatype |
1369 if(FAILED(hr)){ | 1373 if(FAILED(hr)){ |
1370 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: SetMediaType(pSG) call failed. Error:0x%x\n", (unsigned int)hr); | 1374 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: SetMediaType(pSG) call failed. Error:0x%x\n", (unsigned int)hr); |
1371 break; | 1375 break; |
1372 } | 1376 } |
1373 // hr = OLE_CALL_ARGS(pSG, SetCallback, (ISampleGrabberCB *) pCSGCB, 1); //we want to receive copy of sample's data | 1377 // hr = OLE_CALL_ARGS(pSG, SetCallback, (ISampleGrabberCB *) pCSGCB, 1); //we want to receive copy of sample's data |
1387 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: SetBufferSamples(pSG) call failed. Error:0x%x\n", (unsigned int)hr); | 1391 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: SetBufferSamples(pSG) call failed. Error:0x%x\n", (unsigned int)hr); |
1388 break; | 1392 break; |
1389 } | 1393 } |
1390 OLE_RELEASE_SAFE(pSG); | 1394 OLE_RELEASE_SAFE(pSG); |
1391 | 1395 |
1392 if(priv->tv_param->normalize_audio_chunks && !memcmp(&(pmt->majortype),&(MEDIATYPE_Audio),16)){ | 1396 if(priv->tv_param->normalize_audio_chunks && !memcmp(&(arpmt[nFormatProbed]->majortype),&(MEDIATYPE_Audio),16)){ |
1393 set_buffer_preference(20,(WAVEFORMATEX*)(pmt->pbFormat),pCapturePin,pSGIn); | 1397 set_buffer_preference(20,(WAVEFORMATEX*)(arpmt[nFormatProbed]->pbFormat),pCapturePin,pSGIn); |
1394 } | 1398 } |
1395 | 1399 |
1396 /* connecting filters together: VideoCapture --> SampleGrabber */ | 1400 /* connecting filters together: VideoCapture --> SampleGrabber */ |
1397 hr = OLE_CALL_ARGS(priv->pGraph, Connect, pCapturePin, pSGIn); | 1401 hr = OLE_CALL_ARGS(priv->pGraph, Connect, pCapturePin, pSGIn); |
1398 if(FAILED(hr)){ | 1402 if(FAILED(hr)){ |
1399 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: Unable to create pCapturePin<->pSGIn connection. Error:0x%x\n", (unsigned int)hr); | 1403 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: Unable to create pCapturePin<->pSGIn connection. Error:0x%x\n", (unsigned int)hr); |
1400 break; | 1404 break; |
1401 } | 1405 } |
1402 hr = OLE_CALL_ARGS(pCapturePin, ConnectionMediaType, &conn_mt); | 1406 |
1407 hr = OLE_CALL_ARGS(pCapturePin, ConnectionMediaType, pmt); | |
1403 if(FAILED(hr)) | 1408 if(FAILED(hr)) |
1404 { | 1409 { |
1405 mp_msg(MSGT_TV, MSGL_WARN, MSGTR_TVI_DS_GetActualMediatypeFailed, (unsigned int)hr); | 1410 mp_msg(MSGT_TV, MSGL_WARN, MSGTR_TVI_DS_GetActualMediatypeFailed, (unsigned int)hr); |
1406 } | 1411 } |
1407 | 1412 |
1449 break; | 1454 break; |
1450 } | 1455 } |
1451 /* | 1456 /* |
1452 Prevent ending VBI chain with NullRenderer filter, because this causes VBI pin disconnection | 1457 Prevent ending VBI chain with NullRenderer filter, because this causes VBI pin disconnection |
1453 */ | 1458 */ |
1454 if(memcmp(&(pmt->majortype),&MEDIATYPE_VBI,16)){ | 1459 if(memcmp(&(arpmt[nFormatProbed]->majortype),&MEDIATYPE_VBI,16)){ |
1455 /* connecting filters together: SampleGrabber --> NullRenderer */ | 1460 /* connecting filters together: SampleGrabber --> NullRenderer */ |
1456 hr = OLE_CALL_ARGS(priv->pGraph, Connect, pSGOut, pNRIn); | 1461 hr = OLE_CALL_ARGS(priv->pGraph, Connect, pSGOut, pNRIn); |
1457 if(FAILED(hr)){ | 1462 if(FAILED(hr)){ |
1458 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: Unable to create pSGOut<->pNRIn connection. Error:0x%x\n", (unsigned int)hr); | 1463 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: Unable to create pSGOut<->pNRIn connection. Error:0x%x\n", (unsigned int)hr); |
1459 break; | 1464 break; |
1462 #endif | 1467 #endif |
1463 } | 1468 } |
1464 | 1469 |
1465 hr = S_OK; | 1470 hr = S_OK; |
1466 } while(0); | 1471 } while(0); |
1467 | |
1468 FreeMediaType(pmt); | |
1469 CopyMediaType(pmt, &conn_mt); | |
1470 FreeMediaType(&conn_mt); | |
1471 | 1472 |
1472 OLE_RELEASE_SAFE(pSGF); | 1473 OLE_RELEASE_SAFE(pSGF); |
1473 OLE_RELEASE_SAFE(pSGIn); | 1474 OLE_RELEASE_SAFE(pSGIn); |
1474 OLE_RELEASE_SAFE(pSGOut); | 1475 OLE_RELEASE_SAFE(pSGOut); |
1475 OLE_RELEASE_SAFE(pNR); | 1476 OLE_RELEASE_SAFE(pNR); |
2441 } else { | 2442 } else { |
2442 priv->v_buf->buffersize = 16; | 2443 priv->v_buf->buffersize = 16; |
2443 } | 2444 } |
2444 | 2445 |
2445 priv->v_buf->buffersize *= 1024 * 1024; | 2446 priv->v_buf->buffersize *= 1024 * 1024; |
2446 hr=build_sub_graph(priv, priv->pVideoFilter, priv->v_buf, priv->pmtVideo,&PIN_CATEGORY_CAPTURE); | 2447 hr=build_sub_graph(priv, priv->pVideoFilter, priv->v_buf, priv->arpmtVideo, priv->pmtVideo, &PIN_CATEGORY_CAPTURE); |
2447 if(FAILED(hr)){ | 2448 if(FAILED(hr)){ |
2448 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableBuildVideoSubGraph,(unsigned int)hr); | 2449 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableBuildVideoSubGraph,(unsigned int)hr); |
2449 return hr; | 2450 return hr; |
2450 } | 2451 } |
2451 return S_OK; | 2452 return S_OK; |
2484 priv->a_buf->buffersize=audio_buf_size_from_video( | 2485 priv->a_buf->buffersize=audio_buf_size_from_video( |
2485 priv->v_buf->buffersize, | 2486 priv->v_buf->buffersize, |
2486 (((VIDEOINFOHEADER *) priv->pmtVideo->pbFormat)->dwBitRate), | 2487 (((VIDEOINFOHEADER *) priv->pmtVideo->pbFormat)->dwBitRate), |
2487 (((WAVEFORMATEX *) (priv->pmtAudio->pbFormat))->nAvgBytesPerSec)); | 2488 (((WAVEFORMATEX *) (priv->pmtAudio->pbFormat))->nAvgBytesPerSec)); |
2488 | 2489 |
2489 hr=build_sub_graph(priv, priv->pAudioFilter, priv->a_buf,priv->pmtAudio,&PIN_CATEGORY_CAPTURE); | 2490 hr=build_sub_graph(priv, priv->pAudioFilter, priv->a_buf,priv->arpmtAudio,priv->pmtAudio,&PIN_CATEGORY_CAPTURE); |
2490 if(FAILED(hr)){ | 2491 if(FAILED(hr)){ |
2491 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableBuildAudioSubGraph,(unsigned int)hr); | 2492 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableBuildAudioSubGraph,(unsigned int)hr); |
2492 return 0; | 2493 return 0; |
2493 } | 2494 } |
2494 } | 2495 } |
2503 */ | 2504 */ |
2504 static HRESULT build_vbi_chain(priv_t *priv) | 2505 static HRESULT build_vbi_chain(priv_t *priv) |
2505 { | 2506 { |
2506 #ifdef HAVE_TV_TELETEXT | 2507 #ifdef HAVE_TV_TELETEXT |
2507 HRESULT hr; | 2508 HRESULT hr; |
2509 AM_MEDIA_TYPE* arpmtVBI[2] = { priv->pmtVBI, NULL }; | |
2508 | 2510 |
2509 if(priv->vbi_buf) | 2511 if(priv->vbi_buf) |
2510 return S_OK; | 2512 return S_OK; |
2511 | 2513 |
2512 if(priv->tv_param->tdevice) | 2514 if(priv->tv_param->tdevice) |
2517 | 2519 |
2518 init_ringbuffer(priv->vbi_buf,24,priv->tsp.bufsize); | 2520 init_ringbuffer(priv->vbi_buf,24,priv->tsp.bufsize); |
2519 | 2521 |
2520 priv->pmtVBI=calloc(1,sizeof(AM_MEDIA_TYPE)); | 2522 priv->pmtVBI=calloc(1,sizeof(AM_MEDIA_TYPE)); |
2521 priv->pmtVBI->majortype=MEDIATYPE_VBI; | 2523 priv->pmtVBI->majortype=MEDIATYPE_VBI; |
2522 hr=build_sub_graph(priv, priv->pVideoFilter, priv->vbi_buf,priv->pmtVBI,&PIN_CATEGORY_VBI); | 2524 hr=build_sub_graph(priv, priv->pVideoFilter, priv->vbi_buf,arpmtVBI,NULL,&PIN_CATEGORY_VBI); |
2523 if(FAILED(hr)){ | 2525 if(FAILED(hr)){ |
2524 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableBuildVBISubGraph,(unsigned int)hr); | 2526 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableBuildVBISubGraph,(unsigned int)hr); |
2525 return 0; | 2527 return 0; |
2526 } | 2528 } |
2527 } | 2529 } |
3074 switch (cmd) { | 3076 switch (cmd) { |
3075 /* need rewrite */ | 3077 /* need rewrite */ |
3076 case TVI_CONTROL_VID_SET_FORMAT: | 3078 case TVI_CONTROL_VID_SET_FORMAT: |
3077 { | 3079 { |
3078 int fcc, i; | 3080 int fcc, i; |
3081 void* tmp; | |
3082 | |
3079 if (priv->state) | 3083 if (priv->state) |
3080 return TVI_CONTROL_FALSE; | 3084 return TVI_CONTROL_FALSE; |
3081 fcc = *(int *) arg; | 3085 fcc = *(int *) arg; |
3082 | 3086 |
3083 if(!priv->arpmtVideo) | 3087 if(!priv->arpmtVideo) |
3087 (priv->arpmtVideo[i], fcc, priv->width, priv->height)) | 3091 (priv->arpmtVideo[i], fcc, priv->width, priv->height)) |
3088 break; | 3092 break; |
3089 if (!priv->arpmtVideo[i]) | 3093 if (!priv->arpmtVideo[i]) |
3090 return TVI_CONTROL_FALSE; | 3094 return TVI_CONTROL_FALSE; |
3091 | 3095 |
3092 priv->nVideoFormatUsed = i; | 3096 tmp = priv->arpmtVideo[0]; |
3097 priv->arpmtVideo[0] = priv->arpmtVideo[i]; | |
3098 priv->arpmtVideo[i] = tmp; | |
3099 | |
3100 tmp = priv->arVideoCaps[0]; | |
3101 priv->arVideoCaps[0] = priv->arVideoCaps[i]; | |
3102 priv->arVideoCaps[i] = tmp; | |
3103 | |
3104 priv->nVideoFormatUsed = 0; | |
3093 | 3105 |
3094 if (priv->pmtVideo) | 3106 if (priv->pmtVideo) |
3095 DeleteMediaType(priv->pmtVideo); | 3107 DeleteMediaType(priv->pmtVideo); |
3096 priv->pmtVideo = | 3108 priv->pmtVideo = |
3097 CreateMediaType(priv->arpmtVideo[priv->nVideoFormatUsed]); | 3109 CreateMediaType(priv->arpmtVideo[priv->nVideoFormatUsed]); |