Пример #1
1
void *cam_thread()  
{  	
	int number,FileSize;
	number=0;
	FileSize =0; 
	fd_set fds;  
    struct timeval tv;  
    int r;
    printf ("cam_thread : I'm thread 1\n");
	while (!g_s32Quit) 
		{		
			/* Timeout. */  
			tv.tv_sec = 0;  
			tv.tv_usec = 33333;  
			nanosleep(&tv,NULL);
			if(!camera_get_frame(&pic)){
				printf("error1\r\n");
				break;
			}	
			gen_osd_info();
			osd_print(&pic, osd_string);
			if(!encoder_encode_frame(&pic, &encoded_pic))
				break;
			FileSize+=encoded_pic.length;
			if(g_s32DoPlay>0)
				ringput(encoded_pic.buffer,encoded_pic.length,encoded_pic.frame_type);
			if ((FileSize>MAX_SIZE) && (encoded_pic.frame_type ==FRAME_TYPE_I)) {
				output_close();	
				get_filename();
				printf("file:%s\n",mkv_filename);
				if(!output_init(&pic,mkv_filename))
					break;
				if(!output_write_headers(&header_pic,&psp))
					break;
				FileSize=0;
				ResetTime(&pic,&encoded_pic);
				if(!output_write_frame(&encoded_pic))
					break;
				encoder_release(&encoded_pic);
			} else {
				if(!output_write_frame(&encoded_pic))
					break;
				encoder_release(&encoded_pic);
				}
		}

	printf("exit the enc_thread\n");
	g_s32Quit= 0;
    //pthread_exit(NULL);  
} 
Пример #2
0
BOOL CDxMonthPicker::IsSelected(const COleDateTime& dtDay) const
{
    if (m_dtFSelBase.GetStatus() != COleDateTime::valid)
    {
        return FALSE;
    }

    return DateIsEqual(ResetTime(m_dtFSelBase), ResetTime(dtDay));
}
Пример #3
0
//----------------------------------------------------------------------------
void InverseKinematics::OnKeyDown (unsigned char ucKey, int, int)
{
    if ( ucKey == 'q' || ucKey == 'Q' || ucKey == KEY_ESCAPE )
    {
        RequestTermination();
        return;
    }

    if ( Transform(ucKey) )
        return;

    switch ( ucKey )
    {
    case '0':  // reset frame rate measurements
        ResetTime();
        return;
    case 'w':
        m_spkWireframeState->Enabled() = !m_spkWireframeState->Enabled();
        return;
    case 'i':
        m_pkIKCtrl->Active() = !m_pkIKCtrl->Active();
        m_spkScene->UpdateGS(0.0f);
        UpdateLine();
        return;
    }
}
Пример #4
0
void CDxDatePickerMonth::PopulateDays()
{
    if (m_dtMonth.GetYear() <= 100 && m_dtMonth.GetMonth() <= 2)
        m_dtMonth = COleDateTime(100,2,1,0,0,0);

    if (m_dtMonth.GetStatus() != COleDateTime::valid)
    {
        ATLASSERT(FALSE);
        m_dtMonth = ResetTime(COleDateTime::GetCurrentTime());
    }
    //if (m_dtMonth < COleDateTime(1601,4,1,0,0,0))
    //  m_dtMonth = COleDateTime(1601,4,1,0,0,0);

    // init days from 1st to last
    COleDateTime dtDay(m_dtMonth.GetYear(), m_dtMonth.GetMonth(), 1, 0, 0, 0);
    COleDateTimeSpan spDay(1, 0, 0, 0);

    // adjust first day of the week
    int nOleFirstDayOfWeek = m_pControl->GetFirstDayOfWeek();

    int iDayOfWeek = dtDay.GetDayOfWeek();
    if (iDayOfWeek != -1)
    {
        while (dtDay.GetDayOfWeek() != nOleFirstDayOfWeek && dtDay.GetDayOfWeek() != -1)
        {
            dtDay -= spDay;
        }
    }
    else
    {
        COleDateTime dtFutureDay(dtDay);
        dtFutureDay.SetDate(dtFutureDay.GetYear() + 2000, dtFutureDay.GetMonth(), dtFutureDay.GetDay());
        iDayOfWeek = dtFutureDay.GetDayOfWeek();

        while (dtFutureDay.GetDayOfWeek() != nOleFirstDayOfWeek && dtFutureDay.GetDayOfWeek() != -1)
        {
            dtFutureDay -= spDay;
            dtDay -= spDay;
        }
    }

    //while (dtDay.GetDayOfWeek() != nOleFirstDayOfWeek && dtDay.GetDayOfWeek() != -1)
    //{
    //  dtDay -= spDay;
    //}

    // populate all grid days
    for (int nWeek = 0; nWeek < XTP_MAX_WEEKS; nWeek++)
    {
        for (int nDay = 0; nDay < XTP_WEEK_DAYS; nDay++)
        {
            // create and add new day item
            CDxDatePickerDay* pDay = new CDxDatePickerDay(m_pControl, this, dtDay);
            m_arrDays.Add(pDay);
            // move next day
            dtDay += spDay;
        }
    }
}
Пример #5
0
void
wxGamePanel::InitTime()
{
    m_periLen = Config::Instance().GetPeriodLength() * 60 * 1000;
    m_shotClock = Config::Instance().GetShotClock() * 1000;

    ResetTime();
}
Пример #6
0
void CDDom::Touch( CUser* pUser, DDOM_BASE base )
{
	if( IsValidObj( pUser ) == FALSE )
		return;
	if( IsValidBase( base ) == FALSE )
		return;
	if( GetRunTime() != RUN_FIGHT )
		return; 
	if( pUser->IsDie() )
		return; 

	const DDOM_TEAM teamUser = pUser->m_ddomTeam;
	if( IsValidTeamOne( teamUser ) )
	{
		DDOM_TEAM team = m_Base[base].GetTouchTeam();
		if( team != MAX_TEAM )
		{
			if( team == pUser->m_ddomTeam )
			{
				pUser->AddTextD3D( "This base is already captured by your team.", 0xFFFF0000 );
				return;
			}
		}

		CString strTouch;
		strTouch.Format( "[%s] %s captured %s base", GetName( teamUser ), pUser->GetName(), GetBaseName( base ) );
		//SendBaseTouch( strTouch, base, pUser->m_ddomTeam ); //ATTENTION
		Send( strTouch );

		m_Base[base].SetTouchedBy( teamUser );
		const DDOM_BASE opBase = GetOponentBase( base );

		
		m_idCapUser = pUser->m_idPlayer;
		BOOL bTouchTime = FALSE;
		DDOM_TEAM opTeam = m_Base[opBase].GetTouchTeam(); 
		if( opTeam == pUser->m_ddomTeam )
		{
			bTouchTime = TRUE;
			CString strFontText; 
			strFontText.Format( "Both bases have been dominated by %s team. Countdown start", GetName( teamUser ) );
			Send( strFontText, FONT_MIDMED, DoubleDom::Color::nBlueCol );
			SetTime();
		}
		else
		{
			if( GetTime() == 1 || GetTime() == 2 )
			{
				ResetTime();
				Send( "Last second save", FONT_MIDMED, DoubleDom::Color::nBlueCol );
			}
		}
		m_DomTeam[ teamUser ].Increase( pUser->m_idPlayer, INC_TOUCH );
		SendTouch( pUser->m_ddomTeam, base, bTouchTime ); 
	}
}
/// flash effect
void CSmoothVisibilityCombo::StartFlash( DWORD dwDurationTime, DWORD dwFlashTime )
{
	ResetTime();

	m_iComboType				= VISIBILITY_COMBO_FLASH;
	m_bTransitionActivated		= true;

	m_dwFlashDurationTime		= dwDurationTime; /// Total duration time
	m_dwFlashTime				= dwFlashTime; /// One flash time	
}
ShooterSubsystem::ShooterSubsystem(): Subsystem("ShooterSubsystem"),
  shooterJaguar    ( SHOOTER_JAGUAR_CANID ),
  tensionerJaguar  ( TENSIONER_JAGUAR_CANID ),
  shooterBallSensor( BALL_SENSOR_MODULE, SHOOTER_BALL_SENSOR_CHANNEL),
  tensionerPot     ( SHOOTER_TENSIONER_SENSOR_MODULE, SHOOTER_TENSIONER_SENSOR_CHANNEL )
{
	// we do not know what the initial ball state is.
	ResetBallState();
	adjustmentAngle = 0;
	ResetTime();
}
///	
/// @param iToAppear    : Transition time to appear
/// @param iDuration    : Duration time of invisible
/// @param iToDisappear : Transition time to disappear	
///
void CSmoothVisibilityCombo::StartAppearCombo( DWORD dwToAppear, DWORD dwDuration, DWORD dwToDisappear )
{
	ResetTime();

	m_iComboType				= VISIBILITY_COMBO_TO_APPEAR;
	m_bTransitionActivated		= true;

	m_dwToFirstTransitionTime	= dwToAppear;
	m_dwDurationTime			= dwDuration;
	m_dwToSecondTransitionTime	= dwToDisappear;
}
Пример #10
0
int CFluid::GetFrame()
{
	if (timeSinceAnimationStart / animationData[currentAnim][msPerFrameData] < animationData[currentAnim][frameCountData])
	{
		return animationData[currentAnim][startFrameData] + timeSinceAnimationStart / animationData[currentAnim][msPerFrameData];
	}
	else
	{
		ResetTime();
		return GetFrame();
	}
}
Пример #11
0
int CProjectile::GetFrame()
{
	if (timeSinceAnimationStart / animationData[msPerFrameData] < animationData[frameCountData])
	{
		return timeSinceAnimationStart / animationData[msPerFrameData];
	}
	else
	{
		ResetTime();
		return GetFrame();
	}
}
Пример #12
0
void CArena::Process( void )
{
	if( GetTime() > 0 )
	{
		DecreaseTime();
	}
	else if( GetTime() == 0 )
	{
		SaveToDatabase();
		ResetTime();
	}
}
BottomLiftSubsystem::BottomLiftSubsystem(): Subsystem(const_cast<char*>("BottomLiftSubsystem")),
  
  bottomLiftLeftJaguar( BOTTOM_LIFT_LEFT_JAGUAR_CANID ),
  bottomLiftRightJaguar( BOTTOM_LIFT_RIGHT_JAGUAR_CANID ),
		
//bottomLiftLeftRelay( BOTTOM_LIFT_LEFT_SPIKE_RELAY_CHANNEL ),
//bottomLiftRightRelay( BOTTOM_LIFT_RIGHT_SPIKE_RELAY_CHANNEL ),
  baseBallSensor  ( BALL_SENSOR_MODULE, BOT_LIFT_BASE_BALL_SENSOR_CHANNEL  ),
  middleBallSensor( BALL_SENSOR_MODULE, BOT_LIFT_MIDDLE_BALL_SENSOR_CHANNEL)
{
	ResetBallState();
	ResetTime();	

}
Пример #14
0
void Engine::_Reset(void)
{
    DEBUG(logdetail("Before Reset Cleanup: Memory leak detector says: %u", MLD_COUNTER));
    _reset = false;
    objmgr->RemoveAll();
    _layermgr->Clear();
    physmgr->SetDefaults();
    resMgr.pool.Cleanup();
    resMgr.DropUnused();
    DEBUG(logdetail("After Reset Cleanup: Memory leak detector says: %u", MLD_COUNTER));
    resMgr.vfs.Prepare(true);
    resMgr.vfs.Reload(true);
    ResetTime();
}
Пример #15
0
//==============================================================================
int CEyeTrack::ConnectISCAN(  ){
  int iRet;

  if( IsRunning() ) {
    CP_printf("Error in m_InitSerialThread()! Thread is already running.\n");
    return 1;
  }
  iRet = g_SysGrantIO( LPT_BASE );
  if( iRet ) {
    iPortIO_Granted = 0;
    printf("Error: Cannot grant I/O access, error: %d\n", iRet );
    return 1;
  }
 
  iPortIO_Granted = 1;
  PortOutput( LPT_CONTROL, RESET_ON);
  Sleep(1);
  PortOutput( LPT_CONTROL, GATE_OFF);
  Sleep(1);
  PortOutput( LPT_CONTROL, GATE_ON);


  CP_printf("Connecting to %s port\n", x_aszComNames[ m_iComPortIdx-1]);
  iRet = m_Serial.connect(x_aszComNames[ m_iComPortIdx-1], m_iBaudRate, m_iSerialParity);
  if(iRet) {
    CP_printf("Error in m_InitSerialThread, m_Serial.connect() failed\n");
    return 1;
  }

  m_ReadCount = 0;
  m_iMissCount = 0;
  m_nMissedFrames = 0;
  m_iPrevFrame = 0;
  m_iReportSync = 1;  // report next sync
  // Init sliding buffer
  SetBuffer(sizeof(IScanFrameStruct), ISCAN_BUFFER_SIZE);
  ResetBuffer();
  ResetTime();
  m_StartReadingThread( ); 
  if( !IsRunning() ) {
    CP_printf("Error in m_InitSerialThread()! CreateThread() failed.\n");
    PortOutput( LPT_CONTROL, GATE_OFF);
    RemoveBuffer();
    return 1;
  }
  CP_printf("Connected ISCAN\n");
  CP_printf("Expected number of parameters: %d\n", N_DATA_ITEMS);
  return 0;
}
Пример #16
0
/*****************************************************************************
 * Control:
 *****************************************************************************/
static int Control( demux_t *p_demux, int i_query, va_list args )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    const int64_t i_start_time = p_sys->ic->start_time != AV_NOPTS_VALUE ? p_sys->ic->start_time : 0;
    double f, *pf;
    int64_t i64;

    switch( i_query )
    {
        case DEMUX_CAN_SEEK:
            *va_arg( args, bool * ) = true;
            return VLC_SUCCESS;

        case DEMUX_GET_POSITION:
            pf = va_arg( args, double * ); *pf = 0.0;
            i64 = stream_Size( p_demux->s );
            if( i64 > 0 )
            {
                double current = vlc_stream_Tell( p_demux->s );
                *pf = current / (double)i64;
            }

            if( (p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE) && (p_sys->i_pcr > 0) )
            {
                *pf = (double)p_sys->i_pcr / (double)p_sys->ic->duration;
            }

            return VLC_SUCCESS;

        case DEMUX_SET_POSITION:
        {
            f = va_arg( args, double );
            bool precise = va_arg( args, int );
            i64 = p_sys->ic->duration * f + i_start_time;

            msg_Warn( p_demux, "DEMUX_SET_POSITION: %"PRId64, i64 );

            /* If we have a duration, we prefer to seek by time
               but if we don't, or if the seek fails, try BYTE seeking */
            if( p_sys->ic->duration == (int64_t)AV_NOPTS_VALUE ||
                (av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BACKWARD ) < 0) )
            {
                int64_t i_size = stream_Size( p_demux->s );
                i64 = (i_size * f);

                msg_Warn( p_demux, "DEMUX_SET_BYTE_POSITION: %"PRId64, i64 );
                if( av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BYTE ) < 0 )
                    return VLC_EGENERIC;

                ResetTime( p_demux, -1 );
            }
            else
            {
                if( precise )
                    ResetTime( p_demux, i64 - i_start_time );
                else
                    ResetTime( p_demux, -1 );
            }
            return VLC_SUCCESS;
        }

        case DEMUX_GET_LENGTH:
            if( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE )
                *va_arg( args, vlc_tick_t * ) = FROM_AV_TS(p_sys->ic->duration);
            else
                *va_arg( args, vlc_tick_t * ) = 0;
            return VLC_SUCCESS;

        case DEMUX_GET_TIME:
            *va_arg( args, vlc_tick_t * ) = p_sys->i_pcr;
            return VLC_SUCCESS;

        case DEMUX_SET_TIME:
        {
            i64 = TO_AV_TS(va_arg( args, vlc_tick_t ));
            bool precise = va_arg( args, int );

            msg_Warn( p_demux, "DEMUX_SET_TIME: %"PRId64, i64 );

            if( av_seek_frame( p_sys->ic, -1, i64 + i_start_time, AVSEEK_FLAG_BACKWARD ) < 0 )
            {
                return VLC_EGENERIC;
            }
            if( precise )
                ResetTime( p_demux, i64 - i_start_time );
            else
                ResetTime( p_demux, -1 );
            return VLC_SUCCESS;
        }

        case DEMUX_HAS_UNSUPPORTED_META:
        {
            bool *pb_bool = va_arg( args, bool* );
            *pb_bool = true;
            return VLC_SUCCESS;
        }


        case DEMUX_GET_META:
        {
            static const char names[][10] = {
                [vlc_meta_Title] = "title",
                [vlc_meta_Artist] = "artist",
                [vlc_meta_Genre] = "genre",
                [vlc_meta_Copyright] = "copyright",
                [vlc_meta_Album] = "album",
                //[vlc_meta_TrackNumber] -- TODO: parse number/total value
                [vlc_meta_Description] = "comment",
                //[vlc_meta_Rating]
                [vlc_meta_Date] = "date",
                [vlc_meta_Setting] = "encoder",
                //[vlc_meta_URL]
                [vlc_meta_Language] = "language",
                //[vlc_meta_NowPlaying]
                [vlc_meta_Publisher] = "publisher",
                [vlc_meta_EncodedBy] = "encoded_by",
                //[vlc_meta_ArtworkURL]
                //[vlc_meta_TrackID]
                //[vlc_meta_TrackTotal]
            };
            vlc_meta_t *p_meta = va_arg( args, vlc_meta_t * );
            AVDictionary *dict = p_sys->ic->metadata;

            for( unsigned i = 0; i < sizeof(names) / sizeof(*names); i++)
            {
                if( !names[i][0] )
                    continue;

                AVDictionaryEntry *e = av_dict_get( dict, names[i], NULL, 0 );
                if( e != NULL && e->value != NULL && IsUTF8(e->value) )
                    vlc_meta_Set( p_meta, i, e->value );
            }
            return VLC_SUCCESS;
        }

        case DEMUX_GET_ATTACHMENTS:
        {
            input_attachment_t ***ppp_attach =
                va_arg( args, input_attachment_t*** );
            int *pi_int = va_arg( args, int * );
            int i;

            if( p_sys->i_attachments <= 0 )
                return VLC_EGENERIC;

            *ppp_attach = vlc_alloc( p_sys->i_attachments, sizeof(input_attachment_t*) );
            if( *ppp_attach == NULL )
                return VLC_EGENERIC;

            for( i = 0; i < p_sys->i_attachments; i++ )
            {
                (*ppp_attach)[i] = vlc_input_attachment_Duplicate( p_sys->attachments[i] );
                if((*ppp_attach)[i] == NULL)
                    break;
            }
            *pi_int = i;
            return VLC_SUCCESS;
        }

        case DEMUX_GET_TITLE_INFO:
        {
            input_title_t ***ppp_title = va_arg( args, input_title_t *** );
            int *pi_int = va_arg( args, int * );
            int *pi_title_offset = va_arg( args, int * );
            int *pi_seekpoint_offset = va_arg( args, int * );

            if( !p_sys->p_title )
                return VLC_EGENERIC;

            *ppp_title = malloc( sizeof( input_title_t*) );
            if( *ppp_title == NULL )
                return VLC_EGENERIC;
            (*ppp_title)[0] = vlc_input_title_Duplicate( p_sys->p_title );
            *pi_int = (*ppp_title)[0] ? 1 : 0;
            *pi_title_offset = 0;
            *pi_seekpoint_offset = 0;
            return VLC_SUCCESS;
        }
        case DEMUX_SET_TITLE:
        {
            const int i_title = va_arg( args, int );
            if( !p_sys->p_title || i_title != 0 )
                return VLC_EGENERIC;
            return VLC_SUCCESS;
        }
        case DEMUX_SET_SEEKPOINT:
        {
            const int i_seekpoint = va_arg( args, int );
            if( !p_sys->p_title )
                return VLC_EGENERIC;

            i64 = TO_AV_TS(p_sys->p_title->seekpoint[i_seekpoint]->i_time_offset) +
                  i_start_time;

            msg_Warn( p_demux, "DEMUX_SET_SEEKPOINT: %"PRId64, i64 );

            if( av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BACKWARD ) < 0 )
            {
                return VLC_EGENERIC;
            }
            ResetTime( p_demux, i64 - i_start_time );
            return VLC_SUCCESS;
        }
        case DEMUX_TEST_AND_CLEAR_FLAGS:
        {
            unsigned *restrict flags = va_arg(args, unsigned *);
            *flags &= p_sys->i_update;
            p_sys->i_update &= ~*flags;
            return VLC_SUCCESS;
        }
        case DEMUX_GET_TITLE:
            if( p_sys->p_title == NULL )
                return VLC_EGENERIC;
            *va_arg( args, int * ) = 0;
            return VLC_SUCCESS;
        case DEMUX_GET_SEEKPOINT:
            if( p_sys->p_title == NULL )
                return VLC_EGENERIC;
            *va_arg( args, int * ) = p_sys->i_seekpoint;
            return VLC_SUCCESS;
        case DEMUX_CAN_PAUSE:
        case DEMUX_SET_PAUSE_STATE:
        case DEMUX_CAN_CONTROL_PACE:
        case DEMUX_GET_PTS_DELAY:
            return demux_vaControlHelper( p_demux->s, 0, -1, 0, 1, i_query, args );
        default:
            return VLC_EGENERIC;
    }
}
Пример #17
0
int avformat_OpenDemux( vlc_object_t *p_this )
{
    demux_t       *p_demux = (demux_t*)p_this;
    demux_sys_t   *p_sys;
    AVInputFormat *fmt = NULL;
    vlc_tick_t    i_start_time = VLC_TICK_INVALID;
    bool          b_can_seek;
    const char    *psz_url;
    int           error;

    if( p_demux->psz_filepath )
        psz_url = p_demux->psz_filepath;
    else
        psz_url = p_demux->psz_url;

    if( avformat_ProbeDemux( p_this, &fmt, psz_url ) != VLC_SUCCESS )
        return VLC_EGENERIC;

    vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_can_seek );

    /* Fill p_demux fields */
    p_demux->pf_demux = Demux;
    p_demux->pf_control = Control;
    p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;

    p_sys->ic = 0;
    p_sys->fmt = fmt;
    p_sys->tracks = NULL;
    p_sys->i_ssa_order = 0;
    TAB_INIT( p_sys->i_attachments, p_sys->attachments);
    p_sys->p_title = NULL;
    p_sys->i_seekpoint = 0;
    p_sys->i_update = 0;

    /* Create I/O wrapper */
    unsigned char * p_io_buffer = av_malloc( AVFORMAT_IOBUFFER_SIZE );
    if( !p_io_buffer )
    {
        avformat_CloseDemux( p_this );
        return VLC_ENOMEM;
    }

    p_sys->ic = avformat_alloc_context();
    if( !p_sys->ic )
    {
        av_free( p_io_buffer );
        avformat_CloseDemux( p_this );
        return VLC_ENOMEM;
    }

    AVIOContext *pb = p_sys->ic->pb = avio_alloc_context( p_io_buffer,
        AVFORMAT_IOBUFFER_SIZE, 0, p_demux, IORead, NULL, IOSeek );
    if( !pb )
    {
        av_free( p_io_buffer );
        avformat_CloseDemux( p_this );
        return VLC_ENOMEM;
    }

    p_sys->ic->pb->seekable = b_can_seek ? AVIO_SEEKABLE_NORMAL : 0;
    error = avformat_open_input(&p_sys->ic, psz_url, p_sys->fmt, NULL);

    if( error < 0 )
    {
        msg_Err( p_demux, "Could not open %s: %s", psz_url,
                 vlc_strerror_c(AVUNERROR(error)) );
        av_free( pb->buffer );
        av_free( pb );
        p_sys->ic = NULL;
        avformat_CloseDemux( p_this );
        return VLC_EGENERIC;
    }

    char *psz_opts = var_InheritString( p_demux, "avformat-options" );
    unsigned nb_streams = p_sys->ic->nb_streams;

    AVDictionary *options[nb_streams ? nb_streams : 1];
    options[0] = NULL;
    for (unsigned i = 1; i < nb_streams; i++)
        options[i] = NULL;
    if (psz_opts) {
        vlc_av_get_options(psz_opts, &options[0]);
        for (unsigned i = 1; i < nb_streams; i++) {
            av_dict_copy(&options[i], options[0], 0);
        }
        free(psz_opts);
    }
    vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
    error = avformat_find_stream_info( p_sys->ic, options );
    vlc_avcodec_unlock();
    AVDictionaryEntry *t = NULL;
    while ((t = av_dict_get(options[0], "", t, AV_DICT_IGNORE_SUFFIX))) {
        msg_Err( p_demux, "Unknown option \"%s\"", t->key );
    }
    av_dict_free(&options[0]);
    for (unsigned i = 1; i < nb_streams; i++) {
        av_dict_free(&options[i]);
    }

    nb_streams = p_sys->ic->nb_streams; /* it may have changed */
    if( !nb_streams )
    {
        msg_Err( p_demux, "No streams found");
        avformat_CloseDemux( p_this );
        return VLC_EGENERIC;
    }
    p_sys->tracks = calloc( nb_streams, sizeof(*p_sys->tracks) );
    if( !p_sys->tracks )
    {
        avformat_CloseDemux( p_this );
        return VLC_ENOMEM;
    }
    p_sys->i_tracks = nb_streams;

    if( error < 0 )
    {
        msg_Warn( p_demux, "Could not find stream info: %s",
                  vlc_strerror_c(AVUNERROR(error)) );
    }

    for( unsigned i = 0; i < nb_streams; i++ )
    {
        struct avformat_track_s *p_track = &p_sys->tracks[i];
        AVStream *s = p_sys->ic->streams[i];
        const AVCodecParameters *cp = s->codecpar;
        es_format_t es_fmt;
        const char *psz_type = "unknown";

        /* Do not use the cover art as a stream */
        if( s->disposition == AV_DISPOSITION_ATTACHED_PIC )
            continue;

        vlc_fourcc_t fcc = GetVlcFourcc( cp->codec_id );
        switch( cp->codec_type )
        {
        case AVMEDIA_TYPE_AUDIO:
            es_format_Init( &es_fmt, AUDIO_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
            es_fmt.i_bitrate = cp->bit_rate;
            es_fmt.audio.i_channels = cp->channels;
            es_fmt.audio.i_rate = cp->sample_rate;
            es_fmt.audio.i_bitspersample = cp->bits_per_coded_sample;
            es_fmt.audio.i_blockalign = cp->block_align;
            psz_type = "audio";

            if(cp->codec_id == AV_CODEC_ID_AAC_LATM)
            {
                es_fmt.i_original_fourcc = VLC_FOURCC('L','A','T','M');
                es_fmt.b_packetized = false;
            }
            else if(cp->codec_id == AV_CODEC_ID_AAC && p_sys->fmt->long_name &&
                    strstr(p_sys->fmt->long_name, "raw ADTS AAC"))
            {
                es_fmt.i_original_fourcc = VLC_FOURCC('A','D','T','S');
                es_fmt.b_packetized = false;
            }
            break;

        case AVMEDIA_TYPE_VIDEO:
            es_format_Init( &es_fmt, VIDEO_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );

            es_fmt.video.i_bits_per_pixel = cp->bits_per_coded_sample;
            /* Special case for raw video data */
            if( cp->codec_id == AV_CODEC_ID_RAWVIDEO )
            {
                msg_Dbg( p_demux, "raw video, pixel format: %i", cp->format );
                if( GetVlcChroma( &es_fmt.video, cp->format ) != VLC_SUCCESS)
                {
                    msg_Err( p_demux, "was unable to find a FourCC match for raw video" );
                }
                else
                    es_fmt.i_codec = es_fmt.video.i_chroma;
            }
            /* We need this for the h264 packetizer */
            else if( cp->codec_id == AV_CODEC_ID_H264 && ( p_sys->fmt == av_find_input_format("flv") ||
                p_sys->fmt == av_find_input_format("matroska") || p_sys->fmt == av_find_input_format("mp4") ) )
                es_fmt.i_original_fourcc = VLC_FOURCC( 'a', 'v', 'c', '1' );

            es_fmt.video.i_width = cp->width;
            es_fmt.video.i_height = cp->height;
            es_fmt.video.i_visible_width = es_fmt.video.i_width;
            es_fmt.video.i_visible_height = es_fmt.video.i_height;

            get_rotation(&es_fmt, s);

# warning FIXME: implement palette transmission
            psz_type = "video";

            AVRational rate;
#if (LIBAVUTIL_VERSION_MICRO < 100) /* libav */
# if (LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(55, 20, 0))
            rate.num = s->time_base.num;
            rate.den = s->time_base.den;
# else
            rate.num = s->codec->time_base.num;
            rate.den = s->codec->time_base.den;
# endif
            rate.den *= __MAX( s->codec->ticks_per_frame, 1 );
#else /* ffmpeg */
            rate = av_guess_frame_rate( p_sys->ic, s, NULL );
#endif
            if( rate.den && rate.num )
            {
                es_fmt.video.i_frame_rate = rate.num;
                es_fmt.video.i_frame_rate_base = rate.den;
            }

            AVRational ar;
#if (LIBAVUTIL_VERSION_MICRO < 100) /* libav */
            ar.num = s->sample_aspect_ratio.num;
            ar.den = s->sample_aspect_ratio.den;
#else
            ar = av_guess_sample_aspect_ratio( p_sys->ic, s, NULL );
#endif
            if( ar.num && ar.den )
            {
                es_fmt.video.i_sar_den = ar.den;
                es_fmt.video.i_sar_num = ar.num;
            }
            break;

        case AVMEDIA_TYPE_SUBTITLE:
            es_format_Init( &es_fmt, SPU_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
            if( strncmp( p_sys->ic->iformat->name, "matroska", 8 ) == 0 &&
                cp->codec_id == AV_CODEC_ID_DVD_SUBTITLE &&
                cp->extradata != NULL &&
                cp->extradata_size > 0 )
            {
                char *psz_start;
                char *psz_buf = malloc( cp->extradata_size + 1);
                if( psz_buf != NULL )
                {
                    memcpy( psz_buf, cp->extradata , cp->extradata_size );
                    psz_buf[cp->extradata_size] = '\0';

                    psz_start = strstr( psz_buf, "size:" );
                    if( psz_start &&
                        vobsub_size_parse( psz_start,
                                           &es_fmt.subs.spu.i_original_frame_width,
                                           &es_fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
                    {
                        msg_Dbg( p_demux, "original frame size: %dx%d",
                                 es_fmt.subs.spu.i_original_frame_width,
                                 es_fmt.subs.spu.i_original_frame_height );
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original frame size failed" );
                    }

                    psz_start = strstr( psz_buf, "palette:" );
                    if( psz_start &&
                        vobsub_palette_parse( psz_start, &es_fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
                    {
                        es_fmt.subs.spu.palette[0] = SPU_PALETTE_DEFINED;
                        msg_Dbg( p_demux, "vobsub palette read" );
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original palette failed" );
                    }
                    free( psz_buf );
                }
            }
            else if( cp->codec_id == AV_CODEC_ID_DVB_SUBTITLE &&
                     cp->extradata_size > 3 )
            {
                es_fmt.subs.dvb.i_id = GetWBE( cp->extradata ) |
                                      (GetWBE( cp->extradata + 2 ) << 16);
            }
            else if( cp->codec_id == AV_CODEC_ID_MOV_TEXT )
            {
                if( cp->extradata_size && (es_fmt.p_extra = malloc(cp->extradata_size)) )
                {
                    memcpy( es_fmt.p_extra, cp->extradata, cp->extradata_size );
                    es_fmt.i_extra = cp->extradata_size;
                }
            }
            psz_type = "subtitle";
            break;

        default:
            es_format_Init( &es_fmt, UNKNOWN_ES, 0 );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
            if( cp->codec_type == AVMEDIA_TYPE_ATTACHMENT )
            {
                input_attachment_t *p_attachment;

                psz_type = "attachment";
                if( cp->codec_id == AV_CODEC_ID_TTF )
                {
                    AVDictionaryEntry *filename = av_dict_get( s->metadata, "filename", NULL, 0 );
                    if( filename && filename->value )
                    {
                        p_attachment = vlc_input_attachment_New(
                                filename->value, "application/x-truetype-font",
                                NULL, cp->extradata, (int)cp->extradata_size );
                        if( p_attachment )
                            TAB_APPEND( p_sys->i_attachments, p_sys->attachments,
                                        p_attachment );
                    }
                }
                else msg_Warn( p_demux, "unsupported attachment type (%u) in avformat demux", cp->codec_id );
            }
            else
#endif
            {
                if( cp->codec_type == AVMEDIA_TYPE_DATA )
                    psz_type = "data";

                msg_Warn( p_demux, "unsupported track type (%u:%u) in avformat demux", cp->codec_type, cp->codec_id );
            }
            break;
        }

        AVDictionaryEntry *language = av_dict_get( s->metadata, "language", NULL, 0 );
        if ( language && language->value )
            es_fmt.psz_language = strdup( language->value );

        if( s->disposition & AV_DISPOSITION_DEFAULT )
            es_fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + 1000;

#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
        if( cp->codec_type != AVMEDIA_TYPE_ATTACHMENT )
#endif
        if( cp->codec_type != AVMEDIA_TYPE_DATA )
        {
            const bool    b_ogg = !strcmp( p_sys->fmt->name, "ogg" );
            const uint8_t *p_extra = cp->extradata;
            unsigned      i_extra  = cp->extradata_size;

            if( cp->codec_id == AV_CODEC_ID_THEORA && b_ogg )
            {
                unsigned pi_size[3];
                const void *pp_data[3];
                unsigned i_count;
                for( i_count = 0; i_count < 3; i_count++ )
                {
                    if( i_extra < 2 )
                        break;
                    pi_size[i_count] = GetWBE( p_extra );
                    pp_data[i_count] = &p_extra[2];
                    if( i_extra < pi_size[i_count] + 2 )
                        break;

                    p_extra += 2 + pi_size[i_count];
                    i_extra -= 2 + pi_size[i_count];
                }
                if( i_count > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
                                                     pi_size, pp_data, i_count ) )
                {
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
                }
            }
            else if( cp->codec_id == AV_CODEC_ID_SPEEX && b_ogg )
            {
                const uint8_t p_dummy_comment[] = {
                    0, 0, 0, 0,
                    0, 0, 0, 0,
                };
                unsigned pi_size[2];
                const void *pp_data[2];

                pi_size[0] = i_extra;
                pp_data[0] = p_extra;

                pi_size[1] = sizeof(p_dummy_comment);
                pp_data[1] = p_dummy_comment;

                if( pi_size[0] > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
                                                        pi_size, pp_data, 2 ) )
                {
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
                }
            }
            else if( cp->codec_id == AV_CODEC_ID_OPUS )
            {
                const uint8_t p_dummy_comment[] = {
                    'O', 'p', 'u', 's',
                    'T', 'a', 'g', 's',
                    0, 0, 0, 0, /* Vendor String length */
                                /* Vendor String */
                    0, 0, 0, 0, /* User Comment List Length */

                };
                unsigned pi_size[2];
                const void *pp_data[2];

                pi_size[0] = i_extra;
                pp_data[0] = p_extra;

                pi_size[1] = sizeof(p_dummy_comment);
                pp_data[1] = p_dummy_comment;

                if( pi_size[0] > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
                                                        pi_size, pp_data, 2 ) )
                {
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
                }
            }
            else if( cp->extradata_size > 0 && !es_fmt.i_extra )
            {
                es_fmt.p_extra = malloc( i_extra );
                if( es_fmt.p_extra )
                {
                    es_fmt.i_extra = i_extra;
                    memcpy( es_fmt.p_extra, p_extra, i_extra );
                }
            }

            p_track->p_es = es_out_Add( p_demux->out, &es_fmt );
            if( p_track->p_es && (s->disposition & AV_DISPOSITION_DEFAULT) )
                es_out_Control( p_demux->out, ES_OUT_SET_ES_DEFAULT, p_track->p_es );

            msg_Dbg( p_demux, "adding es: %s codec = %4.4s (%d)",
                     psz_type, (char*)&fcc, cp->codec_id  );
        }
        es_format_Clean( &es_fmt );
    }

    if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
        i_start_time = FROM_AV_TS(p_sys->ic->start_time);

    msg_Dbg( p_demux, "AVFormat(%s %s) supported stream", AVPROVIDER(LIBAVFORMAT), LIBAVFORMAT_IDENT );
    msg_Dbg( p_demux, "    - format = %s (%s)",
             p_sys->fmt->name, p_sys->fmt->long_name );
    msg_Dbg( p_demux, "    - start time = %"PRId64, i_start_time );
    msg_Dbg( p_demux, "    - duration = %"PRId64,
             ( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE ) ?
             FROM_AV_TS(p_sys->ic->duration) : -1 );

    if( p_sys->ic->nb_chapters > 0 )
    {
        p_sys->p_title = vlc_input_title_New();
        p_sys->p_title->i_length = FROM_AV_TS(p_sys->ic->duration);
    }

    for( unsigned i = 0; i < p_sys->ic->nb_chapters; i++ )
    {
        seekpoint_t *s = vlc_seekpoint_New();

        AVDictionaryEntry *title = av_dict_get( p_sys->ic->metadata, "title", NULL, 0);
        if( title && title->value )
        {
            s->psz_name = strdup( title->value );
            EnsureUTF8( s->psz_name );
            msg_Dbg( p_demux, "    - chapter %d: %s", i, s->psz_name );
        }
        s->i_time_offset = vlc_tick_from_samples( p_sys->ic->chapters[i]->start *
            p_sys->ic->chapters[i]->time_base.num,
            p_sys->ic->chapters[i]->time_base.den ) -
            (i_start_time != VLC_TICK_INVALID ? i_start_time : 0 );
        TAB_APPEND( p_sys->p_title->i_seekpoint, p_sys->p_title->seekpoint, s );
    }

    ResetTime( p_demux, 0 );
    return VLC_SUCCESS;
}
Пример #18
0
bool PAPlayer::ProcessPAP()
{
  /*
   * Here's what we should be doing in each player loop:
   *
   * 1.  Run DoWork() on our audio device to actually output audio.
   *
   * 2.  Pass our current buffer to the audio device to see if it wants anything,
   *     and if so, reduce our buffer size accordingly.
   *
   * 3.  Check whether we have space in our buffer for more data, and if so,
   *     read some more in.
   *
   * 4.  Check for end of file and return false if we reach it.
   *
   * 5.  Perform any seeking and ffwd/rewding as necessary.
   *
   * 6.  If we don't do anything in 2...5, we can take a breather and break out for sleeping.
   */
  while (true)
  {
    if (m_bStop) return false;

    // Check for .cue sheet item end
    if (m_currentFile->m_lEndOffset && GetTime() >= GetTotalTime64())
    {
      CLog::Log(LOGINFO, "PAPlayer: Passed end of track in a .cue sheet item");
      m_decoder[m_currentDecoder].SetStatus(STATUS_ENDED);
    }

    // check whether we need to send off our callbacks etc.
    int status = m_decoder[m_currentDecoder].GetStatus();
    if (status == STATUS_NO_FILE)
      return false;

    UpdateCacheLevel();

    // check whether we should queue the next file up
    if ((GetTotalTime64() > 0) && GetTotalTime64() - GetTime() < TIME_TO_CACHE_NEXT_FILE + m_crossFading * 1000L && !m_cachingNextFile)
    { // request the next file from our application
      m_callback.OnQueueNextItem();
      m_cachingNextFile = true;
    }

    if (m_crossFading && m_decoder[0].GetChannels() == m_decoder[1].GetChannels())
    {
      if (((GetTotalTime64() - GetTime() < m_crossFading * 1000L) || (m_forceFadeToNext)) && !m_currentlyCrossFading)
      { // request the next file from our application
        if (m_decoder[1 - m_currentDecoder].GetStatus() == STATUS_QUEUED && m_pStream[1 - m_currentStream])
        {
          m_currentlyCrossFading = true;
          if (m_forceFadeToNext)
          {
            m_forceFadeToNext = false;
            m_crossFadeLength = m_crossFading * 1000L;
          }
          else
          {
            m_crossFadeLength = GetTotalTime64() - GetTime();
          }
          m_currentDecoder = 1 - m_currentDecoder;
          m_decoder[m_currentDecoder].Start();
          m_currentStream = 1 - m_currentStream;
          CLog::Log(LOGDEBUG, "Starting Crossfade - resuming stream %i", m_currentStream);

          snd_pcm_pause(m_pStream[m_currentStream], 0);

          m_callback.OnPlayBackStarted();
          m_clock.SetClock(m_nextFile->m_lStartOffset * 1000 / 75);
          ResetTime();
          *m_currentFile = *m_nextFile;
          m_nextFile->Reset();
          m_cachingNextFile = false;
        }
      }
    }

    // Check for EOF and queue the next track if applicable
    if (m_decoder[m_currentDecoder].GetStatus() == STATUS_ENDED)
    { // time to swap tracks
      if (m_nextFile->m_strPath != m_currentFile->m_strPath ||
          !m_nextFile->m_lStartOffset ||
          m_nextFile->m_lStartOffset != m_currentFile->m_lEndOffset)
      { // don't have a .cue sheet item
        int nextstatus = m_decoder[1 - m_currentDecoder].GetStatus();
        if (nextstatus == STATUS_QUEUED || nextstatus == STATUS_QUEUING || nextstatus == STATUS_PLAYING)
        { // swap streams
          CLog::Log(LOGDEBUG, "PAPlayer: Swapping tracks %i to %i", m_currentDecoder, 1-m_currentDecoder);
          if (!m_crossFading || m_decoder[0].GetChannels() != m_decoder[1].GetChannels())
          { // playing gapless (we use only the 1 output stream in this case)
            int prefixAmount = m_decoder[m_currentDecoder].GetDataSize();
            CLog::Log(LOGDEBUG, "PAPlayer::Prefixing %i samples of old data to new track for gapless playback", prefixAmount);
            m_decoder[1 - m_currentDecoder].PrefixData(m_decoder[m_currentDecoder].GetData(prefixAmount), prefixAmount);
            // check if we need to change the resampler (due to format change)
            unsigned int channels, samplerate, bitspersample;
            m_decoder[m_currentDecoder].GetDataFormat(&channels, &samplerate, &bitspersample);
            unsigned int channels2, samplerate2, bitspersample2;
            m_decoder[1 - m_currentDecoder].GetDataFormat(&channels2, &samplerate2, &bitspersample2);
            // change of channels - reinitialize our speaker configuration
            if (channels != channels2)
            {
              CLog::Log(LOGWARNING, "PAPlayer: Channel number has changed - restarting direct sound");
              FreeStream(m_currentStream);
              if (!CreateStream(m_currentStream, channels2, samplerate2, bitspersample2))
              {
                CLog::Log(LOGERROR, "PAPlayer: Error creating stream!");
                return false;
              }
              snd_pcm_pause(m_pStream[m_currentStream], 0);
            }
            else if (samplerate != samplerate2 || bitspersample != bitspersample2)
            {
              CLog::Log(LOGINFO, "PAPlayer: Restarting resampler due to a change in data format");
              m_resampler[m_currentStream].DeInitialize();
              if (!m_resampler[m_currentStream].InitConverter(samplerate2, bitspersample2, channels2, XBMC_SAMPLE_RATE, 16, PACKET_SIZE))
              {
                CLog::Log(LOGERROR, "PAPlayer: Error initializing resampler!");
                return false;
              }
            }
            CLog::Log(LOGINFO, "PAPlayer: Starting new track");

            m_decoder[m_currentDecoder].Destroy();
            m_decoder[1 - m_currentDecoder].Start();
            m_callback.OnPlayBackStarted();
            ResetTime();
            m_clock.SetClock(m_nextFile->m_lStartOffset * 1000 / 75);
            *m_currentFile = *m_nextFile;
            m_nextFile->Reset();
            m_cachingNextFile = false;
            m_currentDecoder = 1 - m_currentDecoder;
          }
          else
          { // cross fading - shouldn't ever get here - if we do, return false
            if (!m_currentlyCrossFading)
            {
              CLog::Log(LOGERROR, "End of file Reached before crossfading kicked in!");
              return false;
            }
            else
            {
              CLog::Log(LOGINFO, "End of file reached before crossfading finished!");
              return false;
            }
          }
        }
        else
        {
          if (GetTotalTime64() <= 0 && !m_bQueueFailed)
          { //we did not know the duration so didn't queue the next song, try queueing it now
            if (!m_cachingNextFile)
            {// request the next file from our application
              m_callback.OnQueueNextItem();
              m_cachingNextFile = true;
            }
          }
          else
          {
            // no track queued - return and get another one once we are finished
            // with the current stream
            WaitForStream();
            return false;
          }
        }
      }
      else
      {
        // set the next track playing (.cue sheet)
        m_decoder[m_currentDecoder].SetStatus(STATUS_PLAYING);
        m_callback.OnPlayBackStarted();
        ResetTime();
        m_clock.SetClock(m_nextFile->m_lStartOffset * 1000 / 75);
        *m_currentFile = *m_nextFile;
        m_nextFile->Reset();
        m_cachingNextFile = false;
      }
    }

    // handle seeking and ffwd/rewding.
    HandleSeeking();
    if (!HandleFFwdRewd())
    {
      // need to skip to the next track - let's see if we already have another one
      m_decoder[m_currentDecoder].SetStatus(STATUS_ENDED);
      continue; // loop around to start the next track
    }

    if (!m_bPaused) {

    // Let our decoding stream(s) do their thing
    int retVal = m_decoder[m_currentDecoder].ReadSamples(PACKET_SIZE);
    if (retVal == RET_ERROR)
    {
      m_decoder[m_currentDecoder].Destroy();
      return false;
    }

    int retVal2 = m_decoder[1 - m_currentDecoder].ReadSamples(PACKET_SIZE);
    if (retVal2 == RET_ERROR)
    {
      m_decoder[1 - m_currentDecoder].Destroy();
    }

    // if we're cross-fading, then we do this for both streams, otherwise
    // we do it just for the one stream.
    if (m_currentlyCrossFading)
    {
      if (GetTime() >= m_crossFadeLength)  // finished
      {
        CLog::Log(LOGDEBUG, "Finished Crossfading");
        m_currentlyCrossFading = false;
        SetStreamVolume(m_currentStream, g_stSettings.m_nVolumeLevel);
        FreeStream(1 - m_currentStream);
        m_decoder[1 - m_currentDecoder].Destroy();
      }
      else
      {
        float fraction = (float)(m_crossFadeLength - GetTime()) / (float)m_crossFadeLength - 0.5f;
        // make sure we can take valid logs.
        if (fraction > 0.499f) fraction = 0.499f;
        if (fraction < -0.499f) fraction = -0.499f;
        float volumeCurrent = 2000.0f * log10(0.5f - fraction);
        float volumeNext = 2000.0f * log10(0.5f + fraction);
        SetStreamVolume(m_currentStream, g_stSettings.m_nVolumeLevel + (int)volumeCurrent);
        SetStreamVolume(1 - m_currentStream, g_stSettings.m_nVolumeLevel + (int)volumeNext);
        if (AddPacketsToStream(1 - m_currentStream, m_decoder[1 - m_currentDecoder]))
          retVal2 = RET_SUCCESS;
      }
    }

       // add packets as necessary
       if (AddPacketsToStream(m_currentStream, m_decoder[m_currentDecoder]))
         retVal = RET_SUCCESS;

       if (retVal == RET_SLEEP && retVal2 == RET_SLEEP)
         Sleep(1);
    }
    else
        Sleep(100);
  }
  return true;
}
Пример #19
0
bool PAPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options)
{
  if (m_currentlyCrossFading) CloseFileInternal(false); //user seems to be in a hurry

  m_crossFading = g_guiSettings.GetInt("mymusic.crossfade");
  //no crossfading for cdda, cd-reading goes mad and no crossfading for last.fm doesn't like two connections
  if (file.IsCDDA() || file.IsLastFM()) m_crossFading = 0;
  if (m_crossFading && IsPlaying())
  {
    //do a short crossfade on trackskip
    //set to max 2 seconds for these prev/next transitions
    if (m_crossFading > 2) m_crossFading = 2;
    //queue for crossfading
    bool result = QueueNextFile(file, false);
    if (result)
    {
      //crossfading value may be update by QueueNextFile when nr of channels changed
      if (!m_crossFading) // swap to next track
        m_decoder[m_currentDecoder].SetStatus(STATUS_ENDED);
      else //force to fade to next track immediately
        m_forceFadeToNext = true;
    }
    return result;
  }

  // normal opening of file, nothing playing or crossfading not enabled
  // however no need to return to gui audio device
  CloseFileInternal(false);

  // always open the file using the current decoder
  m_currentDecoder = 0;

  if (!m_decoder[m_currentDecoder].Create(file, (__int64)(options.starttime * 1000), m_crossFading))
    return false;

  m_iSpeed = 1;
  m_bPaused = false;
  m_bStopPlaying = false;
  ResetTime();
  m_clock.SetSpeed(0);

  CLog::Log(LOGINFO, "PAP Player: Playing %s", file.m_strPath.c_str());

  m_clock.SetClock((__int64)(options.starttime * 1000));

  m_decoder[m_currentDecoder].GetDataFormat(&m_Channels, &m_SampleRate, &m_BitsPerSample);

  if (!CreateStream(m_currentStream, m_Channels, m_SampleRate, m_BitsPerSample))
  {
    m_decoder[m_currentDecoder].Destroy();
    CLog::Log(LOGERROR, "PAPlayer::Unable to create audio stream");
  }

  *m_currentFile = file;

  if (ThreadHandle() == NULL)
    Create();

  m_startEvent.Set();

  m_bIsPlaying = true;
  m_cachingNextFile = false;
  m_currentlyCrossFading = false;
  m_forceFadeToNext = false;
  m_bQueueFailed = false;

  m_decoder[m_currentDecoder].Start();  // start playback

  if (m_pStream[m_currentStream])
     snd_pcm_reset(m_pStream[m_currentStream]);

  if (m_pStream[m_currentStream])
     snd_pcm_pause(m_pStream[m_currentStream], 0);

  m_clock.SetSpeed(m_iSpeed);
  return true;
}
Пример #20
0
/******************************************************************************
* 函数名称: ucGetActAndKey
* 功能描述: 
*     获取当前动作,如为按键动作的话,输出键值
* 输入参数: 无
* 输出参数: 
*	ucKeyValue——当前的按键键值
* 返回值:  当前的动作,分7种动作
*	1、来电	CALLIN
*	2、按银行卡功能	KEYFUN
*	3、打电话动作_免提	CALLON_FREE
*	4、打电话动作_话筒	CALLON_SET
*	5、结束通话	CALLEND
*	6、按键动作	KEYHIT
*	7、无动作	NOACT
* 历史纪录:
*     修改人     日期           日志
*     郑庚     2008-02-18     建立函数
******************************************************************************/
UINT8 ucGetActAndKey(UINT8 *ucKeyValue)
{
	*ucKeyValue = KEY_NULL;
	
	ResetTime();
	while(1)
	{
#ifdef PHONE
		if (gucCallState == KEY_HANGUP)
		{
#ifdef LDV3
			if (EA_ucRingDetect_V3() == 'S')
#else
			if (EA_ucRingDetect() == 'S')
#endif
			{			
				//TelephoneRing();
				if(gucRing == 0)
				{
					gucRing = 1;				
					return CALLIN;
				}
			}
		}
#endif	//End of PHONE

		*ucKeyValue = ucReadInput();
		switch(*ucKeyValue)
		{
		case MagInput:
			return MAG_INPUT;
		case KEY_FUNC:
			return	KEYFUN;
		case KEY_ENTER:
			return	KEYENTER;
		case KEY_BACK:
			return	KEYBACK;
// 		case KEY_KF:
// 			return	KEYKF;
//			break;
#ifdef PLAT_A9L
#ifdef PHONE
		case KEY_CALLOUT:
			return KEYCALLOUT;
		case KEY_CALLIN:
			return KEYCALLIN;
		case KEY_PAY:
			return KEYPAY;
		case KEY_VOLUME:
			return KEYVOLUME;
		case KEY_PHONEBOOK:
			return KEYPHONEBOOK;
#endif
#endif
		case KEY_PICKUP_SET:
			return CALLON_SET;
		case KEY_PICKUP_FREE:
			return CALLON_FREE;
		case KEY_HANGUP:
			return CALLEND;
		case KEY_NULL:
#ifdef PHONE
			if (gucRing == 1)
			{				
#ifdef LDV3
				if (EA_ucRingDetect_V3() != 'S')
#else
				if (EA_ucRingDetect() != 'S') 
#endif
				{
					gucRing = 0;
					return CALLINEND;
				}
			}
#endif //End of PHONE
			break;
		default:
			return KEYHIT;
		}
		
		if (GetPassTime() > IDELDELAYMS)
		{
			return NOACT;
		}
	}	
}
Пример #21
0
//===========================================================================
int CSerialThread::ResetTimeAndBuffer(){
  ResetBuffer();
  ResetTime();
  return 0;
}
Пример #22
0
void CDDom::ResetCapTeam( void )
{
	ResetTime();
	m_Base[TEAM_A].SetTouchedBy( MAX_TEAM );
	m_Base[TEAM_B].SetTouchedBy( MAX_TEAM );
}
Пример #23
0
//---------------------------------------------------------------------------
static hsm_context ActiveStateEnter( hsm_status status )
{
    Watch* watch=((WatchContext*)status->ctx)->watch;
    ResetTime( watch );
    return status->ctx;
}
Пример #24
0
TimeClass::TimeClass()
{
    frames = 0;
    ResetTime();
}
Пример #25
0
//---------------------------------------------------------------------------
// Set new sampling rate
void
NaTimer::SetSamplingRate (NaReal sr)
{
    Tdelta = sr;
    ResetTime();
}
Пример #26
0
CSmoothVisibilityCombo::CSmoothVisibilityCombo()
{
	ResetTime();
}
Пример #27
0
/******************************************************************************
* 函数名称: vGetTelNum
* 功能描述: 
*     获取电话号码,自动设置到呼入号码中去,需要调用获取呼入号码获取
* 输入参数: 无
* 输出参数: 无
* 返回值:  无
* 历史纪录:
*     修改人     日期           日志
*     郑庚     2008-02-18     建立函数
******************************************************************************/
void vGetTelNum(void)
{
	char cTmpNo[50];
	char cShowNo[DIALNOLEN];
	char cShowNoEn[DIALNOLEN];
	UINT8 i, ucLen, ucLen1;

	//因为来电目前跟振铃之有一个等待2.5秒的时间
	//所以直接采用查询方式,有的话就显示电话号码
	ResetTime();
	memset(cTmpNo, 0x00, sizeof(cTmpNo));
	memset(cShowNo, 0x00, sizeof(cShowNo));
	while (1) 
	{
		ucLen = ucGetLastTelNum((UINT8 *)cTmpNo, sizeof(cTmpNo));
		if(ucLen > 0)
		{
			i = 0;
			while(1)
			{				
				if((cTmpNo[i]== 0x3) || i >= ucLen)
				{
					ucLen1 = cTmpNo[i+1];
					i += 2;
					break;
				}
				i++;
			}

			if(i >= ucLen)
			{
				strcpy(cShowNo, "未知来电");
				strcpy(cShowNoEn, "UNKNOWN TELNO");
				break;
			}
			else
			{
				if( ucLen1> (DIALNOLEN-1) )
				{
					memcpy(cShowNo, cTmpNo + i, DIALNOLEN-1);
				}
				else
				{
					memcpy(cShowNo, cTmpNo + i, ucLen1);
				}

				strcpy(cShowNoEn, cShowNo);
				
#ifdef FSK_COMMU_TYPE //只有FSK通讯方式时才进行判断
				//增加代码,判断当前是否是中心拨叫过来号码
				if(ucIsCenCall(cShowNo, strlen(cShowNo)))
				{
					display(3, "中心来电...");
//					inkey(2);
					//执行中心来电操作
					IsCenCallFun();
					EA_modem_setlisten(1);
					vClearComingCallNo();
					return;
				}
#endif
			}
			break;
		}
		else
		{
			if (GetPassTime() >= 4500) 
			{
				strcpy(cShowNo, "未知来电");
				strcpy(cShowNoEn, "UNKNOWN TELNO");
				break;
			}
		}
	}
	EA_ucModemSwitch(MODEMOFF);	
//	display(3, "%s", cShowNo);
	TPA_vDisplayInv(3, DISP_LEFT, cShowNo);
	vClearComingCallNo();
	vSetComingCall(cShowNo);
	return;
}
Пример #28
0
int OpenDemux( vlc_object_t *p_this )
{
    demux_t       *p_demux = (demux_t*)p_this;
    demux_sys_t   *p_sys;
    AVProbeData   pd = { };
    AVInputFormat *fmt = NULL;
    int64_t       i_start_time = -1;
    bool          b_can_seek;
    char         *psz_url;
    const uint8_t *peek;
    int           error;

    /* Init Probe data */
    pd.buf_size = vlc_stream_Peek( p_demux->s, &peek, 2048 + 213 );
    if( pd.buf_size <= 0 )
    {
        msg_Warn( p_demux, "cannot peek" );
        return VLC_EGENERIC;
    }

    pd.buf = malloc( pd.buf_size + AVPROBE_PADDING_SIZE );
    if( unlikely(pd.buf == NULL) )
        return VLC_ENOMEM;

    memcpy( pd.buf, peek, pd.buf_size );
    memset( pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE );

    if( p_demux->psz_file )
        psz_url = strdup( p_demux->psz_file );
    else
    {
        if( asprintf( &psz_url, "%s://%s", p_demux->psz_access,
                      p_demux->psz_location ) == -1)
            psz_url = NULL;
    }

    if( psz_url != NULL )
        msg_Dbg( p_demux, "trying url: %s", psz_url );

    pd.filename = psz_url;

    vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_can_seek );

    vlc_init_avformat(p_this);

    /* Guess format */
    char *psz_format = var_InheritString( p_this, "avformat-format" );
    if( psz_format )
    {
        if( (fmt = av_find_input_format(psz_format)) )
            msg_Dbg( p_demux, "forcing format: %s", fmt->name );
        free( psz_format );
    }

    if( fmt == NULL )
        fmt = av_probe_input_format( &pd, 1 );

    free( pd.buf );

    if( fmt == NULL )
    {
        msg_Dbg( p_demux, "couldn't guess format" );
        free( psz_url );
        return VLC_EGENERIC;
    }

    if( !p_demux->obj.force )
    {
        static const char ppsz_blacklist[][16] = {
            /* Don't handle MPEG unless forced */
            "mpeg", "vcd", "vob", "mpegts",
            /* libavformat's redirector won't work */
            "redir", "sdp",
            /* Don't handle subtitles format */
            "ass", "srt", "microdvd",
            /* No timestamps at all */
            "hevc", "h264",
            ""
        };

        for( int i = 0; *ppsz_blacklist[i]; i++ )
        {
            if( !strcmp( fmt->name, ppsz_blacklist[i] ) )
            {
                free( psz_url );
                return VLC_EGENERIC;
            }
        }
    }

    /* Don't trigger false alarms on bin files */
    if( !p_demux->obj.force && !strcmp( fmt->name, "psxstr" ) )
    {
        int i_len;

        if( !p_demux->psz_file )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }

        i_len = strlen( p_demux->psz_file );
        if( i_len < 4 )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }

        if( strcasecmp( &p_demux->psz_file[i_len - 4], ".str" ) &&
            strcasecmp( &p_demux->psz_file[i_len - 4], ".xai" ) &&
            strcasecmp( &p_demux->psz_file[i_len - 3], ".xa" ) )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }
    }

    msg_Dbg( p_demux, "detected format: %s", fmt->name );

    /* Fill p_demux fields */
    p_demux->pf_demux = Demux;
    p_demux->pf_control = Control;
    p_demux->p_sys = p_sys = xmalloc( sizeof( demux_sys_t ) );
    p_sys->ic = 0;
    p_sys->fmt = fmt;
    p_sys->i_tk = 0;
    p_sys->tk = NULL;
    p_sys->tk_pcr = NULL;
    p_sys->i_ssa_order = 0;
    TAB_INIT( p_sys->i_attachments, p_sys->attachments);
    p_sys->p_title = NULL;

    /* Create I/O wrapper */
    unsigned char * p_io_buffer = av_malloc( AVFORMAT_IOBUFFER_SIZE );
    if( !p_io_buffer )
    {
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }

    p_sys->ic = avformat_alloc_context();
    if( !p_sys->ic )
    {
        av_free( p_io_buffer );
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }

    AVIOContext *pb = p_sys->ic->pb = avio_alloc_context( p_io_buffer,
        AVFORMAT_IOBUFFER_SIZE, 0, p_demux, IORead, NULL, IOSeek );
    if( !pb )
    {
        av_free( p_io_buffer );
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }

    p_sys->ic->pb->seekable = b_can_seek ? AVIO_SEEKABLE_NORMAL : 0;
    error = avformat_open_input(&p_sys->ic, psz_url, p_sys->fmt, NULL);

    if( error < 0 )
    {
        msg_Err( p_demux, "Could not open %s: %s", psz_url,
                 vlc_strerror_c(AVUNERROR(error)) );
        av_free( p_io_buffer );
        av_free( pb );
        p_sys->ic = NULL;
        free( psz_url );
        CloseDemux( p_this );
        return VLC_EGENERIC;
    }
    free( psz_url );

    char *psz_opts = var_InheritString( p_demux, "avformat-options" );
    AVDictionary *options[p_sys->ic->nb_streams ? p_sys->ic->nb_streams : 1];
    options[0] = NULL;
    unsigned int nb_streams = p_sys->ic->nb_streams;
    for (unsigned i = 1; i < nb_streams; i++)
        options[i] = NULL;
    if (psz_opts) {
        vlc_av_get_options(psz_opts, &options[0]);
        for (unsigned i = 1; i < nb_streams; i++) {
            av_dict_copy(&options[i], options[0], 0);
        }
        free(psz_opts);
    }
    vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
    error = avformat_find_stream_info( p_sys->ic, options );
    /* FIXME: what if nb_streams change after that call? */
    vlc_avcodec_unlock();
    AVDictionaryEntry *t = NULL;
    while ((t = av_dict_get(options[0], "", t, AV_DICT_IGNORE_SUFFIX))) {
        msg_Err( p_demux, "Unknown option \"%s\"", t->key );
    }
    av_dict_free(&options[0]);
    for (unsigned i = 1; i < nb_streams; i++) {
        av_dict_free(&options[i]);
    }

    if( error < 0 )
    {
        msg_Warn( p_demux, "Could not find stream info: %s",
                  vlc_strerror_c(AVUNERROR(error)) );
    }

    for( unsigned i = 0; i < p_sys->ic->nb_streams; i++ )
    {
        AVStream *s = p_sys->ic->streams[i];
        const AVCodecParameters *cp = s->codecpar;
        es_out_id_t  *es = NULL;
        es_format_t es_fmt;
        const char *psz_type = "unknown";

        /* Do not use the cover art as a stream */
        if( s->disposition == AV_DISPOSITION_ATTACHED_PIC )
        {
            TAB_APPEND( p_sys->i_tk, p_sys->tk, NULL );
            continue;
        }

        vlc_fourcc_t fcc = GetVlcFourcc( cp->codec_id );
        switch( cp->codec_type )
        {
        case AVMEDIA_TYPE_AUDIO:
            es_format_Init( &es_fmt, AUDIO_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
            es_fmt.i_bitrate = cp->bit_rate;
            es_fmt.audio.i_channels = cp->channels;
            es_fmt.audio.i_rate = cp->sample_rate;
            es_fmt.audio.i_bitspersample = cp->bits_per_coded_sample;
            es_fmt.audio.i_blockalign = cp->block_align;
            psz_type = "audio";

            if(cp->codec_id == AV_CODEC_ID_AAC_LATM)
            {
                es_fmt.i_original_fourcc = VLC_FOURCC('L','A','T','M');
                es_fmt.b_packetized = false;
            }
            else if(cp->codec_id == AV_CODEC_ID_AAC &&
                    strstr(p_sys->fmt->long_name, "raw ADTS AAC"))
            {
                es_fmt.i_original_fourcc = VLC_FOURCC('A','D','T','S');
                es_fmt.b_packetized = false;
            }
            break;

        case AVMEDIA_TYPE_VIDEO:
            es_format_Init( &es_fmt, VIDEO_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );

            es_fmt.video.i_bits_per_pixel = cp->bits_per_coded_sample;
            /* Special case for raw video data */
            if( cp->codec_id == AV_CODEC_ID_RAWVIDEO )
            {
                msg_Dbg( p_demux, "raw video, pixel format: %i", cp->format );
                if( GetVlcChroma( &es_fmt.video, cp->format ) != VLC_SUCCESS)
                {
                    msg_Err( p_demux, "was unable to find a FourCC match for raw video" );
                }
                else
                    es_fmt.i_codec = es_fmt.video.i_chroma;
            }
            /* We need this for the h264 packetizer */
            else if( cp->codec_id == AV_CODEC_ID_H264 && ( p_sys->fmt == av_find_input_format("flv") ||
                p_sys->fmt == av_find_input_format("matroska") || p_sys->fmt == av_find_input_format("mp4") ) )
                es_fmt.i_original_fourcc = VLC_FOURCC( 'a', 'v', 'c', '1' );

            es_fmt.video.i_width = cp->width;
            es_fmt.video.i_height = cp->height;
            es_fmt.video.i_visible_width = es_fmt.video.i_width;
            es_fmt.video.i_visible_height = es_fmt.video.i_height;

            get_rotation(&es_fmt, s);

# warning FIXME: implement palette transmission
            psz_type = "video";
            es_fmt.video.i_frame_rate = s->codec->time_base.num;
            es_fmt.video.i_frame_rate_base = s->codec->time_base.den * __MAX( s->codec->ticks_per_frame, 1 );
            es_fmt.video.i_sar_num = s->sample_aspect_ratio.num;
            if (s->sample_aspect_ratio.num > 0)
                es_fmt.video.i_sar_den = s->sample_aspect_ratio.den;
            else
                es_fmt.video.i_sar_den = 0;
            break;

        case AVMEDIA_TYPE_SUBTITLE:
            es_format_Init( &es_fmt, SPU_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
            if( strncmp( p_sys->ic->iformat->name, "matroska", 8 ) == 0 &&
                cp->codec_id == AV_CODEC_ID_DVD_SUBTITLE &&
                cp->extradata != NULL &&
                cp->extradata_size > 0 )
            {
                char *psz_start;
                char *psz_buf = malloc( cp->extradata_size + 1);
                if( psz_buf != NULL )
                {
                    memcpy( psz_buf, cp->extradata , cp->extradata_size );
                    psz_buf[cp->extradata_size] = '\0';

                    psz_start = strstr( psz_buf, "size:" );
                    if( psz_start &&
                        vobsub_size_parse( psz_start,
                                           &es_fmt.subs.spu.i_original_frame_width,
                                           &es_fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
                    {
                        msg_Dbg( p_demux, "original frame size: %dx%d",
                                 es_fmt.subs.spu.i_original_frame_width,
                                 es_fmt.subs.spu.i_original_frame_height );
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original frame size failed" );
                    }

                    psz_start = strstr( psz_buf, "palette:" );
                    if( psz_start &&
                        vobsub_palette_parse( psz_start, &es_fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
                    {
                        es_fmt.subs.spu.palette[0] = SPU_PALETTE_DEFINED;
                        msg_Dbg( p_demux, "vobsub palette read" );
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original palette failed" );
                    }
                    free( psz_buf );
                }
            }

            psz_type = "subtitle";
            break;

        default:
            es_format_Init( &es_fmt, UNKNOWN_ES, 0 );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
            if( cp->codec_type == AVMEDIA_TYPE_ATTACHMENT )
            {
                input_attachment_t *p_attachment;

                psz_type = "attachment";
                if( cp->codec_id == AV_CODEC_ID_TTF )
                {
                    AVDictionaryEntry *filename = av_dict_get( s->metadata, "filename", NULL, 0 );
                    if( filename && filename->value )
                    {
                        p_attachment = vlc_input_attachment_New(
                                filename->value, "application/x-truetype-font",
                                NULL, cp->extradata, (int)cp->extradata_size );
                        if( p_attachment )
                            TAB_APPEND( p_sys->i_attachments, p_sys->attachments,
                                        p_attachment );
                    }
                }
                else msg_Warn( p_demux, "unsupported attachment type (%u) in avformat demux", cp->codec_id );
            }
            else
#endif
            {
                if( cp->codec_type == AVMEDIA_TYPE_DATA )
                    psz_type = "data";

                msg_Warn( p_demux, "unsupported track type (%u:%u) in avformat demux", cp->codec_type, cp->codec_id );
            }
            break;
        }

        AVDictionaryEntry *language = av_dict_get( s->metadata, "language", NULL, 0 );
        if ( language && language->value )
            es_fmt.psz_language = strdup( language->value );

        if( s->disposition & AV_DISPOSITION_DEFAULT )
            es_fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + 1000;

#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
        if( cp->codec_type != AVMEDIA_TYPE_ATTACHMENT )
#endif
        if( cp->codec_type != AVMEDIA_TYPE_DATA )
        {
            const bool    b_ogg = !strcmp( p_sys->fmt->name, "ogg" );
            const uint8_t *p_extra = cp->extradata;
            unsigned      i_extra  = cp->extradata_size;

            if( cp->codec_id == AV_CODEC_ID_THEORA && b_ogg )
            {
                unsigned pi_size[3];
                const void *pp_data[3];
                unsigned i_count;
                for( i_count = 0; i_count < 3; i_count++ )
                {
                    if( i_extra < 2 )
                        break;
                    pi_size[i_count] = GetWBE( p_extra );
                    pp_data[i_count] = &p_extra[2];
                    if( i_extra < pi_size[i_count] + 2 )
                        break;

                    p_extra += 2 + pi_size[i_count];
                    i_extra -= 2 + pi_size[i_count];
                }
                if( i_count > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
                                                     pi_size, pp_data, i_count ) )
                {
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
                }
            }
            else if( cp->codec_id == AV_CODEC_ID_SPEEX && b_ogg )
            {
                const uint8_t p_dummy_comment[] = {
                    0, 0, 0, 0,
                    0, 0, 0, 0,
                };
                unsigned pi_size[2];
                const void *pp_data[2];

                pi_size[0] = i_extra;
                pp_data[0] = p_extra;

                pi_size[1] = sizeof(p_dummy_comment);
                pp_data[1] = p_dummy_comment;

                if( pi_size[0] > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
                                                        pi_size, pp_data, 2 ) )
                {
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
                }
            }
            else if( cp->codec_id == AV_CODEC_ID_OPUS )
            {
                const uint8_t p_dummy_comment[] = {
                    'O', 'p', 'u', 's',
                    'T', 'a', 'g', 's',
                    0, 0, 0, 0, /* Vendor String length */
                                /* Vendor String */
                    0, 0, 0, 0, /* User Comment List Length */

                };
                unsigned pi_size[2];
                const void *pp_data[2];

                pi_size[0] = i_extra;
                pp_data[0] = p_extra;

                pi_size[1] = sizeof(p_dummy_comment);
                pp_data[1] = p_dummy_comment;

                if( pi_size[0] > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
                                                        pi_size, pp_data, 2 ) )
                {
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
                }
            }
            else if( cp->extradata_size > 0 )
            {
                es_fmt.p_extra = malloc( i_extra );
                if( es_fmt.p_extra )
                {
                    es_fmt.i_extra = i_extra;
                    memcpy( es_fmt.p_extra, p_extra, i_extra );
                }
            }
            es = es_out_Add( p_demux->out, &es_fmt );
            if( s->disposition & AV_DISPOSITION_DEFAULT )
                es_out_Control( p_demux->out, ES_OUT_SET_ES_DEFAULT, es );
            es_format_Clean( &es_fmt );

            msg_Dbg( p_demux, "adding es: %s codec = %4.4s (%d)",
                     psz_type, (char*)&fcc, cp->codec_id  );
        }
        TAB_APPEND( p_sys->i_tk, p_sys->tk, es );
    }
    p_sys->tk_pcr = xcalloc( p_sys->i_tk, sizeof(*p_sys->tk_pcr) );

    if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
        i_start_time = p_sys->ic->start_time * 1000000 / AV_TIME_BASE;

    msg_Dbg( p_demux, "AVFormat(%s %s) supported stream", AVPROVIDER(LIBAVFORMAT), LIBAVFORMAT_IDENT );
    msg_Dbg( p_demux, "    - format = %s (%s)",
             p_sys->fmt->name, p_sys->fmt->long_name );
    msg_Dbg( p_demux, "    - start time = %"PRId64, i_start_time );
    msg_Dbg( p_demux, "    - duration = %"PRId64,
             ( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE ) ?
             p_sys->ic->duration * 1000000 / AV_TIME_BASE : -1 );

    if( p_sys->ic->nb_chapters > 0 )
    {
        p_sys->p_title = vlc_input_title_New();
        p_sys->p_title->i_length = p_sys->ic->duration * 1000000 / AV_TIME_BASE;
    }

    for( unsigned i = 0; i < p_sys->ic->nb_chapters; i++ )
    {
        seekpoint_t *s = vlc_seekpoint_New();

        AVDictionaryEntry *title = av_dict_get( p_sys->ic->metadata, "title", NULL, 0);
        if( title && title->value )
        {
            s->psz_name = strdup( title->value );
            EnsureUTF8( s->psz_name );
            msg_Dbg( p_demux, "    - chapter %d: %s", i, s->psz_name );
        }
        s->i_time_offset = p_sys->ic->chapters[i]->start * 1000000 *
            p_sys->ic->chapters[i]->time_base.num /
            p_sys->ic->chapters[i]->time_base.den -
            (i_start_time != -1 ? i_start_time : 0 );
        TAB_APPEND( p_sys->p_title->i_seekpoint, p_sys->p_title->seekpoint, s );
    }

    ResetTime( p_demux, 0 );
    return VLC_SUCCESS;
}