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]);