@ -46,6 +46,63 @@ extern "C" {
# include "decklink_common.h"
# include "decklink_dec.h"
typedef struct VANCLineNumber {
BMDDisplayMode mode ;
int vanc_start ;
int field0_vanc_end ;
int field1_vanc_start ;
int vanc_end ;
} VANCLineNumber ;
/* These VANC line numbers need not be very accurate. In any case
* GetBufferForVerticalBlankingLine ( ) will return an error when invalid
* ancillary line number was requested . We just need to make sure that the
* entire VANC region is covered , while making sure we don ' t decode VANC of
* another source during switching */
static VANCLineNumber vanc_line_numbers [ ] = {
/* SD Modes */
{ bmdModeNTSC , 11 , 19 , 274 , 282 } ,
{ bmdModeNTSC2398 , 11 , 19 , 274 , 282 } ,
{ bmdModePAL , 7 , 22 , 320 , 335 } ,
{ bmdModeNTSCp , 11 , - 1 , - 1 , 39 } ,
{ bmdModePALp , 7 , - 1 , - 1 , 45 } ,
/* HD 1080 Modes */
{ bmdModeHD1080p2398 , 8 , - 1 , - 1 , 42 } ,
{ bmdModeHD1080p24 , 8 , - 1 , - 1 , 42 } ,
{ bmdModeHD1080p25 , 8 , - 1 , - 1 , 42 } ,
{ bmdModeHD1080p2997 , 8 , - 1 , - 1 , 42 } ,
{ bmdModeHD1080p30 , 8 , - 1 , - 1 , 42 } ,
{ bmdModeHD1080i50 , 8 , 20 , 570 , 585 } ,
{ bmdModeHD1080i5994 , 8 , 20 , 570 , 585 } ,
{ bmdModeHD1080i6000 , 8 , 20 , 570 , 585 } ,
{ bmdModeHD1080p50 , 8 , - 1 , - 1 , 42 } ,
{ bmdModeHD1080p5994 , 8 , - 1 , - 1 , 42 } ,
{ bmdModeHD1080p6000 , 8 , - 1 , - 1 , 42 } ,
/* HD 720 Modes */
{ bmdModeHD720p50 , 8 , - 1 , - 1 , 26 } ,
{ bmdModeHD720p5994 , 8 , - 1 , - 1 , 26 } ,
{ bmdModeHD720p60 , 8 , - 1 , - 1 , 26 } ,
/* For all other modes, for which we don't support VANC */
{ bmdModeUnknown , 0 , - 1 , - 1 , - 1 }
} ;
static int get_vanc_line_idx ( BMDDisplayMode mode )
{
unsigned int i ;
for ( i = 0 ; i < FF_ARRAY_ELEMS ( vanc_line_numbers ) ; i + + ) {
if ( mode = = vanc_line_numbers [ i ] . mode )
return i ;
}
/* Return the VANC idx for Unknown mode */
return i - 1 ;
}
static uint8_t calc_parity_and_line_offset ( int line )
{
uint8_t ret = ( line < 313 ) < < 5 ;
@ -502,20 +559,23 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
}
}
# endif
if ( videoFrame - > GetWidth ( ) = = 1920 & & v anc_format = = bmdFormat10BitYUV ) {
int first_active_line = ctx - > bmd_field_dominance = = bmdProgressiveFrame ? 42 : 584 ;
for ( i = 8 ; i < first_active_line ; i + + ) {
if ( vanc_format = = bmdFormat10BitYUV ) {
int idx = get_vanc_line_idx ( ctx - > bmd_mode ) ;
for ( i = vanc_line_numbers [ idx ] . vanc_start ; i < = vanc_line_numbers [ idx ] . vanc_end ; i + + ) {
uint8_t * buf ;
if ( vanc - > GetBufferForVerticalBlankingLine ( i , ( void * * ) & buf ) = = S_OK )
if ( vanc - > GetBufferForVerticalBlankingLine ( i , ( void * * ) & buf ) = = S_OK ) {
if ( videoFrame - > GetWidth ( ) = = 1920 ) {
txt_buf = teletext_data_unit_from_vanc_data ( buf , txt_buf , ctx - > teletext_lines ) ;
if ( ctx - > bmd_field_dominance ! = bmdProgressiveFrame & & i = = 20 ) // skip field1 active lines
i = 569 ;
if ( txt_buf - txt_buf0 > 1611 ) { // ensure we still have at least 1920 bytes free in the buffer
av_log ( avctx , AV_LOG_ERROR , " Too many OP47 teletext packets. \n " ) ;
break ;
}
}
}
if ( i = = vanc_line_numbers [ idx ] . field0_vanc_end )
i = vanc_line_numbers [ idx ] . field1_vanc_start - 1 ;
}
}
vanc - > Release ( ) ;
if ( txt_buf - txt_buf0 > 1 ) {
int stuffing_units = ( 4 - ( ( 45 + txt_buf - txt_buf0 ) / 46 ) % 4 ) % 4 ;