Exemplo n.º 1
0
static int AVI_ChunkRead_indx( stream_t *s, avi_chunk_t *p_chk )
{
    unsigned int i_count, i;
    int32_t      i_dummy;
    avi_chunk_indx_t *p_indx = (avi_chunk_indx_t*)p_chk;

    AVI_READCHUNK_ENTER;

    AVI_READ2BYTES( p_indx->i_longsperentry );
    AVI_READ1BYTE ( p_indx->i_indexsubtype );
    AVI_READ1BYTE ( p_indx->i_indextype );
    AVI_READ4BYTES( p_indx->i_entriesinuse );

    AVI_READ4BYTES( p_indx->i_id );
    p_indx->idx.std     = NULL;
    p_indx->idx.field   = NULL;
    p_indx->idx.super   = NULL;

    if( p_indx->i_indextype == AVI_INDEX_OF_CHUNKS && p_indx->i_indexsubtype == 0 )
    {
        AVI_READ8BYTES( p_indx->i_baseoffset );
        AVI_READ4BYTES( i_dummy );

        i_count = __MIN( p_indx->i_entriesinuse, i_read / 8 );
        p_indx->i_entriesinuse = i_count;
        p_indx->idx.std = xcalloc( i_count, sizeof( indx_std_entry_t ) );

        for( i = 0; i < i_count; i++ )
        {
            AVI_READ4BYTES( p_indx->idx.std[i].i_offset );
            AVI_READ4BYTES( p_indx->idx.std[i].i_size );
        }
    }
    else if( p_indx->i_indextype == AVI_INDEX_OF_CHUNKS && p_indx->i_indexsubtype == AVI_INDEX_2FIELD )
    {
        AVI_READ8BYTES( p_indx->i_baseoffset );
        AVI_READ4BYTES( i_dummy );

        i_count = __MIN( p_indx->i_entriesinuse, i_read / 12 );
        p_indx->i_entriesinuse = i_count;
        p_indx->idx.field = xcalloc( i_count, sizeof( indx_field_entry_t ) );
        for( i = 0; i < i_count; i++ )
        {
            AVI_READ4BYTES( p_indx->idx.field[i].i_offset );
            AVI_READ4BYTES( p_indx->idx.field[i].i_size );
            AVI_READ4BYTES( p_indx->idx.field[i].i_offsetfield2 );
        }
    }
    else if( p_indx->i_indextype == AVI_INDEX_OF_INDEXES )
    {
        p_indx->i_baseoffset = 0;
        AVI_READ4BYTES( i_dummy );
        AVI_READ4BYTES( i_dummy );
        AVI_READ4BYTES( i_dummy );

        i_count = __MIN( p_indx->i_entriesinuse, i_read / 16 );
        p_indx->i_entriesinuse = i_count;
        p_indx->idx.super = xcalloc( i_count, sizeof( indx_super_entry_t ) );

        for( i = 0; i < i_count; i++ )
        {
            AVI_READ8BYTES( p_indx->idx.super[i].i_offset );
            AVI_READ4BYTES( p_indx->idx.super[i].i_size );
            AVI_READ4BYTES( p_indx->idx.super[i].i_duration );
        }
    }
    else
    {
        msg_Warn( (vlc_object_t*)s, "unknown type/subtype index" );
    }

#ifdef AVI_DEBUG
    msg_Dbg( (vlc_object_t*)s, "indx: type=%d subtype=%d entry=%d", p_indx->i_indextype, p_indx->i_indexsubtype, p_indx->i_entriesinuse );
#endif
    AVI_READCHUNK_EXIT( VLC_SUCCESS );
}
Exemplo n.º 2
0
/*****************************************************************************
 * ffmpeg_OpenCodec:
 *****************************************************************************/
int ffmpeg_OpenCodec( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    if( p_sys->p_context->extradata_size <= 0 )
    {
        if( p_sys->i_codec_id == CODEC_ID_VC1 ||
            p_sys->i_codec_id == CODEC_ID_VORBIS ||
            p_sys->i_codec_id == CODEC_ID_THEORA ||
            p_sys->i_codec_id == CODEC_ID_AAC )
        {
            msg_Warn( p_dec, "waiting for extra data for codec %s",
                      p_sys->psz_namecodec );
            return 1;
        }
    }
    if( p_dec->fmt_in.i_cat == VIDEO_ES )
    {
        p_sys->p_context->width  = p_dec->fmt_in.video.i_width;
        p_sys->p_context->height = p_dec->fmt_in.video.i_height;
        p_sys->p_context->bits_per_coded_sample = p_dec->fmt_in.video.i_bits_per_pixel;
    }
    else if( p_dec->fmt_in.i_cat == AUDIO_ES )
    {
        p_sys->p_context->sample_rate = p_dec->fmt_in.audio.i_rate;
        p_sys->p_context->channels = p_dec->fmt_in.audio.i_channels;

        p_sys->p_context->block_align = p_dec->fmt_in.audio.i_blockalign;
        p_sys->p_context->bit_rate = p_dec->fmt_in.i_bitrate;
        p_sys->p_context->bits_per_coded_sample = p_dec->fmt_in.audio.i_bitspersample;
    }
    int ret;
    vlc_avcodec_lock();
    ret = avcodec_open( p_sys->p_context, p_sys->p_codec );
    vlc_avcodec_unlock();
    if( ret < 0 )
        return VLC_EGENERIC;
    msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );

#ifdef HAVE_AVCODEC_MT
    if( p_dec->fmt_in.i_cat == VIDEO_ES )
    {
        switch( p_sys->p_context->active_thread_type )
        {
            case FF_THREAD_FRAME:
                msg_Dbg( p_dec, "using frame thread mode with %d threads",
                         p_sys->p_context->thread_count );
                break;
            case FF_THREAD_SLICE:
                msg_Dbg( p_dec, "using slice thread mode with %d threads",
                         p_sys->p_context->thread_count );
                break;
            case 0:
                if( p_sys->p_context->thread_count > 1 )
                    msg_Warn( p_dec, "failed to enable threaded decoding" );
                break;
            default:
                msg_Warn( p_dec, "using unknown thread mode with %d threads",
                          p_sys->p_context->thread_count );
                break;
        }
    }
#endif

    p_sys->b_delayed_open = false;

    return VLC_SUCCESS;
}
Exemplo n.º 3
0
static void OutputFrame( sout_stream_sys_t *p_sys, picture_t *p_pic, bool b_need_duplicate, sout_stream_t *p_stream, sout_stream_id_t *id, block_t **out )
{
    picture_t *p_pic2 = NULL;

    /*
     * Encoding
     */

    /* Check if we have a subpicture to overlay */
    if( p_sys->p_spu )
    {
        video_format_t fmt = id->p_encoder->fmt_in.video;
        if( fmt.i_visible_width <= 0 || fmt.i_visible_height <= 0 )
        {
            fmt.i_visible_width  = fmt.i_width;
            fmt.i_visible_height = fmt.i_height;
            fmt.i_x_offset       = 0;
            fmt.i_y_offset       = 0;
        }

        subpicture_t *p_subpic = spu_Render( p_sys->p_spu, NULL, &fmt, &fmt,
                                             p_pic->date, p_pic->date, false );

        /* Overlay subpicture */
        if( p_subpic )
        {
            if( picture_IsReferenced( p_pic ) && !filter_chain_GetLength( id->p_f_chain ) )
            {
                /* We can't modify the picture, we need to duplicate it,
                 * in this point the picture is already p_encoder->fmt.in format*/
                picture_t *p_tmp = video_new_buffer_encoder( id->p_encoder );
                if( likely( p_tmp ) )
                {
                    picture_Copy( p_tmp, p_pic );
                    picture_Release( p_pic );
                    p_pic = p_tmp;
                }
            }
            if( unlikely( !p_sys->p_spu_blend ) )
                p_sys->p_spu_blend = filter_NewBlend( VLC_OBJECT( p_sys->p_spu ), &fmt );
            if( likely( p_sys->p_spu_blend ) )
                picture_BlendSubpicture( p_pic, p_sys->p_spu_blend, p_subpic );
            subpicture_Delete( p_subpic );
        }
    }

    if( p_sys->i_threads == 0 )
    {
        block_t *p_block;

        p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
        block_ChainAppend( out, p_block );
    }

    if( p_sys->b_master_sync )
    {
        mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
        mtime_t i_video_drift = p_pic->date - i_pts;
        if (unlikely ( i_video_drift  > MASTER_SYNC_MAX_DRIFT
              || i_video_drift < -MASTER_SYNC_MAX_DRIFT ) )
        {
            msg_Dbg( p_stream,
                "video drift is too high (%"PRId64"), resetting master sync",
                i_video_drift );
            date_Set( &id->interpolated_pts, p_pic->date );
            i_pts = p_pic->date + 1;
        }
        date_Increment( &id->interpolated_pts, 1 );

        if( unlikely( b_need_duplicate ) )
        {

           if( p_sys->i_threads >= 1 )
           {
               /* We can't modify the picture, we need to duplicate it */
               p_pic2 = video_new_buffer_encoder( id->p_encoder );
               if( likely( p_pic2 != NULL ) )
               {
                   picture_Copy( p_pic2, p_pic );
                   p_pic2->date = i_pts;
               }
           }
           else
           {
               block_t *p_block;
               p_pic->date = i_pts;
               p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
               block_ChainAppend( out, p_block );
           }
       }
    }

    if( p_sys->i_threads == 0 )
    {
        picture_Release( p_pic );
    }
    else
    {
        vlc_mutex_lock( &p_sys->lock_out );
        picture_fifo_Push( p_sys->pp_pics, p_pic );
        if( p_pic2 != NULL )
        {
            picture_fifo_Push( p_sys->pp_pics, p_pic2 );
        }
        vlc_cond_signal( &p_sys->cond );
        vlc_mutex_unlock( &p_sys->lock_out );
    }
}
Exemplo n.º 4
0
Arquivo: access.c Projeto: Adatan/vlc
/*****************************************************************************
 * Open: Initialize module's data structures and libdsm
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    access_t     *p_access = (access_t*)p_this;
    access_sys_t *p_sys;
    smb_stat st;

    /* Init p_access */
    access_InitFields( p_access );
    p_sys = p_access->p_sys = (access_sys_t*)calloc( 1, sizeof( access_sys_t ) );
    if( p_access->p_sys == NULL )
        return VLC_ENOMEM;

    p_sys->p_ns = netbios_ns_new();
    if( p_sys->p_ns == NULL )
        goto error;

    p_sys->p_session = smb_session_new();
    if( p_sys->p_session == NULL )
        goto error;

    vlc_UrlParse( &p_sys->url, p_access->psz_location, 0 );
    get_credentials( p_access );
    if( get_address( p_access ) != VLC_SUCCESS )
        goto error;

    msg_Dbg( p_access, "Creds: username = %s, domain = %s",
             p_sys->creds.login, p_sys->creds.domain );
    msg_Dbg( p_access, "Session: Host name = %s, ip = %s", p_sys->netbios_name,
             inet_ntoa( p_sys->addr ) );

    /* Now that we have the required data, let's establish a session */
    if( !smb_session_connect( p_sys->p_session, p_sys->netbios_name,
                              p_sys->addr.s_addr, SMB_TRANSPORT_TCP ) )
    {
        msg_Err( p_access, "Unable to connect/negotiate SMB session");
        goto error;
    }

    get_path( p_access );

    if( login( p_access ) != VLC_SUCCESS )
    {
        msg_Err( p_access, "Unable to connect to share %s", p_sys->psz_share );
        goto error;
    }

    /* If there is no shares, browse them */
    if( !p_sys->psz_share )
        return BrowserInit( p_access );

    msg_Dbg( p_access, "Path: Share name = %s, path = %s", p_sys->psz_share,
             p_sys->psz_path );

    /* Let's finally ask a handle to the file we wanna read ! */
    p_sys->i_fd = smb_fopen( p_sys->p_session, p_sys->i_tid, p_sys->psz_path,
                             SMB_MOD_RO );
    if( !p_sys->i_fd )
    {
        msg_Err( p_access, "Unable to open file with path %s (in share %s)",
                 p_sys->psz_path, p_sys->psz_share );
        goto error;
    }

    st = smb_stat_fd( p_sys->p_session, p_sys->i_fd );
    if( smb_stat_get( st, SMB_STAT_ISDIR ) )
    {
        smb_fclose( p_sys->p_session, p_sys->i_fd );
        return BrowserInit( p_access );
    }

    msg_Dbg( p_access, "Successfully opened smb://%s", p_access->psz_location );

    ACCESS_SET_CALLBACKS( Read, NULL, Control, Seek );
    return VLC_SUCCESS;

    error:
        Close( p_this );
        return VLC_EGENERIC;
}
Exemplo n.º 5
0
/*****************************************************************************
 * Open: open the rtsp connection
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    access_t *p_access = (access_t *)p_this;
    access_sys_t *p_sys;
    char* psz_server = NULL;
    int i_result;

    if( !p_access->psz_access || (
        strncmp( p_access->psz_access, "rtsp", 4 ) &&
        strncmp( p_access->psz_access, "pnm", 3 )  &&
        strncmp( p_access->psz_access, "realrtsp", 8 ) ))
    {
            return VLC_EGENERIC;
    }

    p_access->pf_read = NULL;
    p_access->pf_block = BlockRead;
    p_access->pf_seek = Seek;
    p_access->pf_control = Control;
    p_access->info.i_update = 0;
    p_access->info.i_size = 0;
    p_access->info.i_pos = 0;
    p_access->info.b_eof = false;
    p_access->info.i_title = 0;
    p_access->info.i_seekpoint = 0;
    p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;
    p_sys->p_rtsp = malloc( sizeof( rtsp_client_t) );
    if( !p_sys->p_rtsp )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }

    p_sys->p_header = NULL;
    p_sys->p_rtsp->p_userdata = p_access;
    p_sys->p_rtsp->pf_connect = RtspConnect;
    p_sys->p_rtsp->pf_disconnect = RtspDisconnect;
    p_sys->p_rtsp->pf_read = RtspRead;
    p_sys->p_rtsp->pf_read_line = RtspReadLine;
    p_sys->p_rtsp->pf_write = RtspWrite;

    i_result = rtsp_connect( p_sys->p_rtsp, p_access->psz_path, 0 );
    if( i_result )
    {
        msg_Dbg( p_access, "could not connect to: %s", p_access->psz_path );
        free( p_sys->p_rtsp );
        p_sys->p_rtsp = NULL;
        goto error;
    }

    msg_Dbg( p_access, "rtsp connected" );

    /* looking for server type */
    if( rtsp_search_answers( p_sys->p_rtsp, "Server" ) )
        psz_server = strdup( rtsp_search_answers( p_sys->p_rtsp, "Server" ) );
    else
    {
        if( rtsp_search_answers( p_sys->p_rtsp, "RealChallenge1" ) )
            psz_server = strdup("Real");
        else
            psz_server = strdup("unknown");
    }

    if( strstr( psz_server, "Real" ) || strstr( psz_server, "Helix" ) )
    {
        uint32_t bandwidth = 10485800;
        rmff_header_t *h;

        msg_Dbg( p_access, "found a real/helix rtsp server" );

        if( !(h = real_setup_and_get_header( p_sys->p_rtsp, bandwidth )) )
        {
            /* Check if we got a redirect */
            if( rtsp_search_answers( p_sys->p_rtsp, "Location" ) )
            {
                msg_Dbg( p_access, "redirect: %s",
                         rtsp_search_answers(p_sys->p_rtsp, "Location") );
                msg_Warn( p_access, "redirect not supported" );
                goto error;
            }


            msg_Err( p_access, "rtsp session can not be established" );
            dialog_Fatal( p_access, _("Session failed"), "%s",
                    _("The requested RTSP session could not be established.") );
            goto error;
        }

        p_sys->p_header = block_New( p_access, 4096 );
        p_sys->p_header->i_buffer =
            rmff_dump_header( h, (char *)p_sys->p_header->p_buffer, 1024 );
        rmff_free_header( h );
    }
    else
    {
        msg_Warn( p_access, "only real/helix rtsp servers supported for now" );
        goto error;
    }

    /* Update default_pts to a suitable value for file access */
    var_Create( p_access, "realrtsp-caching",
                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);

    free( psz_server );
    return VLC_SUCCESS;

 error:
    free( psz_server );
    Close( p_this );
    return VLC_EGENERIC;
}
Exemplo n.º 6
0
Arquivo: smooth.c Projeto: Adatan/vlc
static chunk_t *get_chunk( stream_t *s, const bool wait, bool *pb_isinit )
{
    stream_sys_t *p_sys = s->p_sys;

    bool b_foo;
    if ( !pb_isinit )
        pb_isinit = &b_foo;

    *pb_isinit = false;

    vlc_mutex_lock( &p_sys->lock );

    assert(p_sys->p_current_stream);
    chunk_t *p_chunk = p_sys->p_current_stream->p_playback;

    /* init chunk handling, overrides the current one */
    vlc_mutex_lock( &p_sys->playback.lock );
    if ( p_sys->playback.init.p_datachunk )
    {
        if ( p_sys->playback.init.p_startchunk == NULL ||
             p_sys->playback.init.p_startchunk == p_chunk )
        {
            /* Override current chunk and pass init chunk instead */
            p_chunk = p_sys->playback.init.p_datachunk;
            *pb_isinit = true;
            setChunkOffset( p_sys, p_chunk );
#ifndef NDEBUG
            if ( !p_chunk->read_pos )
                msg_Dbg( s, "Sending init chunk from offset %"PRId64, p_chunk->offset );
#endif
            vlc_mutex_unlock( &p_sys->playback.lock );
            vlc_mutex_unlock( &p_sys->lock );
            return p_chunk;
        }
    }
    vlc_mutex_unlock( &p_sys->playback.lock );
    /* !init chunk handling */

    vlc_mutex_lock( &p_sys->p_current_stream->chunks_lock );
    vlc_mutex_unlock( &p_sys->lock );

    while( p_chunk && !p_chunk->data )
    {
        /* Yes I know, checking for p_sys->b_die is not reliable,
         * that's why vlc_object_alive() has been deprecated. But if I
         * understood well, there is no good solution with a stream_filter
         * module anyaway. */
        if( !wait || p_sys->b_error )
        {
            msg_Warn( s, "get_chunk failed! (starttime %"PRId64")", p_chunk->start_time );
            vlc_mutex_unlock( &p_sys->p_current_stream->chunks_lock );
            return NULL;
        }

        if( no_more_chunks( p_sys ) )
        {
            msg_Info( s, "No more chunks, end of the VOD" );
            vlc_mutex_unlock( &p_sys->p_current_stream->chunks_lock );
            return NULL;
        }

        msg_Dbg( s, "get_chunk is waiting for chunk %"PRId64"!!!", p_chunk->start_time );
        vlc_mutex_lock( &p_sys->playback.lock );
        p_sys->playback.b_underrun = true;
        vlc_mutex_unlock( &p_sys->playback.lock );
        vlc_cond_timedwait( &p_sys->playback.wait,
                &p_sys->p_current_stream->chunks_lock, mdate() + CLOCK_FREQ/2 );
    }

    if ( p_chunk )
    {
        setChunkOffset( p_sys, p_chunk );
#ifndef NDEBUG
        if ( !p_chunk->read_pos )
            msg_Dbg( s, "Sending chunk %"PRId64" from offset %"PRId64, p_chunk->start_time, p_chunk->offset );
#endif
    }
    vlc_mutex_unlock( &p_sys->p_current_stream->chunks_lock );

    return p_chunk;
}
Exemplo n.º 7
0
static void config_ReadFile( char *psz_file )
{
    FILE *p_file;
    char psz_line[2048];
    int i;

    if ( psz_file == NULL )
    {
        msg_Err( NULL, "no config file" );
        return;
    }

    if ( (p_file = fopen( psz_file, "r" )) == NULL )
    {
        msg_Err( NULL, "can't fopen config file %s", psz_file );
        return;
    }

    while ( fgets( psz_line, sizeof(psz_line), p_file ) != NULL )
    {
        output_config_t config;
        output_t *p_output;
        char *psz_token, *psz_parser;

        psz_parser = strchr( psz_line, '#' );
        if ( psz_parser != NULL )
            *psz_parser-- = '\0';
        while ( psz_parser >= psz_line && isblank( *psz_parser ) )
            *psz_parser-- = '\0';
        if ( psz_line[0] == '\0' )
            continue;

        config_Defaults( &config );

        psz_token = strtok_r( psz_line, "\t\n ", &psz_parser );
        if ( psz_token == NULL || !config_ParseHost( &config, psz_token ))
        {
            config_Free( &config );
            continue;
        }

        psz_token = strtok_r( NULL, "\t\n ", &psz_parser );
        if ( psz_token == NULL )
        {
            config_Free( &config );
            continue;
        }
        if( atoi( psz_token ) == 1 )
            config.i_config |= OUTPUT_WATCH;
        else
            config.i_config &= ~OUTPUT_WATCH;

        psz_token = strtok_r( NULL, "\t\n ", &psz_parser );
        if ( psz_token == NULL )
        {
            config_Free( &config );
            continue;
        }
        config.i_sid = strtol(psz_token, NULL, 0);

        psz_token = strtok_r( NULL, "\t\n ", &psz_parser );
        if ( psz_token != NULL )
        {
            psz_parser = NULL;
            for ( ; ; )
            {
                psz_token = strtok_r( psz_token, ",", &psz_parser );
                if ( psz_token == NULL )
                    break;
                config.pi_pids = realloc( config.pi_pids,
                                 (config.i_nb_pids + 1) * sizeof(uint16_t) );
                config.pi_pids[config.i_nb_pids++] = strtol(psz_token, NULL, 0);
                psz_token = NULL;
            }
        }

        config_Print( &config );

        p_output = output_Find( &config );

        if ( p_output == NULL )
            p_output = output_Create( &config );

        if ( p_output != NULL )
        {
            free( p_output->config.psz_displayname );
            p_output->config.psz_displayname = strdup( config.psz_displayname );

            config.i_config |= OUTPUT_VALID | OUTPUT_STILL_PRESENT;
            output_Change( p_output, &config );
            demux_Change( p_output, &config );
        }

        config_Free( &config );
    }

    fclose( p_file );

    for ( i = 0; i < i_nb_outputs; i++ )
    {
        output_t *p_output = pp_outputs[i];
        output_config_t config;

        config_Init( &config );

        if ( (p_output->config.i_config & OUTPUT_VALID) &&
             !(p_output->config.i_config & OUTPUT_STILL_PRESENT) )
        {
            msg_Dbg( NULL, "closing %s", p_output->config.psz_displayname );
            demux_Change( p_output, &config );
            output_Close( p_output );
        }

        p_output->config.i_config &= ~OUTPUT_STILL_PRESENT;
        config_Free( &config );
    }
}
Exemplo n.º 8
0
/**
 * It loads the logo images into memory.
 *
 * Read the logo-file input switch, obtaining a list of images and
 * associated durations and transparencies. Store the image(s), and
 * times. An image without a stated time or opacity will use the
 * logo-delay and logo-opacity values.
 */
static void LogoListLoad( vlc_object_t *p_this, logo_list_t *p_logo_list,
                          const char *psz_filename )
{
    char *psz_list; /* the list: <logo>[,[<delay>[,[<alpha>]]]][;...] */
    char *psz_original;
    unsigned int i;
    logo_t *p_logo;         /* the parsing's result */

    p_logo_list->i_counter = 0;
    p_logo_list->i_next_pic = 0;

    psz_original = psz_list = strdup( psz_filename );
    if( !psz_list )
        abort();

    /* Count the number logos == number of ';' + 1 */
    p_logo_list->i_count = 1;
    for( i = 0; i < strlen( psz_list ); i++ )
    {
        if( psz_list[i] == ';' )
            p_logo_list->i_count++;
    }

    p_logo_list->p_logo =
    p_logo              = (logo_t *)calloc( p_logo_list->i_count, sizeof(*p_logo) );			// sunqueen modify
    if( !p_logo )
        abort();

    /* Fill the data */
    for( i = 0; i < p_logo_list->i_count; i++ )
    {
        char *p_c  = strchr( psz_list, ';' );
        char *p_c2 = strchr( psz_list, ',' );

        p_logo[i].i_alpha = -1; /* use default settings */
        p_logo[i].i_delay = -1; /* use default settings */

        if( p_c2 && ( p_c2 < p_c || !p_c ) )
        {
            /* <logo>,<delay>[,<alpha>] type */
            if( p_c2[1] != ',' && p_c2[1] != ';' && p_c2[1] != '\0' )
                p_logo[i].i_delay = atoi( p_c2+1 );
            *p_c2 = '\0';
            if( ( p_c2 = strchr( p_c2+1, ',' ) )
                && ( p_c2 < p_c || !p_c ) && p_c2[1] != ';' && p_c2[1] != '\0' )
                p_logo[i].i_alpha = atoi( p_c2 + 1 );
        }
        else
        {
            /* <logo> type */
            if( p_c )
                *p_c = '\0';
        }

        msg_Dbg( p_this, "logo file name %s, delay %d, alpha %d",
                 psz_list, p_logo[i].i_delay, p_logo[i].i_alpha );
        p_logo[i].p_pic = LoadImage( p_this, psz_list );
        if( !p_logo[i].p_pic )
        {
            msg_Warn( p_this, "error while loading logo %s, will be skipped",
                      psz_list );
        }

        if( p_c )
            psz_list = &p_c[1];
    }

    /* initialize so that on the first update it will wrap back to 0 */
    p_logo_list->i_counter = p_logo_list->i_count - 1;

    free( psz_original );
}
Exemplo n.º 9
0
Arquivo: video.c Projeto: Jasonic/vlc
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
                                          const enum PixelFormat *pi_fmt )
{
    decoder_t *p_dec = p_context->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;
    vlc_va_t *p_va = p_sys->p_va;

    if( p_va != NULL )
        vlc_va_Delete( p_va );

    /* Enumerate available formats */
    bool can_hwaccel = false;
    for( size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        const AVPixFmtDescriptor *dsc = av_pix_fmt_desc_get(pi_fmt[i]);
        if (dsc == NULL)
            continue;
        bool hwaccel = (dsc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0;

        msg_Dbg( p_dec, "available %sware decoder output format %d (%s)",
                 hwaccel ? "hard" : "soft", pi_fmt[i], dsc->name );
        if (hwaccel)
            can_hwaccel = true;
    }

    if (!can_hwaccel)
        goto end;

    /* Profile and level information is needed now.
     * TODO: avoid code duplication with avcodec.c */
    if( p_context->profile != FF_PROFILE_UNKNOWN)
        p_dec->fmt_in.i_profile = p_context->profile;
    if( p_context->level != FF_LEVEL_UNKNOWN)
        p_dec->fmt_in.i_level = p_context->level;

    p_va = vlc_va_New( VLC_OBJECT(p_dec), p_sys->i_codec_id, &p_dec->fmt_in );
    if( p_va == NULL )
        goto end;

    for( size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        if( p_va->pix_fmt != pi_fmt[i] )
            continue;

        /* We try to call vlc_va_Setup when possible to detect errors when
         * possible (later is too late) */
        if( p_context->width > 0 && p_context->height > 0
         && vlc_va_Setup( p_va, &p_context->hwaccel_context,
                          &p_dec->fmt_out.video.i_chroma,
                          p_context->width, p_context->height ) )
        {
            msg_Err( p_dec, "acceleration setup failure" );
            break;
        }

        if( p_va->description )
            msg_Info( p_dec, "Using %s for hardware decoding.",
                      p_va->description );

        /* FIXME this will disable direct rendering
         * even if a new pixel format is renegotiated
         */
        p_sys->b_direct_rendering = false;
        p_sys->p_va = p_va;
        p_context->draw_horiz_band = NULL;
        return pi_fmt[i];
    }

    vlc_va_Delete( p_va );

end:
    /* Fallback to default behaviour */
    p_sys->p_va = NULL;
    return avcodec_default_get_format( p_context, pi_fmt );
}
Exemplo n.º 10
0
Arquivo: dec.c Projeto: robUx4/vlc
static void aout_DecSynchronize (audio_output_t *aout, mtime_t dec_pts,
                                 int input_rate)
{
    aout_owner_t *owner = aout_owner (aout);
    mtime_t drift;

    /**
     * Depending on the drift between the actual and intended playback times,
     * the audio core may ignore the drift, trigger upsampling or downsampling,
     * insert silence or even discard samples.
     * Future VLC versions may instead adjust the input rate.
     *
     * The audio output plugin is responsible for estimating its actual
     * playback time, or rather the estimated time when the next sample will
     * be played. (The actual playback time is always the current time, that is
     * to say mdate(). It is not an useful statistic.)
     *
     * Most audio output plugins can estimate the delay until playback of
     * the next sample to be written to the buffer, or equally the time until
     * all samples in the buffer will have been played. Then:
     *    pts = mdate() + delay
     */
    if (aout_OutputTimeGet (aout, &drift) != 0)
        return; /* nothing can be done if timing is unknown */
    drift += mdate () - dec_pts;

    /* Late audio output.
     * This can happen due to insufficient caching, scheduling jitter
     * or bug in the decoder. Ideally, the output would seek backward. But that
     * is not portable, not supported by some hardware and often unsafe/buggy
     * where supported. The other alternative is to flush the buffers
     * completely. */
    if (drift > (owner->sync.discontinuity ? 0
                  : +3 * input_rate * AOUT_MAX_PTS_DELAY / INPUT_RATE_DEFAULT))
    {
        if (!owner->sync.discontinuity)
            msg_Warn (aout, "playback way too late (%"PRId64"): "
                      "flushing buffers", drift);
        else
            msg_Dbg (aout, "playback too late (%"PRId64"): "
                     "flushing buffers", drift);
        aout_OutputFlush (aout, false);

        aout_StopResampling (aout);
        owner->sync.end = VLC_TS_INVALID;
        owner->sync.discontinuity = true;

        /* Now the output might be too early... Recheck. */
        if (aout_OutputTimeGet (aout, &drift) != 0)
            return; /* nothing can be done if timing is unknown */
        drift += mdate () - dec_pts;
    }

    /* Early audio output.
     * This is rare except at startup when the buffers are still empty. */
    if (drift < (owner->sync.discontinuity ? 0
                : -3 * input_rate * AOUT_MAX_PTS_ADVANCE / INPUT_RATE_DEFAULT))
    {
        if (!owner->sync.discontinuity)
            msg_Warn (aout, "playback way too early (%"PRId64"): "
                      "playing silence", drift);
        aout_DecSilence (aout, -drift, dec_pts);

        aout_StopResampling (aout);
        owner->sync.discontinuity = true;
        drift = 0;
    }

    /* Resampling */
    if (drift > +AOUT_MAX_PTS_DELAY
     && owner->sync.resamp_type != AOUT_RESAMPLING_UP)
    {
        msg_Warn (aout, "playback too late (%"PRId64"): up-sampling",
                  drift);
        owner->sync.resamp_type = AOUT_RESAMPLING_UP;
        owner->sync.resamp_start_drift = +drift;
    }
    if (drift < -AOUT_MAX_PTS_ADVANCE
     && owner->sync.resamp_type != AOUT_RESAMPLING_DOWN)
    {
        msg_Warn (aout, "playback too early (%"PRId64"): down-sampling",
                  drift);
        owner->sync.resamp_type = AOUT_RESAMPLING_DOWN;
        owner->sync.resamp_start_drift = -drift;
    }

    if (owner->sync.resamp_type == AOUT_RESAMPLING_NONE)
        return; /* Everything is fine. Nothing to do. */

    if (llabs (drift) > 2 * owner->sync.resamp_start_drift)
    {   /* If the drift is ever increasing, then something is seriously wrong.
         * Cease resampling and hope for the best. */
        msg_Warn (aout, "timing screwed (drift: %"PRId64" us): "
                  "stopping resampling", drift);
        aout_StopResampling (aout);
        return;
    }

    /* Resampling has been triggered earlier. This checks if it needs to be
     * increased or decreased. Resampling rate changes must be kept slow for
     * the comfort of listeners. */
    int adj = (owner->sync.resamp_type == AOUT_RESAMPLING_UP) ? +2 : -2;

    if (2 * llabs (drift) <= owner->sync.resamp_start_drift)
        /* If the drift has been reduced from more than half its initial
         * value, then it is time to switch back the resampling direction. */
        adj *= -1;

    if (!aout_FiltersAdjustResampling (owner->filters, adj))
    {   /* Everything is back to normal: stop resampling. */
        owner->sync.resamp_type = AOUT_RESAMPLING_NONE;
        msg_Dbg (aout, "resampling stopped (drift: %"PRId64" us)", drift);
    }
}
Exemplo n.º 11
0
Arquivo: rtp.c Projeto: CSRedRat/vlc
/* see http://www.iana.org/assignments/rtp-parameters */
void rtp_autodetect (demux_t *demux, rtp_session_t *session,
                     const block_t *block)
{
    uint8_t ptype = rtp_ptype (block);
    rtp_pt_t pt = {
        .init = NULL,
        .destroy = codec_destroy,
        .decode = codec_decode,
        .frequency = 0,
        .number = ptype,
    };

    /* Remember to keep this in sync with modules/services_discovery/sap.c */
    switch (ptype)
    {
      case 0:
        msg_Dbg (demux, "detected G.711 mu-law");
        pt.init = pcmu_init;
        pt.frequency = 8000;
        break;

      case 3:
        msg_Dbg (demux, "detected GSM");
        pt.init = gsm_init;
        pt.frequency = 8000;
        break;

      case 8:
        msg_Dbg (demux, "detected G.711 A-law");
        pt.init = pcma_init;
        pt.frequency = 8000;
        break;

      case 10:
        msg_Dbg (demux, "detected stereo PCM");
        pt.init = l16s_init;
        pt.frequency = 44100;
        break;

      case 11:
        msg_Dbg (demux, "detected mono PCM");
        pt.init = l16m_init;
        pt.frequency = 44100;
        break;

      case 12:
        msg_Dbg (demux, "detected QCELP");
        pt.init = qcelp_init;
        pt.frequency = 8000;
        break;

      case 14:
        msg_Dbg (demux, "detected MPEG Audio");
        pt.init = mpa_init;
        pt.decode = mpa_decode;
        pt.frequency = 90000;
        break;

      case 32:
        msg_Dbg (demux, "detected MPEG Video");
        pt.init = mpv_init;
        pt.decode = mpv_decode;
        pt.frequency = 90000;
        break;

      case 33:
        msg_Dbg (demux, "detected MPEG2 TS");
        pt.init = ts_init;
        pt.destroy = stream_destroy;
        pt.decode = stream_decode;
        pt.frequency = 90000;
        break;

      default:
        /*
         * If the rtp payload type is unknown then check demux if it is specified
         */
        if (!strcmp(demux->psz_demux, "h264")
         || !strcmp(demux->psz_demux, "ts"))
        {
            msg_Dbg (demux, "dynamic payload format %s specified by demux",
                     demux->psz_demux);
            pt.init = demux_init;
            pt.destroy = stream_destroy;
            pt.decode = stream_decode;
            pt.frequency = 90000;
            break;
        }
        if (ptype >= 96)
        {
            char *dynamic = var_InheritString(demux, "rtp-dynamic-pt");
            if (dynamic == NULL)
                ;
            else if (!strcmp(dynamic, "theora"))
            {
                msg_Dbg (demux, "assuming Theora Encoded Video");
                pt.init = theora_init;
                pt.destroy = xiph_destroy;
                pt.decode = xiph_decode;
                pt.frequency = 90000;
            }
            else
                msg_Err (demux, "unknown dynamic payload format `%s' "
                                "specified", dynamic);
            free (dynamic);
        }

        msg_Err (demux, "unspecified payload format (type %"PRIu8")", ptype);
        msg_Info (demux, "A valid SDP is needed to parse this RTP stream.");
        dialog_Fatal (demux, N_("SDP required"),
             N_("A description in SDP format is required to receive the RTP "
                "stream. Note that rtp:// URIs cannot work with dynamic "
                "RTP payload format (%"PRIu8")."), ptype);
        return;
    }
    rtp_add_type (demux, session, &pt);
}
Exemplo n.º 12
0
Arquivo: dec.c Projeto: robUx4/vlc
/**
 * Marks the audio output for restart, to update any parameter of the output
 * plug-in (e.g. output device or channel mapping).
 */
void aout_RequestRestart (audio_output_t *aout, unsigned mode)
{
    aout_owner_t *owner = aout_owner (aout);
    atomic_fetch_or (&owner->restart, mode);
    msg_Dbg (aout, "restart requested (%u)", mode);
}
Exemplo n.º 13
0
/*****************************************************************************
 * Open: initializes raw audio demuxer
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys;

    p_demux->p_sys      = p_sys = malloc( sizeof( demux_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;

    char *psz_fourcc = var_CreateGetString( p_demux, "rawaud-fourcc" );
    es_format_Init( &p_sys->fmt, AUDIO_ES,
                    vlc_fourcc_GetCodecFromString( AUDIO_ES, psz_fourcc ) );
    free( psz_fourcc );

    if( !p_sys->fmt.i_codec )
    {
        msg_Err( p_demux, "rawaud-fourcc must be a 4 character string");
        es_format_Clean( &p_sys->fmt );
        free( p_sys );
        return VLC_EGENERIC;
    }

    // get the bits per sample ratio based on codec
    switch( p_sys->fmt.i_codec )
    {

        case VLC_CODEC_FL64:
            p_sys->fmt.audio.i_bitspersample = 64;
            break;

        case VLC_CODEC_FL32:
        case VLC_CODEC_S32L:
        case VLC_CODEC_S32B:
            p_sys->fmt.audio.i_bitspersample = 32;
            break;

        case VLC_CODEC_S24L:
        case VLC_CODEC_S24B:
            p_sys->fmt.audio.i_bitspersample = 24;
            break;

        case VLC_CODEC_S16L:
        case VLC_CODEC_S16B:
            p_sys->fmt.audio.i_bitspersample = 16;
            break;

        case VLC_CODEC_S8:
        case VLC_CODEC_U8:
            p_sys->fmt.audio.i_bitspersample = 8;
            break;

        default:
            msg_Err( p_demux, "unknown fourcc format %4.4s",
                    (char *)&p_sys->fmt.i_codec);
            es_format_Clean( &p_sys->fmt );
            free( p_sys );
            return VLC_EGENERIC;

    }


    p_sys->fmt.psz_language = var_CreateGetString( p_demux, "rawaud-lang" );
    p_sys->fmt.audio.i_channels = var_CreateGetInteger( p_demux, "rawaud-channels" );
    p_sys->fmt.audio.i_rate = var_CreateGetInteger( p_demux, "rawaud-samplerate" );

    if( p_sys->fmt.audio.i_rate == 0 || p_sys->fmt.audio.i_rate > 384000 )
    {
        msg_Err( p_demux, "invalid sample rate");
        es_format_Clean( &p_sys->fmt );
        free( p_sys );
        return VLC_EGENERIC;
    }

    if( p_sys->fmt.audio.i_channels == 0 || p_sys->fmt.audio.i_channels > 32 )
    {
        msg_Err( p_demux, "invalid number of channels");
        es_format_Clean( &p_sys->fmt );
        free( p_sys );
        return VLC_EGENERIC;
    }

    p_sys->fmt.i_bitrate = p_sys->fmt.audio.i_rate *
                           p_sys->fmt.audio.i_channels *
                           p_sys->fmt.audio.i_bitspersample;

    if( p_sys->fmt.i_bitrate > 50000000)
    {
        msg_Err( p_demux, "invalid bitrate");
        es_format_Clean( &p_sys->fmt );
        free( p_sys );
        return VLC_EGENERIC;
    }

    msg_Dbg( p_demux,
            "format initialized: channels=%d , samplerate=%d Hz, fourcc=%4.4s, bits per sample = %d, bitrate = %d bit/s",
            p_sys->fmt.audio.i_channels,
            p_sys->fmt.audio.i_rate,
            (char*)&p_sys->fmt.i_codec,
            p_sys->fmt.audio.i_bitspersample,
            p_sys->fmt.i_bitrate);

    /* add the es */
    p_sys->p_es = es_out_Add( p_demux->out, &p_sys->fmt );
    msg_Dbg( p_demux, "elementary stream added");

    /* initialize timing */
    date_Init( &p_sys->pts, p_sys->fmt.audio.i_rate, 1 );
    date_Set( &p_sys->pts, VLC_TICK_0 );

    /* calculate 50ms frame size/time */
    p_sys->i_frame_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 );
    p_sys->i_seek_step  = p_sys->fmt.audio.i_channels *
                          ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 );
    p_sys->i_frame_size = p_sys->i_frame_samples * p_sys->i_seek_step;
    msg_Dbg( p_demux, "frame size is %d bytes ", p_sys->i_frame_size);

    p_demux->pf_demux   = Demux;
    p_demux->pf_control = Control;
    return VLC_SUCCESS;
}
Exemplo n.º 14
0
CtrlGeneric *TopWindow::findHitControl( int xPos, int yPos )
{
    if( m_pActiveLayout == NULL )
    {
        return NULL;
    }

    // Get the controls in the active layout
    const list<LayeredControl> &ctrlList = m_pActiveLayout->getControlList();
    list<LayeredControl>::const_reverse_iterator iter;

    // New control hit by the mouse
    CtrlGeneric *pNewHitControl = NULL;

    // Loop on the control list to find the uppest hit control
    for( iter = ctrlList.rbegin(); iter != ctrlList.rend(); iter++ )
    {
        // Get the position of the control in the layout
        const Position *pos = (*iter).m_pControl->getPosition();
        if( pos != NULL )
        {
            // Compute the coordinates of the mouse relative to the control
            int xRel = xPos - pos->getLeft();
            int yRel = yPos - pos->getTop();

            CtrlGeneric *pCtrl = (*iter).m_pControl;
            // Control hit ?
            if( pCtrl->isVisible() && pCtrl->mouseOver( xRel, yRel ) )
            {
                pNewHitControl = (*iter).m_pControl;
                break;
            }
        }
        else
        {
            msg_Dbg( getIntf(), "control at NULL position" );
        }
    }

    // If the hit control has just been entered, send it an enter event
    if( pNewHitControl && (pNewHitControl != m_pLastHitControl) )
    {
        // Don't send the event if another control captured the mouse
        if( !m_pCapturingControl || (m_pCapturingControl == pNewHitControl ) )
        {
            EvtEnter evt( getIntf() );
            pNewHitControl->handleEvent( evt );

            if( !m_pCapturingControl )
            {
                // Show the tooltip
                m_rWindowManager.hideTooltip();
                UString tipText = pNewHitControl->getTooltipText();
                if( tipText.length() > 0 )
                {
                    // Set the tooltip text variable
                    VarManager *pVarManager = VarManager::instance( getIntf() );
                    pVarManager->getTooltipText().set( tipText );
                    m_rWindowManager.showTooltip();
                }
            }
        }
    }

    return pNewHitControl;
}
Exemplo n.º 15
0
static int SendIn( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
                   block_t *p_buffer )
{
    in_sout_stream_sys_t *p_sys = (in_sout_stream_sys_t *)p_stream->p_sys;
    bridge_t *p_bridge;
    bool b_no_es = true;
    int i;
    int i_date = mdate();

    /* First forward the packet for our own ES */
    if( !p_sys->b_placeholder )
        p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );

    /* Then check all bridged streams */
    vlc_mutex_lock( &lock );

    p_bridge = var_GetAddress( p_stream->p_libvlc, p_sys->psz_name );

    if( p_bridge )
    {
    for ( i = 0; i < p_bridge->i_es_num; i++ )
    {
        if ( !p_bridge->pp_es[i]->b_empty )
            b_no_es = false;

        while ( p_bridge->pp_es[i]->p_block != NULL
                 && (p_bridge->pp_es[i]->p_block->i_dts + p_sys->i_delay
                       < i_date
                      || p_bridge->pp_es[i]->p_block->i_dts + p_sys->i_delay
                          < p_bridge->pp_es[i]->i_last) )
        {
            block_t *p_block = p_bridge->pp_es[i]->p_block;
            msg_Dbg( p_stream, "dropping a packet (%"PRId64 ")",
                     i_date - p_block->i_dts - p_sys->i_delay );
            p_bridge->pp_es[i]->p_block
                = p_bridge->pp_es[i]->p_block->p_next;
            block_Release( p_block );
        }

        if ( p_bridge->pp_es[i]->p_block == NULL )
        {
            p_bridge->pp_es[i]->pp_last = &p_bridge->pp_es[i]->p_block;
        }

        if ( p_bridge->pp_es[i]->b_changed )
        {
            if ( p_bridge->pp_es[i]->b_empty && p_bridge->pp_es[i]->id != NULL )
            {
                p_stream->p_next->pf_del( p_stream->p_next, p_bridge->pp_es[i]->id );
            }
            else
            {
                /* We need at least two packets to enter the mux. */
                if ( p_bridge->pp_es[i]->p_block == NULL
                      || p_bridge->pp_es[i]->p_block->p_next == NULL )
                {
                    continue;
                }

                p_bridge->pp_es[i]->fmt.i_id += p_sys->i_id_offset;
                if( !p_sys->b_placeholder )
                {
                    p_bridge->pp_es[i]->id = p_stream->p_next->pf_add(
                                p_stream->p_next, &p_bridge->pp_es[i]->fmt );
                    if ( p_bridge->pp_es[i]->id == NULL )
                    {
                        msg_Warn( p_stream, "couldn't create chain for id %d",
                                  p_bridge->pp_es[i]->fmt.i_id );
                    }
                }
                msg_Dbg( p_stream, "bridging in input codec=%4.4s id=%d pos=%d",
                         (char*)&p_bridge->pp_es[i]->fmt.i_codec,
                         p_bridge->pp_es[i]->fmt.i_id, i );
            }
        }
        p_bridge->pp_es[i]->b_changed = false;

        if ( p_bridge->pp_es[i]->b_empty )
            continue;

        if ( p_bridge->pp_es[i]->p_block == NULL )
        {
            if ( p_bridge->pp_es[i]->id != NULL
                  && p_bridge->pp_es[i]->i_last < i_date )
            {
                if( !p_sys->b_placeholder )
                    p_stream->p_next->pf_del( p_stream->p_next,
                                          p_bridge->pp_es[i]->id );
                p_bridge->pp_es[i]->fmt.i_id -= p_sys->i_id_offset;
                p_bridge->pp_es[i]->b_changed = true;
                p_bridge->pp_es[i]->id = NULL;
            }
            continue;
        }

        if ( p_bridge->pp_es[i]->id != NULL || p_sys->b_placeholder)
        {
            block_t *p_block = p_bridge->pp_es[i]->p_block;
            while ( p_block != NULL )
            {
                p_bridge->pp_es[i]->i_last = p_block->i_dts;
                p_block->i_pts += p_sys->i_delay;
                p_block->i_dts += p_sys->i_delay;
                p_block = p_block->p_next;
            }
            sout_stream_id_sys_t *newid = NULL;
            if( p_sys->b_placeholder )
            {
                switch( p_bridge->pp_es[i]->fmt.i_cat )
                {
                    case VIDEO_ES:
                        p_sys->i_last_video = i_date;
                        newid = p_sys->id_video;
                        if( !newid )
                            break;
                        if( !p_sys->b_switch_on_iframe ||
                            p_sys->i_state == placeholder_off ||
                            ( p_bridge->pp_es[i]->fmt.i_cat == VIDEO_ES &&
                              p_bridge->pp_es[i]->p_block->i_flags & BLOCK_FLAG_TYPE_I ) )
                        {
                            p_stream->p_next->pf_send( p_stream->p_next,
                                       newid,
                                       p_bridge->pp_es[i]->p_block );
                            p_sys->i_state = placeholder_off;
                        }
                        break;
                    case AUDIO_ES:
                        newid = p_sys->id_audio;
                        if( !newid )
                            break;
                        p_sys->i_last_audio = i_date;
                    default:
                        p_stream->p_next->pf_send( p_stream->p_next,
                                   newid?newid:p_bridge->pp_es[i]->id,
                                   p_bridge->pp_es[i]->p_block );
                        break;
                }
            }
            else /* !b_placeholder */
                p_stream->p_next->pf_send( p_stream->p_next,
                                       p_bridge->pp_es[i]->id,
                                       p_bridge->pp_es[i]->p_block );
        }
        else
        {
            block_ChainRelease( p_bridge->pp_es[i]->p_block );
        }

        p_bridge->pp_es[i]->p_block = NULL;
        p_bridge->pp_es[i]->pp_last = &p_bridge->pp_es[i]->p_block;
    }

    if( b_no_es )
    {
        for ( i = 0; i < p_bridge->i_es_num; i++ )
            free( p_bridge->pp_es[i] );
        free( p_bridge->pp_es );
        free( p_bridge );
        var_Destroy( p_stream->p_libvlc, p_sys->psz_name );
    }
    }

    if( p_sys->b_placeholder )
    {
        switch( id->i_cat )
        {
            case VIDEO_ES:
                if( ( p_sys->i_last_video + p_sys->i_placeholder_delay < i_date
                    && (  !p_sys->b_switch_on_iframe
                       || p_buffer->i_flags & BLOCK_FLAG_TYPE_I ) )
                  || p_sys->i_state == placeholder_on )
                {
                    p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
                    p_sys->i_state = placeholder_on;
                }
                else
                    block_Release( p_buffer );
                break;

            case AUDIO_ES:
                if( p_sys->i_last_audio + p_sys->i_placeholder_delay < i_date )
                    p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
                else
                    block_Release( p_buffer );
                break;

            default:
                block_Release( p_buffer ); /* FIXME: placeholder subs anyone? */
                break;
        }
    }

    vlc_mutex_unlock( &lock );

    return VLC_SUCCESS;
}
Exemplo n.º 16
0
Arquivo: video.c Projeto: Jasonic/vlc
/*****************************************************************************
 * InitVideo: initialize the video decoder
 *****************************************************************************
 * the ffmpeg codec will be opened, some memory allocated. The vout is not yet
 * opened (done after the first decoded frame).
 *****************************************************************************/
int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
{
    decoder_sys_t *p_sys;
    int i_val;

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(decoder_sys_t) ) ) == NULL )
        return VLC_ENOMEM;

    p_codec->type = AVMEDIA_TYPE_VIDEO;
    p_context->codec_type = AVMEDIA_TYPE_VIDEO;
    p_context->codec_id = i_codec_id;
    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
    p_sys->i_codec_id = i_codec_id;
    p_sys->psz_namecodec = psz_namecodec;
    p_sys->p_ff_pic = avcodec_alloc_frame();
    p_sys->b_delayed_open = true;
    p_sys->p_va = NULL;
    vlc_sem_init( &p_sys->sem_mt, 0 );

    /* ***** Fill p_context with init values ***** */
    p_sys->p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in.i_original_fourcc ?: p_dec->fmt_in.i_codec );

    /*  ***** Get configuration of ffmpeg plugin ***** */
    p_sys->p_context->workaround_bugs =
        var_InheritInteger( p_dec, "avcodec-workaround-bugs" );
    p_sys->p_context->err_recognition =
        var_InheritInteger( p_dec, "avcodec-error-resilience" );

    if( var_CreateGetBool( p_dec, "grayscale" ) )
        p_sys->p_context->flags |= CODEC_FLAG_GRAY;

    /* ***** Output always the frames ***** */
#if LIBAVCODEC_VERSION_CHECK(55, 23, 1, 40, 101)
    p_sys->p_context->flags |= CODEC_FLAG_OUTPUT_CORRUPT;
#endif

    i_val = var_CreateGetInteger( p_dec, "avcodec-vismv" );
    if( i_val ) p_sys->p_context->debug_mv = i_val;

    i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" );
    if( i_val >= 4 ) p_sys->p_context->skip_loop_filter = AVDISCARD_ALL;
    else if( i_val == 3 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONKEY;
    else if( i_val == 2 ) p_sys->p_context->skip_loop_filter = AVDISCARD_BIDIR;
    else if( i_val == 1 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONREF;

    if( var_CreateGetBool( p_dec, "avcodec-fast" ) )
        p_sys->p_context->flags2 |= CODEC_FLAG2_FAST;

    /* ***** libavcodec frame skipping ***** */
    p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" );

    i_val = var_CreateGetInteger( p_dec, "avcodec-skip-frame" );
    if( i_val >= 4 ) p_sys->p_context->skip_frame = AVDISCARD_ALL;
    else if( i_val == 3 ) p_sys->p_context->skip_frame = AVDISCARD_NONKEY;
    else if( i_val == 2 ) p_sys->p_context->skip_frame = AVDISCARD_BIDIR;
    else if( i_val == 1 ) p_sys->p_context->skip_frame = AVDISCARD_NONREF;
    else if( i_val == -1 ) p_sys->p_context->skip_frame = AVDISCARD_NONE;
    else p_sys->p_context->skip_frame = AVDISCARD_DEFAULT;
    p_sys->i_skip_frame = p_sys->p_context->skip_frame;

    i_val = var_CreateGetInteger( p_dec, "avcodec-skip-idct" );
    if( i_val >= 4 ) p_sys->p_context->skip_idct = AVDISCARD_ALL;
    else if( i_val == 3 ) p_sys->p_context->skip_idct = AVDISCARD_NONKEY;
    else if( i_val == 2 ) p_sys->p_context->skip_idct = AVDISCARD_BIDIR;
    else if( i_val == 1 ) p_sys->p_context->skip_idct = AVDISCARD_NONREF;
    else if( i_val == -1 ) p_sys->p_context->skip_idct = AVDISCARD_NONE;
    else p_sys->p_context->skip_idct = AVDISCARD_DEFAULT;
    p_sys->i_skip_idct = p_sys->p_context->skip_idct;

    /* ***** libavcodec direct rendering ***** */
    p_sys->b_direct_rendering = false;
    p_sys->i_direct_rendering_used = -1;
    if( var_CreateGetBool( p_dec, "avcodec-dr" ) &&
       (p_sys->p_codec->capabilities & CODEC_CAP_DR1) &&
        /* No idea why ... but this fixes flickering on some TSCC streams */
        p_sys->i_codec_id != AV_CODEC_ID_TSCC && p_sys->i_codec_id != AV_CODEC_ID_CSCD &&
        p_sys->i_codec_id != AV_CODEC_ID_CINEPAK &&
        !p_sys->p_context->debug_mv )
    {
        /* Some codecs set pix_fmt only after the 1st frame has been decoded,
         * so we need to do another check in ffmpeg_GetFrameBuf() */
        p_sys->b_direct_rendering = true;
    }

    /* libavcodec doesn't properly release old pictures when frames are skipped */
    //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false;
    if( p_sys->b_direct_rendering )
    {
        msg_Dbg( p_dec, "trying to use direct rendering" );
        p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE;
    }
    else
    {
        msg_Dbg( p_dec, "direct rendering is disabled" );
    }

    p_sys->p_context->get_format = ffmpeg_GetFormat;
    /* Always use our get_buffer wrapper so we can calculate the
     * PTS correctly */
#if LIBAVCODEC_VERSION_MAJOR >= 55
    p_sys->p_context->get_buffer2 = lavc_GetFrame;
#else
    p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf;
    p_sys->p_context->reget_buffer = avcodec_default_reget_buffer;
    p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;
#endif
    p_sys->p_context->opaque = p_dec;

#ifdef HAVE_AVCODEC_MT
    int i_thread_count = var_InheritInteger( p_dec, "avcodec-threads" );
    if( i_thread_count <= 0 )
    {
        i_thread_count = vlc_GetCPUCount();
        if( i_thread_count > 1 )
            i_thread_count++;

        //FIXME: take in count the decoding time
        i_thread_count = __MIN( i_thread_count, 4 );
    }
    i_thread_count = __MIN( i_thread_count, 16 );
    msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count );
    p_sys->p_context->thread_count = i_thread_count;
    p_sys->p_context->thread_safe_callbacks = true;

    switch( i_codec_id )
    {
        case AV_CODEC_ID_MPEG4:
        case AV_CODEC_ID_H263:
            p_sys->p_context->thread_type = 0;
            break;
        case AV_CODEC_ID_MPEG1VIDEO:
        case AV_CODEC_ID_MPEG2VIDEO:
            p_sys->p_context->thread_type &= ~FF_THREAD_SLICE;
            /* fall through */
# if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 1, 0))
        case AV_CODEC_ID_H264:
        case AV_CODEC_ID_VC1:
        case AV_CODEC_ID_WMV3:
            p_sys->p_context->thread_type &= ~FF_THREAD_FRAME;
# endif
    }

    if( p_sys->p_context->thread_type & FF_THREAD_FRAME )
        p_dec->i_extra_picture_buffers = 2 * p_sys->p_context->thread_count;
#endif

    /* ***** misc init ***** */
    p_sys->i_pts = VLC_TS_INVALID;
    p_sys->b_has_b_frames = false;
    p_sys->b_first_frame = true;
    p_sys->b_flush = false;
    p_sys->i_late_frames = 0;

    /* Set output properties */
    p_dec->fmt_out.i_cat = VIDEO_ES;
    if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS )
    {
        /* we are doomed. but not really, because most codecs set their pix_fmt later on */
        p_dec->fmt_out.i_codec = VLC_CODEC_I420;
    }
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;

    p_dec->fmt_out.video.orientation = p_dec->fmt_in.video.orientation;

#if LIBAVCODEC_VERSION_MAJOR < 54
    /* Setup palette */
    memset( &p_sys->palette, 0, sizeof(p_sys->palette) );
    if( p_dec->fmt_in.video.p_palette )
    {
        p_sys->palette.palette_changed = 1;

        for( int i = 0; i < __MIN( AVPALETTE_COUNT, p_dec->fmt_in.video.p_palette->i_entries ); i++ )
        {
            union {
                uint32_t u;
                uint8_t a[4];
            } c;
            c.a[0] = p_dec->fmt_in.video.p_palette->palette[i][0];
            c.a[1] = p_dec->fmt_in.video.p_palette->palette[i][1];
            c.a[2] = p_dec->fmt_in.video.p_palette->palette[i][2];
            c.a[3] = p_dec->fmt_in.video.p_palette->palette[i][3];

            p_sys->palette.palette[i] = c.u;
        }
        p_sys->p_context->palctrl = &p_sys->palette;

        p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) );
        if( p_dec->fmt_out.video.p_palette )
            *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in.video.p_palette;
    }
    else if( p_sys->i_codec_id != CODEC_ID_MSVIDEO1 && p_sys->i_codec_id != CODEC_ID_CINEPAK )
    {
        p_sys->p_context->palctrl = &p_sys->palette;
    }
#else
    if( p_dec->fmt_in.video.p_palette ) {
        p_sys->palette_sent = false;
        p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) );
        if( p_dec->fmt_out.video.p_palette )
            *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in.video.p_palette;
    } else
        p_sys->palette_sent = true;
#endif

    /* ***** init this codec with special data ***** */
    ffmpeg_InitCodec( p_dec );

    /* ***** Open the codec ***** */
    if( ffmpeg_OpenCodec( p_dec ) < 0 )
    {
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
        av_free( p_sys->p_ff_pic );
        vlc_sem_destroy( &p_sys->sem_mt );
        free( p_sys );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
Exemplo n.º 17
0
Arquivo: smooth.c Projeto: Adatan/vlc
static int parse_Manifest( stream_t *s )
{
    stream_sys_t *p_sys = s->p_sys;
    xml_t *vlc_xml = NULL;
    xml_reader_t *vlc_reader = NULL;
    int type = UNKNOWN_ES;
    const char *name, *value;
    stream_t *st = s->p_source;
    msg_Dbg( s, "Manifest parsing\n" );

    vlc_xml = xml_Create( st );
    if( !vlc_xml )
    {
        msg_Err( s, "Failed to open XML parser" );
        return VLC_EGENERIC;
    }

    vlc_reader = xml_ReaderCreate( vlc_xml, st );
    if( !vlc_reader )
    {
        msg_Err( s, "Failed to open source for parsing" );
        xml_Delete( vlc_xml );
        return VLC_EGENERIC;
    }

    const char *node;
    uint8_t *WaveFormatEx;
    sms_stream_t *sms = NULL;
    quality_level_t *ql = NULL;
    custom_attrs_t *cp = NULL;
    int64_t start_time = 0, duration = 0;
    int64_t computed_start_time = 0, computed_duration = 0;
    unsigned next_track_id = 1;
    int loop_count = 0;
    bool b_weird = false;
    int ret = VLC_SUCCESS;

#define TIMESCALE 10000000
    while( (type = xml_ReaderNextNode( vlc_reader, &node )) > 0 )
    {
        switch( type )
        {
            case XML_READER_STARTELEM:

                if( !strcmp( node, "SmoothStreamingMedia" ) )
                {
                    while( (name = xml_ReaderNextAttr( vlc_reader, &value )) )
                    {
                        if( !strcmp( name, "Duration" ) )
                            p_sys->vod_duration = strtoull( value, NULL, 10 );
                        else if( !strcmp( name, "TimeScale" ) )
                            p_sys->timescale = strtoul( value, NULL, 10 );
                        else if ( !strcmp( name, "LookAheadFragmentCount" ) )
                            p_sys->download.lookahead_count = strtoul( value, NULL, 10 );
                    }
                    if( !p_sys->timescale )
                        p_sys->timescale = TIMESCALE;
                }
                else if( !strcmp( node, "StreamIndex" ) )
                {
                    sms_Free( sms );
                    sms = sms_New();
                    if( unlikely( !sms ) )
                    {
                        ret = VLC_ENOMEM;
                        goto cleanup;
                    }
                    sms->id = next_track_id;
                    next_track_id++;

                    while( (name = xml_ReaderNextAttr( vlc_reader, &value )) )
                    {
                        if( !strcmp( name, "Type" ) )
                        {
                            if( !strcmp( value, "video" ) )
                                sms->type = VIDEO_ES;
                            else if( !strcmp( value, "audio" ) )
                                sms->type = AUDIO_ES;
                            else if( !strcmp( value, "text" ) )
                                sms->type = SPU_ES;
                        }

                        else if( !strcmp( name, "Name" ) )
                            sms->name = strdup( value );
                        else if( !strcmp( name, "TimeScale" ) )
                            sms->timescale = strtoull( value, NULL, 10 );
                        else if( !strcmp( name, "FourCC" ) )
                            sms->default_FourCC =
                                VLC_FOURCC( value[0], value[1], value[2], value[3] );

                        else if( !strcmp( name, "Chunks" ) )
                        {
                            sms->vod_chunks_nb = strtoul( value, NULL, 10 );
                            if( sms->vod_chunks_nb == 0 ) /* live */
                                sms->vod_chunks_nb = UINT32_MAX;
                        }

                        else if( !strcmp( name, "QualityLevels" ) )
                            sms->qlevel_nb = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "Url" ) )
                            sms->url_template = strdup(value);
                    }

                    if( !sms->timescale )
                        sms->timescale = TIMESCALE;

                    if( !sms->name )
                    {
                        if( sms->type == VIDEO_ES )
                            sms->name = strdup( "video" );
                        else if( sms->type == AUDIO_ES )
                            sms->name = strdup( "audio" );
                        else if( sms->type == SPU_ES )
                            sms->name = strdup( "text" );
                    }
                }
                else if ( !strcmp( node, "CustomAttributes" ) )
                {
                    if (!sms || !ql || cp)
                        break;
                    cp = (custom_attrs_t *) calloc( 1, sizeof(*cp) );
                    if( unlikely( !cp ) )
                    {
                        ret = VLC_ENOMEM;
                        goto cleanup;
                    }
                }
                else if ( !strcmp( node, "Attribute" ) )
                {
                    if (!sms || !ql || !cp)
                        break;
                    while( (name = xml_ReaderNextAttr( vlc_reader, &value )) )
                    {
                        if( !strcmp( name, "Name" ) && !cp->psz_key )
                            cp->psz_key = strdup( value );
                        else
                        if( !strcmp( name, "Value" ) && !cp->psz_value )
                            cp->psz_value = strdup( value );
                    }
                }
                else if( !strcmp( node, "QualityLevel" ) )
                {
                    if ( !sms )
                        break;

                    ql = ql_New();
                    if( !ql )
                    {
                        ret = VLC_ENOMEM;
                        goto cleanup;
                    }

                    while( (name = xml_ReaderNextAttr( vlc_reader, &value )) )
                    {
                        if( !strcmp( name, "Index" ) )
                            ql->Index = strtol( value, NULL, 10 );
                        else if( !strcmp( name, "Bitrate" ) )
                            ql->Bitrate = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "PacketSize" ) )
                            ql->nBlockAlign = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "FourCC" ) )
                            ql->FourCC = VLC_FOURCC( value[0], value[1],
                                                     value[2], value[3] );
                        else if( !strcmp( name, "CodecPrivateData" ) )
                            ql->CodecPrivateData = strdup( value );
                        else if( !strcmp( name, "WaveFormatEx" ) )
                        {
                            WaveFormatEx = decode_string_hex_to_binary( value );
                            uint16_t data_len = ((uint16_t *)WaveFormatEx)[8];
                            ql->CodecPrivateData = strndup( value + 36, data_len * 2 );

                            uint16_t wf_tag = ((uint16_t *)WaveFormatEx)[0];
                            wf_tag_to_fourcc( wf_tag, &ql->FourCC, NULL );

                            ql->Channels = ((uint16_t *)WaveFormatEx)[1];
                            ql->SamplingRate = ((uint32_t *)WaveFormatEx)[1];
                            ql->nBlockAlign = ((uint16_t *)WaveFormatEx)[6];
                            ql->BitsPerSample = ((uint16_t *)WaveFormatEx)[7];
                            free( WaveFormatEx );
                        }
                        else if( !strcmp( name, "MaxWidth" ) || !strcmp( name, "Width" ) )
                            ql->MaxWidth = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "MaxHeight" ) || !strcmp( name, "Height" ) )
                            ql->MaxHeight = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "Channels" ) )
                            ql->Channels = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "SamplingRate" ) )
                            ql->SamplingRate = strtoul( value, NULL, 10 );
                        else if( !strcmp( name, "BitsPerSample" ) )
                            ql->BitsPerSample = strtoul( value, NULL, 10 );
                    }

                    ARRAY_APPEND( sms->qlevels, ql );
                }
                else if ( !strcmp( node, "Content" ) && sms && !sms->url_template )
                {
                    /* empty(@Url) && ./Content == manifest embedded content */
                    sms_Free( sms );
                    sms = NULL;
                }
                else if( !strcmp( node, "c" ) )
                {
                    if ( !sms )
                        break;
                    loop_count++;
                    start_time = duration = -1;
                    while( (name = xml_ReaderNextAttr( vlc_reader, &value )) )
                    {
                        if( !strcmp( name, "t" ) )
                            start_time = strtoll( value, NULL, 10 );
                        if( !strcmp( name, "d" ) )
                            duration = strtoll( value, NULL, 10 );
                    }
                    if( start_time == -1 )
                    {
                        assert( duration != -1 );
                        computed_start_time += computed_duration;
                        computed_duration = duration;
                    }
                    else if( duration == -1 )
                    {
                        assert( start_time != -1 );
                        /* Handle weird Manifests which give only the start time
                         * of the first segment. In those cases, we have to look
                         * at the start time of the second segment to compute
                         * the duration of the first one. */
                        if( loop_count == 1 )
                        {
                            b_weird = true;
                            computed_start_time = start_time;
                            continue;
                        }

                        computed_duration = start_time - computed_start_time;
                        if( !b_weird )
                            computed_start_time = start_time;
                    }
                    else
                    {
                        if( b_weird )
                            computed_duration = start_time - computed_start_time;
                        else
                        {
                            computed_start_time = start_time;
                            computed_duration = duration;
                        }
                    }

                    if( unlikely( chunk_AppendNew( sms, computed_duration,
                                        computed_start_time ) == NULL ) )
                    {
                        ret = VLC_ENOMEM;
                        goto cleanup;
                    }
                    if( b_weird && start_time != -1 )
                        computed_start_time = start_time;
                }
                break;

            case XML_READER_ENDELEM:
                if ( !strcmp( node, "CustomAttributes" ) )
                {
                    if ( cp )
                    {
                        ARRAY_APPEND(ql->custom_attrs, cp);
                        cp = NULL;
                    }
                }
                else if ( !strcmp( node, "Attribute" ) )
                {
                    if( !cp->psz_key || !cp->psz_value )
                    {
                        cleanup_attributes( &cp );
                    }
                }
                else if( strcmp( node, "StreamIndex" ) )
                    break;
                else if ( sms )
                {
                    ARRAY_APPEND( p_sys->sms, sms );

                    computed_start_time = 0;
                    computed_duration = 0;
                    loop_count = 0;
                    if( b_weird && !chunk_AppendNew( sms, computed_duration, computed_start_time ) )
                    {
                        ret = VLC_ENOMEM;
                        goto cleanup;
                    }

                    b_weird = false;

                    if( sms->qlevel_nb == 0 )
                        sms->qlevel_nb = sms->qlevels.i_size;

                    sms = NULL;
                }
                break;

            case XML_READER_TEXT:
                break;
            default:
                ret = VLC_EGENERIC;
                goto cleanup;
        }
    }
#undef TIMESCALE

cleanup:
    cleanup_attributes( &cp );
    sms_Free( sms );
    xml_ReaderDelete( vlc_reader );
    xml_Delete( vlc_xml );

    return ret;
}
Exemplo n.º 18
0
Arquivo: video.c Projeto: Jasonic/vlc
static picture_t *lavc_dr_GetFrame(struct AVCodecContext *ctx,
                                   AVFrame *frame, int flags)
{
    decoder_t *dec = (decoder_t *)ctx->opaque;
    decoder_sys_t *sys = dec->p_sys;

    if (GetVlcChroma(&dec->fmt_out.video, ctx->pix_fmt) != VLC_SUCCESS)
        return NULL;
    dec->fmt_out.i_codec = dec->fmt_out.video.i_chroma;
    if (ctx->pix_fmt == PIX_FMT_PAL8)
        return NULL;

    int width = frame->width;
    int height = frame->height;
    int aligns[AV_NUM_DATA_POINTERS];

    avcodec_align_dimensions2(ctx, &width, &height, aligns);

    picture_t *pic = ffmpeg_NewPictBuf(dec, ctx);
    if (pic == NULL)
        return NULL;

    /* Check that the picture is suitable for libavcodec */
    if (pic->p[0].i_pitch < width * pic->p[0].i_pixel_pitch)
    {
        if (sys->i_direct_rendering_used != 0)
            msg_Dbg(dec, "plane 0: pitch too small (%d/%d*%d)",
                    pic->p[0].i_pitch, width, pic->p[0].i_pixel_pitch);
        goto no_dr;
    }

    if (pic->p[0].i_lines < height)
    {
        if (sys->i_direct_rendering_used != 0)
            msg_Dbg(dec, "plane 0: lines too few (%d/%d)",
                    pic->p[0].i_lines, height);
        goto no_dr;
    }

    for (int i = 0; i < pic->i_planes; i++)
    {
        if (pic->p[i].i_pitch % aligns[i])
        {
            if (sys->i_direct_rendering_used != 0)
                msg_Dbg(dec, "plane %d: pitch not aligned (%d%%%d)",
                        i, pic->p[i].i_pitch, aligns[i]);
            goto no_dr;
        }
        if (((uintptr_t)pic->p[i].p_pixels) % aligns[i])
        {
            if (sys->i_direct_rendering_used != 0)
                msg_Warn(dec, "plane %d not aligned", i);
            goto no_dr;
        }
    }

    /* Allocate buffer references */
    for (int i = 0; i < pic->i_planes; i++)
    {
        lavc_pic_ref_t *ref = malloc(sizeof (*ref));
        if (ref == NULL)
            goto error;
        ref->decoder = dec;
        ref->picture = pic;
        decoder_LinkPicture(dec, pic);

        uint8_t *data = pic->p[i].p_pixels;
        int size = pic->p[i].i_pitch * pic->p[i].i_lines;

        frame->buf[i] = av_buffer_create(data, size, lavc_dr_ReleaseFrame,
                                         ref, 0);
        if (unlikely(frame->buf[i] == NULL))
        {
            lavc_dr_ReleaseFrame(ref, data);
            goto error;
        }
    }
    decoder_UnlinkPicture(dec, pic);
    (void) flags;
    return pic;
error:
    for (unsigned i = 0; frame->buf[i] != NULL; i++)
        av_buffer_unref(&frame->buf[i]);
no_dr:
    decoder_DeletePicture(dec, pic);
    return NULL;
}
Exemplo n.º 19
0
Arquivo: smooth.c Projeto: Adatan/vlc
static unsigned int sms_Read( stream_t *s, uint8_t *p_read, unsigned int i_read )
{
    stream_sys_t *p_sys = s->p_sys;
    unsigned int copied = 0;
    chunk_t *chunk = NULL;

    do
    {
        bool b_isinitchunk = false;
        chunk = get_chunk( s, true, &b_isinitchunk );
        /* chunk here won't be processed further */
//        msg_Dbg( s, "chunk %"PRIu64" init %d", (uint64_t) chunk, b_isinitchunk );
        if( !chunk )
            return copied;

        if( chunk->read_pos >= chunk->size )
        {
            if( chunk->type == VIDEO_ES ||
                ( !SMS_GET_SELECTED_ST( VIDEO_ES ) && chunk->type == AUDIO_ES ) )
            {
                p_sys->playback.toffset += chunk->duration;
                vlc_cond_signal( &p_sys->download.wait );
            }

            if ( b_isinitchunk )
            {
                assert( chunk->read_pos == chunk->size );
                vlc_mutex_lock( &p_sys->playback.lock );
                p_sys->playback.init.p_startchunk = NULL;
                p_sys->playback.init.p_datachunk = NULL;
                chunk_Free( chunk );
                vlc_mutex_unlock( &p_sys->playback.lock );
            }
            else
            {
                vlc_mutex_lock( &p_sys->lock );
                if( gotoNextChunk( p_sys ) == NULL )
                {
                    vlc_mutex_unlock( &p_sys->lock );
                    return 0;
                }
                vlc_mutex_unlock( &p_sys->lock );
            }

            continue;
        }

        if( chunk->read_pos == 0 )
        {
            const char *verb = p_read == NULL ? "skipping" : "reading";
            msg_Dbg( s, "%s chunk time %"PRIu64" (%u bytes), type %i",
                        verb, chunk->start_time, i_read, chunk->type );
        }

        uint64_t len = 0;
        uint8_t *src = chunk->data + chunk->read_pos;
        if( i_read <= chunk->size - chunk->read_pos )
            len = i_read;
        else
            len = chunk->size - chunk->read_pos;

        if( len > 0 )
        {
            if( p_read ) /* otherwise caller skips data */
                memcpy( p_read + copied, src, len );
            chunk->read_pos += len;
            copied += len;
            i_read -= len;
            p_sys->playback.boffset += len;
        }

    } while ( i_read > 0 );

    return copied;
}
Exemplo n.º 20
0
/*****************************************************************************
 * Init: initialize Crop video thread output method
 *****************************************************************************/
static int Init( vout_thread_t *p_vout )
{
    char *psz_var;
    video_format_t fmt;

    I_OUTPUTPICTURES = 0;
    memset( &fmt, 0, sizeof(video_format_t) );

    p_vout->p_sys->i_lastchange = 0;
    p_vout->p_sys->b_changed = false;

    /* Initialize the output structure */
    p_vout->output.i_chroma = p_vout->render.i_chroma;
    p_vout->output.i_width  = p_vout->render.i_width;
    p_vout->output.i_height = p_vout->render.i_height;
    p_vout->output.i_aspect = p_vout->render.i_aspect;
    p_vout->fmt_out = p_vout->fmt_in;

    /* Shall we use autocrop ? */
    p_vout->p_sys->b_autocrop = var_InheritBool( p_vout, "autocrop" );
#ifdef BEST_AUTOCROP
    p_vout->p_sys->i_ratio_max =
        var_InheritInteger( p_vout, "autocrop-ratio-max" );
    p_vout->p_sys->i_threshold =
        var_InheritInteger( p_vout, "autocrop-luminance-threshold" );
    p_vout->p_sys->i_skipPercent =
        var_InheritInteger( p_vout, "autocrop-skip-percent" );
    p_vout->p_sys->i_nonBlackPixel =
        var_InheritInteger( p_vout, "autocrop-non-black-pixels" );
    p_vout->p_sys->i_diff =
        var_InheritInteger( p_vout, "autocrop-diff" );
    p_vout->p_sys->i_time =
        var_InheritInteger( p_vout, "autocrop-time" );
    var_SetString( p_vout, "ratio-crop", "0" );

    if (p_vout->p_sys->b_autocrop)
        p_vout->p_sys->i_ratio = 0;
    else
    {
        p_vout->p_sys->i_ratio = var_InheritInteger( p_vout, "crop-ratio" );
        // ratio < width / height => ratio = 0 (unchange ratio)
        if (p_vout->p_sys->i_ratio < (p_vout->output.i_width * 1000) / p_vout->output.i_height)
            p_vout->p_sys->i_ratio = 0;
    }
#endif


    /* Get geometry value from the user */
    psz_var = var_InheritString( p_vout, "crop-geometry" );
    if( psz_var )
    {
        char *psz_parser, *psz_tmp;

        psz_parser = psz_tmp = psz_var;
        while( *psz_tmp && *psz_tmp != 'x' ) psz_tmp++;

        if( *psz_tmp )
        {
            psz_tmp[0] = '\0';
            p_vout->p_sys->i_width = atoi( psz_parser );

            psz_parser = ++psz_tmp;
            while( *psz_tmp && *psz_tmp != '+' ) psz_tmp++;

            if( *psz_tmp )
            {
                psz_tmp[0] = '\0';
                p_vout->p_sys->i_height = atoi( psz_parser );

                psz_parser = ++psz_tmp;
                while( *psz_tmp && *psz_tmp != '+' ) psz_tmp++;

                if( *psz_tmp )
                {
                    psz_tmp[0] = '\0';
                    p_vout->p_sys->i_x = atoi( psz_parser );
                    p_vout->p_sys->i_y = atoi( ++psz_tmp );
                }
                else
                {
                    p_vout->p_sys->i_x = atoi( psz_parser );
                    p_vout->p_sys->i_y =
                        ( p_vout->output.i_height - p_vout->p_sys->i_height ) / 2;
                }
            }
            else
            {
                p_vout->p_sys->i_height = atoi( psz_parser );
                p_vout->p_sys->i_x =
                    ( p_vout->output.i_width - p_vout->p_sys->i_width ) / 2;
                p_vout->p_sys->i_y =
                    ( p_vout->output.i_height - p_vout->p_sys->i_height ) / 2;
            }
        }
        else
        {
            p_vout->p_sys->i_width = atoi( psz_parser );
            p_vout->p_sys->i_height = p_vout->output.i_height;
            p_vout->p_sys->i_x =
                ( p_vout->output.i_width - p_vout->p_sys->i_width ) / 2;
            p_vout->p_sys->i_y =
                ( p_vout->output.i_height - p_vout->p_sys->i_height ) / 2;
        }

        /* Check for validity */
        if( p_vout->p_sys->i_x + p_vout->p_sys->i_width
                > p_vout->output.i_width )
        {
            p_vout->p_sys->i_x = 0;
            if( p_vout->p_sys->i_width > p_vout->output.i_width )
            {
                p_vout->p_sys->i_width = p_vout->output.i_width;
            }
        }

        if( p_vout->p_sys->i_y + p_vout->p_sys->i_height
                > p_vout->output.i_height )
        {
            p_vout->p_sys->i_y = 0;
            if( p_vout->p_sys->i_height > p_vout->output.i_height )
            {
                p_vout->p_sys->i_height = p_vout->output.i_height;
            }
        }

        free( psz_var );
    }
    else
#ifdef BEST_AUTOCROP
        if (p_vout->p_sys->i_ratio)
        {
            p_vout->p_sys->i_aspect    =  p_vout->p_sys->i_ratio * 432;
            p_vout->p_sys->i_width  = p_vout->fmt_out.i_visible_width;
            p_vout->p_sys->i_height = p_vout->output.i_aspect
                                      * p_vout->output.i_height / p_vout->p_sys->i_aspect
                                      * p_vout->p_sys->i_width / p_vout->output.i_width;
            p_vout->p_sys->i_height += p_vout->p_sys->i_height % 2;
            p_vout->p_sys->i_x = p_vout->fmt_out.i_x_offset;
            p_vout->p_sys->i_y = (p_vout->output.i_height - p_vout->p_sys->i_height) / 2;
        }
        else
#endif
        {
            p_vout->p_sys->i_width  = p_vout->fmt_out.i_visible_width;
            p_vout->p_sys->i_height = p_vout->fmt_out.i_visible_height;
            p_vout->p_sys->i_x = p_vout->fmt_out.i_x_offset;
            p_vout->p_sys->i_y = p_vout->fmt_out.i_y_offset;
        }

    /* Pheeew. Parsing done. */
    msg_Dbg( p_vout, "cropping at %ix%i+%i+%i, %sautocropping",
             p_vout->p_sys->i_width, p_vout->p_sys->i_height,
             p_vout->p_sys->i_x, p_vout->p_sys->i_y,
             p_vout->p_sys->b_autocrop ? "" : "not " );
    /* Set current output image properties */
    p_vout->p_sys->i_aspect = (int64_t)VOUT_ASPECT_FACTOR *
                              p_vout->fmt_out.i_sar_num * p_vout->p_sys->i_width /
                              (p_vout->fmt_out.i_sar_den * p_vout->p_sys->i_height);

#ifdef BEST_AUTOCROP
    msg_Info( p_vout, "ratio %d",  p_vout->p_sys->i_aspect / 432);
#endif
    fmt.i_width = fmt.i_visible_width = p_vout->p_sys->i_width;
    fmt.i_height = fmt.i_visible_height = p_vout->p_sys->i_height;
    fmt.i_x_offset = fmt.i_y_offset = 0;
    fmt.i_chroma = p_vout->render.i_chroma;
    fmt.i_sar_num = p_vout->p_sys->i_aspect * fmt.i_height;
    fmt.i_sar_den = VOUT_ASPECT_FACTOR * fmt.i_width;

    /* Try to open the real video output */
    p_vout->p_sys->p_vout = vout_Create( p_vout, &fmt );
    if( p_vout->p_sys->p_vout == NULL )
    {
        msg_Err( p_vout, "failed to create vout" );
        dialog_Fatal( p_vout, _("Cropping failed"), "%s",
                      _("VLC could not open the video output module.") );
        return VLC_EGENERIC;
    }

    vlc_mutex_init( &p_vout->p_sys->lock );
#ifdef BEST_AUTOCROP
    var_AddCallback( p_vout, "ratio-crop", FilterCallback, NULL );
#endif

    vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );

    vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );

    return VLC_SUCCESS;
}
Exemplo n.º 21
0
int main( int i_argc, char **pp_argv )
{
    const char *psz_network_name = "DVBlast - http://www.videolan.org/projects/dvblast.html";
    char *p_network_name_tmp = NULL;
    size_t i_network_name_tmp_size;
    char *psz_dup_config = NULL;
    mtime_t i_poll_timeout = MAX_POLL_TIMEOUT;
    struct sched_param param;
    int i_error;
    int c;
    struct sigaction sa;
    sigset_t set;

    int b_enable_syslog = 0;

    if ( i_argc == 1 )
        usage();

    /*
     * The only short options left are: 346789
     * Use them wisely.
     */
    static const struct option long_options[] =
    {
        { "config-file",     required_argument, NULL, 'c' },
        { "remote-socket",   required_argument, NULL, 'r' },
        { "ttl",             required_argument, NULL, 't' },
        { "rtp-output",      required_argument, NULL, 'o' },
        { "priority",        required_argument, NULL, 'i' },
        { "adapter",         required_argument, NULL, 'a' },
        { "frontend-number", required_argument, NULL, 'n' },
        { "delsys",          required_argument, NULL, '5' },
        { "frequency",       required_argument, NULL, 'f' },
        { "fec-inner",       required_argument, NULL, 'F' },
        { "rolloff",         required_argument, NULL, 'R' },
        { "symbol-rate",     required_argument, NULL, 's' },
        { "diseqc",          required_argument, NULL, 'S' },
        { "uncommitted",     required_argument, NULL, 'k' },
        { "voltage",         required_argument, NULL, 'v' },
        { "force-pulse",     no_argument,       NULL, 'p' },
        { "bandwidth",       required_argument, NULL, 'b' },
        { "inversion",       required_argument, NULL, 'I' },
        { "modulation",      required_argument, NULL, 'm' },
        { "pilot",           required_argument, NULL, 'P' },
        { "multistream-id",  required_argument, NULL, '1' },
        { "fec-lp",          required_argument, NULL, 'K' },
        { "guard",           required_argument, NULL, 'G' },
        { "hierarchy",       required_argument, NULL, 'H' },
        { "transmission",    required_argument, NULL, 'X' },
        { "lock-timeout",    required_argument, NULL, 'O' },
        { "budget-mode",     no_argument,       NULL, 'u' },
        { "select-pmts",     no_argument,       NULL, 'w' },
        { "udp",             no_argument,       NULL, 'U' },
        { "unique-ts-id",    no_argument,       NULL, 'T' },
        { "latency",         required_argument, NULL, 'L' },
        { "retention",       required_argument, NULL, 'E' },
        { "duplicate",       required_argument, NULL, 'd' },
        { "rtp-input",       required_argument, NULL, 'D' },
        { "asi-adapter",     required_argument, NULL, 'A' },
        { "any-type",        no_argument,       NULL, 'z' },
        { "dvb-compliance",  no_argument,       NULL, 'C' },
        { "emm-passthrough", no_argument,       NULL, 'W' },
        { "ecm-passthrough", no_argument,       NULL, 'Y' },
        { "epg-passthrough", no_argument,       NULL, 'e' },
        { "network-name",    no_argument,       NULL, 'M' },
        { "network-id",      no_argument,       NULL, 'N' },
        { "system-charset",  required_argument, NULL, 'j' },
        { "dvb-charset",     required_argument, NULL, 'J' },
        { "provider-name",   required_argument, NULL, 'B' },
        { "logger",          no_argument,       NULL, 'l' },
        { "logger-ident",    required_argument, NULL, 'g' },
        { "print",           required_argument, NULL, 'x' },
        { "quit-timeout",    required_argument, NULL, 'Q' },
        { "quiet",           no_argument,       NULL, 'q' },
        { "help",            no_argument,       NULL, 'h' },
        { "version",         no_argument,       NULL, 'V' },
        { "mrtg-file",       required_argument, NULL, 'Z' },
        { "ca-number",       required_argument, NULL, 'y' },
        { "pidmap",          required_argument, NULL, '0' },
        { "dvr-buf-size",    required_argument, NULL, '2' },
        { 0, 0, 0, 0 }
    };

    while ( (c = getopt_long(i_argc, pp_argv, "q::c:r:t:o:i:a:n:5:f:F:R:s:S:k:v:pb:I:m:P:K:G:H:X:O:uwUTL:E:d:D:A:lg:zCWYeM:N:j:J:B:x:Q:hVZ:y:0:1:2:", long_options, NULL)) != -1 )
    {
        switch ( c )
        {
        case 'q':
            if ( optarg )
            {
                if ( *optarg == 'q' )  /* e.g. -qqq */
                {
                    i_verbose--;
                    while ( *optarg == 'q' )
                    {
                        i_verbose--;
                        optarg++;
                    }
                }
                else
                {
                    i_verbose -= atoi( optarg );  /* e.g. -q2 */
                }
            }
            else
            {
                i_verbose--;  /* -q */
            }
            break;

        case 'c':
            psz_conf_file = optarg;
            /*
             * When configuration file is used it is reasonable to assume that
             * services may be added/removed. If b_select_pmts is not set dvblast
             * is unable to start streaming newly added services in the config.
             */
            b_select_pmts = 1;
            break;

        case 'r':
            psz_srv_socket = optarg;
            break;

        case 't':
            i_ttl_global = strtol( optarg, NULL, 0 );
            break;

        case 'o':
        {
            struct in_addr maddr;
            if ( !inet_aton( optarg, &maddr ) )
                usage();
            memcpy( pi_ssrc_global, &maddr.s_addr, 4 * sizeof(uint8_t) );
            break;
        }

        case 'i':
            i_priority = strtol( optarg, NULL, 0 );
            break;

        case 'a':
            i_adapter = strtol( optarg, NULL, 0 );
            break;

        case 'n':
            i_fenum = strtol( optarg, NULL, 0 );
            break;

        case 'y':
            i_canum = strtol( optarg, NULL, 0 );
            break;

        case '5':
            psz_delsys = optarg;
            break;

        case 'f':
            if (optarg && optarg[0] != '-')
                i_frequency = strtol( optarg, NULL, 0 );
            if ( pf_Open != NULL )
                usage();
#ifdef HAVE_DVB_SUPPORT
            pf_Open = dvb_Open;
            pf_Read = dvb_Read;
            pf_Reset = dvb_Reset;
            pf_SetFilter = dvb_SetFilter;
            pf_UnsetFilter = dvb_UnsetFilter;
#else
            msg_Err( NULL, "DVBlast is compiled without DVB support.");
            exit(1);
#endif
            break;

        case 'F':
            i_fec = strtol( optarg, NULL, 0 );
            break;

        case 'R':
            i_rolloff = strtol( optarg, NULL, 0 );
            break;

        case 's':
            i_srate = strtol( optarg, NULL, 0 );
            break;

        case 'S':
            i_satnum = strtol( optarg, NULL, 16 );
            break;

        case 'k':
            i_uncommitted = strtol( optarg, NULL, 16 );
            break;

        case 'v':
            i_voltage = strtol( optarg, NULL, 0 );
            break;

        case 'p':
            b_tone = 1;
            break;

        case 'b':
            i_bandwidth = strtol( optarg, NULL, 0 );
            break;

        case 'I':
            i_inversion = strtol( optarg, NULL, 0 );
            break;

        case 'm':
            psz_modulation = optarg;
            break;

        case 'P':
            i_pilot = strtol( optarg, NULL, 0 );
            break;

        case '1':
            i_mis = strtol( optarg, NULL, 0 );
            break;

        case 'K':
            i_fec_lp = strtol( optarg, NULL, 0 );
            break;

        case 'G':
            i_guard = strtol( optarg, NULL, 0 );
            break;

        case 'X':
            i_transmission = strtol( optarg, NULL, 0 );
            break;

        case 'O':
            i_frontend_timeout_duration = strtoll( optarg, NULL, 0 ) * 1000;
            break;

        case 'H':
            i_hierarchy = strtol( optarg, NULL, 0 );
            break;

        case 'u':
            b_budget_mode = 1;
            break;

        case 'w':
            b_select_pmts = 1; //!b_select_pmts;
            break;

        case 'U':
            b_udp_global = true;
            break;

        case 'L':
            i_latency_global = strtoll( optarg, NULL, 0 ) * 1000;
            break;

        case 'E':
            i_retention_global = strtoll( optarg, NULL, 0 ) * 1000;
            break;

        case 'd':
            psz_dup_config = optarg;
            break;

        case 'D':
            psz_udp_src = optarg;
            if ( pf_Open != NULL )
                usage();
            pf_Open = udp_Open;
            pf_Read = udp_Read;
            pf_Reset = udp_Reset;
            pf_SetFilter = udp_SetFilter;
            pf_UnsetFilter = udp_UnsetFilter;
            break;

        case 'A':
#ifdef HAVE_ASI_SUPPORT
            if ( pf_Open != NULL )
                usage();
            if ( strncmp(optarg, "deltacast:", 10) == 0)
            {
#ifdef HAVE_ASI_DELTACAST_SUPPORT
                i_asi_adapter = strtol( optarg+10, NULL, 0 );
                pf_Open = asi_deltacast_Open;
                pf_Read = asi_deltacast_Read;
                pf_Reset = asi_deltacast_Reset;
                pf_SetFilter = asi_deltacast_SetFilter;
                pf_UnsetFilter = asi_deltacast_UnsetFilter;
#else
                msg_Err( NULL, "DVBlast is compiled without Deltacast ASI support.");
                exit(1);
#endif
            }
            else
            {
                i_asi_adapter = strtol( optarg, NULL, 0 );
                pf_Open = asi_Open;
                pf_Read = asi_Read;
                pf_Reset = asi_Reset;
                pf_SetFilter = asi_SetFilter;
                pf_UnsetFilter = asi_UnsetFilter;
            }
#else
            msg_Err( NULL, "DVBlast is compiled without ASI support.");
            exit(1);
#endif
            break;

        case 'z':
            b_any_type = 1;
            break;

        case 'C':
            b_dvb_global = true;
            break;

        case 'W':
            b_enable_emm = true;
            break;

        case 'Y':
            b_enable_ecm = true;
            break;
 
        case 'e':
            b_epg_global = true;
            break;

        case 'M':
            psz_network_name = optarg;
            break;

        case 'N':
            i_network_id = strtoul( optarg, NULL, 0 );
            break;

        case 'T':
            b_random_tsid = 1;
            break;

        case 'j':
            psz_native_charset = optarg;
            break;

        case 'J':
            psz_dvb_charset = optarg;
            break;

        case 'B':
            psz_provider_name = optarg;
            break;

        case 'l':
            b_enable_syslog = 1;
            break;

        case 'g':
            psz_syslog_ident = optarg;
            break;

        case 'x':
            b_print_enabled = true;
            if ( !strcmp(optarg, "text") )
                i_print_type = PRINT_TEXT;
            else if ( !strcmp(optarg, "xml") )
                i_print_type = PRINT_XML;
            else
            {
                b_print_enabled = false;
                msg_Warn( NULL, "unrecognized print type %s", optarg );
            }
            /* Make stdout line-buffered */
            setvbuf(stdout, NULL, _IOLBF, 0);
            break;

        case 'Q':
            i_quit_timeout_duration = strtoll( optarg, NULL, 0 ) * 1000;
            break;

        case 'V':
            DisplayVersion();
            exit(0);
            break;

        case 'Z':
            psz_mrtg_file = optarg;
            break;

        case '0': {
            /* We expect a comma separated list of numbers.
               Put them into the pi_newpids array as they appear */
            char *str1;
            char *saveptr = NULL;
            char *tok = NULL;
            int i, i_newpid;
            for (i = 0, str1 = optarg; i < N_MAP_PIDS; i++, str1 = NULL)
            {
                tok = strtok_r(str1, ",", &saveptr);
                if ( !tok )
                    break;
                i_newpid = strtoul(tok, NULL, 0);
                if ( !i_newpid ) {
                     msg_Err( NULL, "Invalid pidmap string" );
                     usage();
                }
                pi_newpids[i] = i_newpid;
            }
            b_do_remap = true;
            break;
        }
#ifdef HAVE_DVB_SUPPORT
        case '2':
            i_dvr_buffer_size = strtol( optarg, NULL, 0 );
            if (!i_dvr_buffer_size)
                usage();	// it exits
            /* roundup to packet size */
            i_dvr_buffer_size += TS_SIZE - 1;
            i_dvr_buffer_size /= TS_SIZE;
            i_dvr_buffer_size *= TS_SIZE;
            break;
#endif
        case 'h':
        default:
            usage();
        }
    }
    if ( optind < i_argc || pf_Open == NULL )
        usage();

    if ( b_enable_syslog )
        msg_Connect( psz_syslog_ident ? psz_syslog_ident : pp_argv[0] );

    if ( i_verbose )
        DisplayVersion();

    msg_Warn( NULL, "restarting" );
    switch (i_print_type) 
    {
        case PRINT_XML:
            printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
            printf("<TS>\n");
            break;
        default:
            break;
    }

    if ( b_udp_global )
    {
        msg_Warn( NULL, "raw UDP output is deprecated.  Please consider using RTP." );
        msg_Warn( NULL, "for DVB-IP compliance you should use RTP." );
    }

    if ( b_epg_global && !b_dvb_global )
    {
        msg_Dbg( NULL, "turning on DVB compliance, required by EPG information" );
        b_dvb_global = true;
    }

    memset( &output_dup, 0, sizeof(output_dup) );
    if ( psz_dup_config != NULL )
    {
        output_config_t config;

        config_Defaults( &config );
        if ( !config_ParseHost( &config, psz_dup_config ) )
            msg_Err( NULL, "Invalid target address for -d switch" );
        else
        {
            output_Init( &output_dup, &config );
            output_Change( &output_dup, &config );
        }

        config_Free( &config );
    }

    if ( strcasecmp( psz_native_charset, psz_dvb_charset ) )
    {
#ifdef HAVE_ICONV
        iconv_t iconv_system = iconv_open( psz_dvb_charset,
                                           psz_native_charset );
        if ( iconv_system != (iconv_t)-1 )
        {
            size_t i = strlen( psz_network_name );
            char *p, *psz_string;
            i_network_name_tmp_size = i * 6;
            p = psz_string = malloc(i_network_name_tmp_size);
            if ( iconv( iconv_system, (char **)&psz_network_name, &i, &p,
                        &i_network_name_tmp_size ) == -1 )
                free( psz_string );
            else
            {
                p_network_name_tmp = psz_string;
                i_network_name_tmp_size = p - psz_string;
            }
            iconv_close( iconv_system );
        }
#else
        msg_Warn( NULL,
                  "unable to convert from %s to %s (iconv is not available)",
                  psz_native_charset, psz_dvb_charset );
#endif
    }
    if ( p_network_name_tmp == NULL )
    {
        p_network_name_tmp = strdup(psz_network_name);
        i_network_name_tmp_size = strlen(psz_network_name);
    }
    p_network_name = dvb_string_set( (uint8_t *)p_network_name_tmp,
                                     i_network_name_tmp_size, psz_dvb_charset,
                                     &i_network_name_size );
    free( p_network_name_tmp );

    /* Set signal handlers */
    memset( &sa, 0, sizeof(struct sigaction) );
    sa.sa_handler = SigHandler;
    sigfillset( &set );

    if ( sigaction( SIGHUP, &sa, NULL ) == -1 || sigaction( SIGINT, &sa, NULL ) == -1 )
    {
        msg_Err( NULL, "couldn't set signal handler: %s", strerror(errno) );
        exit(EXIT_FAILURE);
    }

    srand( time(NULL) * getpid() );

    demux_Open();

    // init the mrtg logfile
    mrtgInit(psz_mrtg_file);

    if ( i_priority > 0 )
    {
        memset( &param, 0, sizeof(struct sched_param) );
        param.sched_priority = i_priority;
        if ( (i_error = pthread_setschedparam( pthread_self(), SCHED_RR,
                                               &param )) )
        {
            msg_Warn( NULL, "couldn't set thread priority: %s",
                      strerror(i_error) );
        }
    }

    config_ReadFile( psz_conf_file );

    if ( psz_srv_socket != NULL )
        comm_Open();

    for ( ; ; )
    {
        block_t *p_ts;

        if ( b_exit_now )
        {
            msg_Info( NULL, "Shutdown was requested." );
            break;
        }

        if ( b_conf_reload )
        {
            b_conf_reload = 0;
            msg_Info( NULL, "Configuration reload was requested." );
            config_ReadFile( psz_conf_file );
        }

        if ( i_quit_timeout && i_quit_timeout <= i_wallclock )
        {
            switch (i_print_type)
            {
            case PRINT_XML:
                printf("</TS>\n");
                break;
            default:
                break;
            }
            exit(EXIT_SUCCESS);
        }

        p_ts = pf_Read( i_poll_timeout );
        if ( p_ts != NULL )
        {
            mrtgAnalyse(p_ts);
            demux_Run( p_ts );
        }
        i_poll_timeout = output_Send();
        if ( i_poll_timeout == -1 || i_poll_timeout > MAX_POLL_TIMEOUT )
            i_poll_timeout = MAX_POLL_TIMEOUT;
    }

    mrtgClose();
    outputs_Close( i_nb_outputs );
    demux_Close();
    free( p_network_name );

    if ( b_enable_syslog )
        msg_Disconnect();

    if ( psz_srv_socket && i_comm_fd > -1 )
        unlink( psz_srv_socket );

    return EXIT_SUCCESS;
}
Exemplo n.º 22
0
Arquivo: vcd.c Projeto: 9034725985/vlc
/*****************************************************************************
 * Block:
 *****************************************************************************/
static block_t *Block( access_t *p_access )
{
    access_sys_t *p_sys = p_access->p_sys;
    int i_blocks = VCD_BLOCKS_ONCE;
    block_t *p_block;

    /* Check end of file */
    if( p_access->info.b_eof ) return NULL;

    /* Check end of title */
    while( p_sys->i_sector >= p_sys->p_sectors[p_sys->i_current_title + 2] )
    {
        if( p_sys->i_current_title + 2 >= p_sys->i_titles )
        {
            p_access->info.b_eof = true;
            return NULL;
        }

        p_sys->i_current_title++;
        p_sys->i_current_seekpoint = 0;
        p_sys->offset = 0;
    }

    /* Don't read after the end of a title */
    if( p_sys->i_sector + i_blocks >=
        p_sys->p_sectors[p_sys->i_current_title + 2] )
    {
        i_blocks = p_sys->p_sectors[p_sys->i_current_title + 2 ] - p_sys->i_sector;
    }

    /* Do the actual reading */
    if( i_blocks < 0 || !( p_block = block_Alloc( i_blocks * VCD_DATA_SIZE ) ) )
    {
        msg_Err( p_access, "cannot get a new block of size: %i",
                 i_blocks * VCD_DATA_SIZE );
        return NULL;
    }

    if( ioctl_ReadSectors( VLC_OBJECT(p_access), p_sys->vcddev,
            p_sys->i_sector, p_block->p_buffer, i_blocks, VCD_TYPE ) < 0 )
    {
        msg_Err( p_access, "cannot read sector %i", p_sys->i_sector );
        block_Release( p_block );

        /* Try to skip one sector (in case of bad sectors) */
        p_sys->offset += VCD_DATA_SIZE;
        p_sys->i_sector++;
        return NULL;
    }

    /* Update seekpoints */
    for( int i_read = 0; i_read < i_blocks; i_read++ )
    {
        input_title_t *t = p_sys->title[p_sys->i_current_title];

        if( t->i_seekpoint > 0 &&
            p_sys->i_current_seekpoint + 1 < t->i_seekpoint &&
            (int64_t) /* Unlikely to go over 8192 PetaB */
                (p_sys->offset + i_read * VCD_DATA_SIZE) >=
            t->seekpoint[p_sys->i_current_seekpoint + 1]->i_byte_offset )
        {
            msg_Dbg( p_access, "seekpoint change" );
            p_sys->i_current_seekpoint++;
        }
    }

    /* Update a few values */
    p_sys->offset += p_block->i_buffer;
    p_sys->i_sector += i_blocks;

    return p_block;
}
Exemplo n.º 23
0
/*****************************************************************************
 * DecodeBlock:
 *****************************************************************************/
static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_block;

    if( !pp_block || !*pp_block ) return NULL;

    p_block = *pp_block;

    if( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
    {
        block_Release( p_block );
        return NULL;
    }

    /* Remove ADTS header if we have decoder specific config */
    if( p_dec->fmt_in.i_extra && p_block->i_buffer > 7 )
    {
        if( p_block->p_buffer[0] == 0xff &&
            ( p_block->p_buffer[1] & 0xf0 ) == 0xf0 ) /* syncword */
        {   /* ADTS header present */
            size_t i_header_size; /* 7 bytes (+ 2 bytes for crc) */
            i_header_size = 7 + ( ( p_block->p_buffer[1] & 0x01 ) ? 0 : 2 );
            /* FIXME: multiple blocks per frame */
            if( p_block->i_buffer > i_header_size )
            {
                p_block->p_buffer += i_header_size;
                p_block->i_buffer -= i_header_size;
            }
        }
    }

    /* Append the block to the temporary buffer */
    if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
    {
        size_t  i_buffer_size = p_sys->i_buffer + p_block->i_buffer;
        uint8_t *p_buffer     = realloc( p_sys->p_buffer, i_buffer_size );
        if( p_buffer )
        {
            p_sys->i_buffer_size = i_buffer_size;
            p_sys->p_buffer      = p_buffer;
        }
        else
        {
            p_block->i_buffer = 0;
        }
    }

    if( p_block->i_buffer > 0 )
    {
        vlc_memcpy( &p_sys->p_buffer[p_sys->i_buffer],
                     p_block->p_buffer, p_block->i_buffer );
        p_sys->i_buffer += p_block->i_buffer;
        p_block->i_buffer = 0;
    }

    if( p_dec->fmt_out.audio.i_rate == 0 && p_dec->fmt_in.i_extra > 0 )
    {
        /* We have a decoder config so init the handle */
        unsigned long i_rate;
        unsigned char i_channels;

        if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
                          p_dec->fmt_in.i_extra,
                          &i_rate, &i_channels ) >= 0 )
        {
            p_dec->fmt_out.audio.i_rate = i_rate;
            p_dec->fmt_out.audio.i_channels = i_channels;
            p_dec->fmt_out.audio.i_physical_channels
                = p_dec->fmt_out.audio.i_original_channels
                = pi_channels_guessed[i_channels];

            date_Init( &p_sys->date, i_rate, 1 );
        }
    }

    if( p_dec->fmt_out.audio.i_rate == 0 && p_sys->i_buffer )
    {
        unsigned long i_rate;
        unsigned char i_channels;

        /* Init faad with the first frame */
        if( faacDecInit( p_sys->hfaad,
                         p_sys->p_buffer, p_sys->i_buffer,
                         &i_rate, &i_channels ) < 0 )
        {
            block_Release( p_block );
            return NULL;
        }

        p_dec->fmt_out.audio.i_rate = i_rate;
        p_dec->fmt_out.audio.i_channels = i_channels;
        p_dec->fmt_out.audio.i_physical_channels
            = p_dec->fmt_out.audio.i_original_channels
            = pi_channels_guessed[i_channels];
        date_Init( &p_sys->date, i_rate, 1 );
    }

    if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != date_Get( &p_sys->date ) )
    {
        date_Set( &p_sys->date, p_block->i_pts );
    }
    else if( !date_Get( &p_sys->date ) )
    {
        /* We've just started the stream, wait for the first PTS. */
        block_Release( p_block );
        p_sys->i_buffer = 0;
        return NULL;
    }

    /* Decode all data */
    if( p_sys->i_buffer )
    {
        void *samples;
        faacDecFrameInfo frame;
        aout_buffer_t *p_out;
        int i, j;

        samples = faacDecDecode( p_sys->hfaad, &frame,
                                 p_sys->p_buffer, p_sys->i_buffer );

        if( frame.error > 0 )
        {
            msg_Warn( p_dec, "%s", faacDecGetErrorMessage( frame.error ) );

            /* Flush the buffer */
            p_sys->i_buffer = 0;
            block_Release( p_block );
            return NULL;
        }

        if( frame.channels <= 0 || frame.channels > 8 || frame.channels == 7 )
        {
            msg_Warn( p_dec, "invalid channels count: %i", frame.channels );

            /* Flush the buffer */
            p_sys->i_buffer -= frame.bytesconsumed;
            if( p_sys->i_buffer > 0 )
            {
                memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed],
                         p_sys->i_buffer );
            }
            block_Release( p_block );
            return NULL;
        }

        if( frame.samples <= 0 )
        {
            msg_Warn( p_dec, "decoded zero sample" );

            /* Flush the buffer */
            p_sys->i_buffer -= frame.bytesconsumed;
            if( p_sys->i_buffer > 0 )
            {
                memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed],
                         p_sys->i_buffer );
            }
            block_Release( p_block );
            return NULL;
        }

        /* We decoded a valid frame */
        if( p_dec->fmt_out.audio.i_rate != frame.samplerate )
        {
            date_Init( &p_sys->date, frame.samplerate, 1 );
            date_Set( &p_sys->date, p_block->i_pts );
        }
        p_block->i_pts = VLC_TS_INVALID;  /* PTS is valid only once */

        p_dec->fmt_out.audio.i_rate = frame.samplerate;
        p_dec->fmt_out.audio.i_channels = frame.channels;
        p_dec->fmt_out.audio.i_physical_channels
            = p_dec->fmt_out.audio.i_original_channels
            = pi_channels_guessed[frame.channels];

        /* Adjust stream info when dealing with SBR/PS */
        bool b_sbr = (frame.sbr == 1) || (frame.sbr == 2);
        if( p_sys->b_sbr != b_sbr || p_sys->b_ps != frame.ps )
        {
            const char *psz_ext = (b_sbr && frame.ps) ? "SBR+PS" :
                                    b_sbr ? "SBR" : "PS";

            msg_Dbg( p_dec, "AAC %s (channels: %u, samplerate: %lu)",
                    psz_ext, frame.channels, frame.samplerate );

            if( !p_dec->p_description )
                p_dec->p_description = vlc_meta_New();
            if( p_dec->p_description )
                vlc_meta_AddExtra( p_dec->p_description, _("AAC extension"), psz_ext );

            p_sys->b_sbr = b_sbr;
            p_sys->b_ps = frame.ps;
        }

        /* Convert frame.channel_position to our own channel values */
        p_dec->fmt_out.audio.i_physical_channels = 0;
        for( i = 0; i < frame.channels; i++ )
        {
            /* Find the channel code */
            for( j = 0; j < MAX_CHANNEL_POSITIONS; j++ )
            {
                if( frame.channel_position[i] == pi_channels_in[j] )
                    break;
            }
            if( j >= MAX_CHANNEL_POSITIONS )
            {
                msg_Warn( p_dec, "unknown channel ordering" );
                /* Invent something */
                j = i;
            }
            /* */
            p_sys->pi_channel_positions[i] = pi_channels_out[j];
            if( p_dec->fmt_out.audio.i_physical_channels & pi_channels_out[j] )
                frame.channels--; /* We loose a duplicated channel */
            else
                p_dec->fmt_out.audio.i_physical_channels |= pi_channels_out[j];
        }
        p_dec->fmt_out.audio.i_original_channels =
            p_dec->fmt_out.audio.i_physical_channels;

        p_out = decoder_NewAudioBuffer(p_dec, frame.samples/frame.channels);
        if( p_out == NULL )
        {
            p_sys->i_buffer = 0;
            block_Release( p_block );
            return NULL;
        }

        p_out->i_pts = date_Get( &p_sys->date );
        p_out->i_length = date_Increment( &p_sys->date,
                                          frame.samples / frame.channels )
                          - p_out->i_pts;

        DoReordering( (uint32_t *)p_out->p_buffer, samples,
                      frame.samples / frame.channels, frame.channels,
                      p_sys->pi_channel_positions );

        p_sys->i_buffer -= frame.bytesconsumed;
        if( p_sys->i_buffer > 0 )
        {
            memmove( p_sys->p_buffer, &p_sys->p_buffer[frame.bytesconsumed],
                     p_sys->i_buffer );
        }

        return p_out;
    }

    block_Release( p_block );
    return NULL;
}
Exemplo n.º 24
0
Arquivo: vcd.c Projeto: 9034725985/vlc
/*****************************************************************************
 * VCDOpen: open vcd
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    access_t     *p_access = (access_t *)p_this;
    access_sys_t *p_sys;
    if( p_access->psz_filepath == NULL )
        return VLC_EGENERIC;

    char *psz_dup = ToLocaleDup( p_access->psz_filepath );
    char *psz;
    int i_title = 0;
    int i_chapter = 0;
    vcddev_t *vcddev;

    /* Command line: vcd://[dev_path][#title[,chapter]] */
    if( ( psz = strchr( psz_dup, '#' ) ) )
    {
        *psz++ = '\0';

        i_title = strtol( psz, &psz, 0 );
        if( *psz )
            i_chapter = strtol( psz+1, &psz, 0 );
    }

    if( *psz_dup == '\0' )
    {
        free( psz_dup );

        /* Only when selected */
        if( strcmp( p_access->psz_access, "vcd" ) &&
            strcmp( p_access->psz_access, "svcd" ) )
            return VLC_EGENERIC;

        psz_dup = var_CreateGetString( p_access, "vcd" );
        if( *psz_dup == '\0' )
        {
            free( psz_dup );
            return VLC_EGENERIC;
        }
    }

#if defined( _WIN32 ) || defined( __OS2__ )
    if( psz_dup[0] && psz_dup[1] == ':' &&
        psz_dup[2] == '\\' && psz_dup[3] == '\0' ) psz_dup[2] = '\0';
#endif

    /* Open VCD */
    vcddev = ioctl_Open( p_this, psz_dup );
    free( psz_dup );
    if( !vcddev )
        return VLC_EGENERIC;

    /* Set up p_access */
    p_access->p_sys = p_sys = calloc( 1, sizeof( access_sys_t ) );
    if( unlikely(!p_sys ))
        goto error;
    p_sys->vcddev = vcddev;
    p_sys->offset = 0;

    /* We read the Table Of Content information */
    p_sys->i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
                                          p_sys->vcddev, &p_sys->p_sectors );
    if( p_sys->i_titles < 0 )
    {
        msg_Err( p_access, "unable to count tracks" );
        goto error;
    }
    else if( p_sys->i_titles <= 1 )
    {
        msg_Err( p_access, "no movie tracks found" );
        goto error;
    }

    /* The first title isn't usable */
    p_sys->i_titles--;

    for( int i = 0; i < p_sys->i_titles; i++ )
    {
        p_sys->title[i] = vlc_input_title_New();

        msg_Dbg( p_access, "title[%d] start=%d", i, p_sys->p_sectors[1+i] );
        msg_Dbg( p_access, "title[%d] end=%d", i, p_sys->p_sectors[i+2] );
    }

    /* Map entry points into chapters */
    if( EntryPoints( p_access ) )
    {
        msg_Warn( p_access, "could not read entry points, will not use them" );
    }

    /* Starting title/chapter and sector */
    if( i_title >= p_sys->i_titles )
        i_title = 0;
    if( i_chapter >= p_sys->title[i_title]->i_seekpoint )
        i_chapter = 0;

    p_sys->i_sector = p_sys->p_sectors[1+i_title];
    if( i_chapter > 0 )
    {
        p_sys->i_sector += ( p_sys->title[i_title]->seekpoint[i_chapter]->i_byte_offset /
                           VCD_DATA_SIZE );
    }

    /* p_access */
    p_access->pf_read    = NULL;
    p_access->pf_block   = Block;
    p_access->pf_control = Control;
    p_access->pf_seek    = Seek;

    p_access->info.b_eof       = false;

    p_sys->i_current_title = i_title;
    p_sys->i_current_seekpoint = i_chapter;
    p_sys->offset = (uint64_t)(p_sys->i_sector - p_sys->p_sectors[1+i_title]) *
                               VCD_DATA_SIZE;

    return VLC_SUCCESS;

error:
    ioctl_Close( VLC_OBJECT(p_access), vcddev );
    free( p_sys );
    return VLC_EGENERIC;
}
Exemplo n.º 25
0
/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*) p_this;
    int i_cat, i_codec_id, i_result;
    const char *psz_namecodec;

    AVCodecContext *p_context = NULL;
    AVCodec        *p_codec = NULL;

    /* *** determine codec type *** */
    if( !GetFfmpegCodec( p_dec->fmt_in.i_codec, &i_cat, &i_codec_id,
                             &psz_namecodec ) )
    {
        return VLC_EGENERIC;
    }

    /* Initialization must be done before avcodec_find_decoder() */
    InitLibavcodec(p_this);

    /* *** ask ffmpeg for a decoder *** */
    p_codec = avcodec_find_decoder( i_codec_id );
    if( !p_codec )
    {
        msg_Dbg( p_dec, "codec not found (%s)", psz_namecodec );
        return VLC_EGENERIC;
    }

    /* *** get a p_context *** */
    p_context = avcodec_alloc_context();
    if( !p_context )
        return VLC_ENOMEM;
    p_context->debug = var_InheritInteger( p_dec, "ffmpeg-debug" );
    p_context->opaque = (void *)p_this;

    /* Set CPU capabilities */
    unsigned i_cpu = vlc_CPU();
    p_context->dsp_mask = 0;
    if( !(i_cpu & CPU_CAPABILITY_MMX) )
    {
        p_context->dsp_mask |= FF_MM_MMX;
    }
    if( !(i_cpu & CPU_CAPABILITY_MMXEXT) )
    {
        p_context->dsp_mask |= FF_MM_MMXEXT;
    }
    if( !(i_cpu & CPU_CAPABILITY_3DNOW) )
    {
        p_context->dsp_mask |= FF_MM_3DNOW;
    }
    if( !(i_cpu & CPU_CAPABILITY_SSE) )
    {
        p_context->dsp_mask |= FF_MM_SSE;
    }
    if( !(i_cpu & CPU_CAPABILITY_SSE2) )
    {
        p_context->dsp_mask |= FF_MM_SSE2;
    }
#ifdef FF_MM_SSE3
    if( !(i_cpu & CPU_CAPABILITY_SSE3) )
        p_context->dsp_mask |= FF_MM_SSE3;
#endif
#ifdef FF_MM_SSSE3
    if( !(i_cpu & CPU_CAPABILITY_SSSE3) )
        p_context->dsp_mask |= FF_MM_SSSE3;
#endif
#ifdef FF_MM_SSE4
    if( !(i_cpu & CPU_CAPABILITY_SSE4_1) )
        p_context->dsp_mask |= FF_MM_SSE4;
#endif
#ifdef FF_MM_SSE42
    if( !(i_cpu & CPU_CAPABILITY_SSE4_2) )
        p_context->dsp_mask |= FF_MM_SSE42;
#endif

    p_dec->b_need_packetized = true;
    switch( i_cat )
    {
    case VIDEO_ES:
        p_dec->pf_decode_video = DecodeVideo;
        i_result =  InitVideoDec ( p_dec, p_context, p_codec,
                                       i_codec_id, psz_namecodec );
        break;
    case AUDIO_ES:
        p_dec->pf_decode_audio = DecodeAudio;
        i_result =  InitAudioDec ( p_dec, p_context, p_codec,
                                       i_codec_id, psz_namecodec );
        break;
    case SPU_ES:
        p_dec->pf_decode_sub = DecodeSubtitle;
        i_result =  InitSubtitleDec( p_dec, p_context, p_codec,
                                     i_codec_id, psz_namecodec );
        break;
    default:
        i_result = VLC_EGENERIC;
    }

    if( i_result == VLC_SUCCESS )
    {
        p_dec->p_sys->i_cat = i_cat;
        if( p_context->profile != FF_PROFILE_UNKNOWN)
            p_dec->fmt_in.i_profile = p_context->profile;
        if( p_context->level != FF_LEVEL_UNKNOWN)
            p_dec->fmt_in.i_level = p_context->level;
    }

    return i_result;
}
Exemplo n.º 26
0
static int sms_Read( stream_t *s, uint8_t *p_read, int i_read )
{
    stream_sys_t *p_sys = s->p_sys;
    int copied = 0;
    chunk_t *chunk = NULL;

    do
    {
        chunk = get_chunk( s, true );
        if( !chunk )
            return copied;

        if( chunk->read_pos >= (int)chunk->size )
        {
            if( chunk->type == VIDEO_ES ||
                ( !SMS_GET_SELECTED_ST( VIDEO_ES ) && chunk->type == AUDIO_ES ) )
            {
                vlc_mutex_lock( &p_sys->download.lock_wait );
                p_sys->playback.toffset += chunk->duration;
                vlc_mutex_unlock( &p_sys->download.lock_wait );
                vlc_cond_signal( &p_sys->download.wait);
            }
            if( !p_sys->b_cache || p_sys->b_live )
            {
                FREENULL( chunk->data );
                chunk->read_pos = 0;
            }

            chunk->read_pos = 0;

            p_sys->playback.index += 1;
            msg_Dbg( s, "Incrementing playback index" );

            continue;
        }

        if( chunk->read_pos == 0 )
        {
            const char *verb = p_read == NULL ? "skipping" : "reading";
            msg_Dbg( s, "%s chunk %u (%u bytes), type %i",
                        verb, chunk->sequence, i_read, chunk->type );
            /* check integrity */
            uint32_t type;
            uint8_t *slice = chunk->data;
            SMS_GET4BYTES( type );
            SMS_GETFOURCC( type );
            assert( type == ATOM_moof || type == ATOM_uuid );
        }

        int len = -1;
        uint8_t *src = chunk->data + chunk->read_pos;
        if( i_read <= chunk->size - chunk->read_pos )
            len = i_read;
        else
            len = chunk->size - chunk->read_pos;

        if( len > 0 )
        {
            if( p_read ) /* otherwise caller skips data */
                memcpy( p_read + copied, src, len );
            chunk->read_pos += len;
            copied += len;
            i_read -= len;
        }


    } while ( i_read > 0 );

    return copied;
}
Exemplo n.º 27
0
static void transcode_video_encoder_init( sout_stream_t *p_stream,
                                          sout_stream_id_t *id )
{
    sout_stream_sys_t *p_sys = p_stream->p_sys;

    const es_format_t *p_fmt_out = &id->p_decoder->fmt_out;
    if( id->p_f_chain ) {
        p_fmt_out = filter_chain_GetFmtOut( id->p_f_chain );
    }
    if( id->p_uf_chain ) {
        p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
    }

    /* Calculate scaling
     * width/height of source */
    int i_src_visible_width = p_fmt_out->video.i_visible_width;
    int i_src_visible_height = p_fmt_out->video.i_visible_height;

    if (i_src_visible_width == 0)
        i_src_visible_width = p_fmt_out->video.i_width;
    if (i_src_visible_height == 0)
        i_src_visible_height = p_fmt_out->video.i_height;


    /* with/height scaling */
    float f_scale_width = 1;
    float f_scale_height = 1;

    /* aspect ratio */
    float f_aspect = (double)p_fmt_out->video.i_sar_num *
                     p_fmt_out->video.i_width /
                     p_fmt_out->video.i_sar_den /
                     p_fmt_out->video.i_height;

    msg_Dbg( p_stream, "decoder aspect is %f:1", f_aspect );

    /* Change f_aspect from source frame to source pixel */
    f_aspect = f_aspect * i_src_visible_height / i_src_visible_width;
    msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );

    /* Calculate scaling factor for specified parameters */
    if( id->p_encoder->fmt_out.video.i_width <= 0 &&
        id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
    {
        /* Global scaling. Make sure width will remain a factor of 16 */
        float f_real_scale;
        int  i_new_height;
        int i_new_width = i_src_visible_width * p_sys->f_scale;

        if( i_new_width % 16 <= 7 && i_new_width >= 16 )
            i_new_width -= i_new_width % 16;
        else
            i_new_width += 16 - i_new_width % 16;

        f_real_scale = (float)( i_new_width ) / (float) i_src_visible_width;

        i_new_height = __MAX( 16, i_src_visible_height * (float)f_real_scale );

        f_scale_width = f_real_scale;
        f_scale_height = (float) i_new_height / (float) i_src_visible_height;
    }
    else if( id->p_encoder->fmt_out.video.i_width > 0 &&
             id->p_encoder->fmt_out.video.i_height <= 0 )
    {
        /* Only width specified */
        f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_visible_width;
        f_scale_height = f_scale_width;
    }
    else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
             id->p_encoder->fmt_out.video.i_height > 0 )
    {
         /* Only height specified */
         f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_visible_height;
         f_scale_width = f_scale_height;
     }
     else if( id->p_encoder->fmt_out.video.i_width > 0 &&
              id->p_encoder->fmt_out.video.i_height > 0 )
     {
         /* Width and height specified */
         f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_visible_width;
         f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_visible_height;
     }

     /* check maxwidth and maxheight */
     if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
                                                     i_src_visible_width )
     {
         f_scale_width = (float)p_sys->i_maxwidth / i_src_visible_width;
     }

     if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
                                                       i_src_visible_height )
     {
         f_scale_height = (float)p_sys->i_maxheight / i_src_visible_height;
     }


     /* Change aspect ratio from source pixel to scaled pixel */
     f_aspect = f_aspect * f_scale_height / f_scale_width;
     msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );

     /* f_scale_width and f_scale_height are now final */
     /* Calculate width, height from scaling
      * Make sure its multiple of 2
      */
     /* width/height of output stream */
     int i_dst_visible_width =  2 * (int)(f_scale_width*i_src_visible_width/2+0.5);
     int i_dst_visible_height = 2 * (int)(f_scale_height*i_src_visible_height/2+0.5);
     int i_dst_width =  2 * (int)(f_scale_width*p_fmt_out->video.i_width/2+0.5);
     int i_dst_height = 2 * (int)(f_scale_height*p_fmt_out->video.i_height/2+0.5);

     /* Change aspect ratio from scaled pixel to output frame */
     f_aspect = f_aspect * i_dst_visible_width / i_dst_visible_height;

     /* Store calculated values */
     id->p_encoder->fmt_out.video.i_width = i_dst_width;
     id->p_encoder->fmt_out.video.i_visible_width = i_dst_visible_width;
     id->p_encoder->fmt_out.video.i_height = i_dst_height;
     id->p_encoder->fmt_out.video.i_visible_height = i_dst_visible_height;

     id->p_encoder->fmt_in.video.i_width = i_dst_width;
     id->p_encoder->fmt_in.video.i_visible_width = i_dst_visible_width;
     id->p_encoder->fmt_in.video.i_height = i_dst_height;
     id->p_encoder->fmt_in.video.i_visible_height = i_dst_visible_height;

     msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
         i_src_visible_width, i_src_visible_height,
         i_dst_visible_width, i_dst_visible_height
     );

    /* Handle frame rate conversion */
    if( !id->p_encoder->fmt_out.video.i_frame_rate ||
        !id->p_encoder->fmt_out.video.i_frame_rate_base )
    {
        if( p_fmt_out->video.i_frame_rate &&
            p_fmt_out->video.i_frame_rate_base )
        {
            id->p_encoder->fmt_out.video.i_frame_rate =
                p_fmt_out->video.i_frame_rate;
            id->p_encoder->fmt_out.video.i_frame_rate_base =
                p_fmt_out->video.i_frame_rate_base;
        }
        else
        {
            /* Pick a sensible default value */
            id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
            id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
        }
    }

    id->p_encoder->fmt_in.video.i_frame_rate =
        id->p_encoder->fmt_out.video.i_frame_rate;
    id->p_encoder->fmt_in.video.i_frame_rate_base =
        id->p_encoder->fmt_out.video.i_frame_rate_base;

    date_Init( &id->interpolated_pts,
               id->p_encoder->fmt_out.video.i_frame_rate,
               id->p_encoder->fmt_out.video.i_frame_rate_base );

    /* Check whether a particular aspect ratio was requested */
    if( id->p_encoder->fmt_out.video.i_sar_num <= 0 ||
        id->p_encoder->fmt_out.video.i_sar_den <= 0 )
    {
        vlc_ureduce( &id->p_encoder->fmt_out.video.i_sar_num,
                     &id->p_encoder->fmt_out.video.i_sar_den,
                     (uint64_t)p_fmt_out->video.i_sar_num * i_src_visible_width  * i_dst_visible_height,
                     (uint64_t)p_fmt_out->video.i_sar_den * i_src_visible_height * i_dst_visible_width,
                     0 );
    }
    else
    {
        vlc_ureduce( &id->p_encoder->fmt_out.video.i_sar_num,
                     &id->p_encoder->fmt_out.video.i_sar_den,
                     id->p_encoder->fmt_out.video.i_sar_num,
                     id->p_encoder->fmt_out.video.i_sar_den,
                     0 );
    }

    id->p_encoder->fmt_in.video.i_sar_num =
        id->p_encoder->fmt_out.video.i_sar_num;
    id->p_encoder->fmt_in.video.i_sar_den =
        id->p_encoder->fmt_out.video.i_sar_den;

    msg_Dbg( p_stream, "encoder aspect is %i:%i",
             id->p_encoder->fmt_out.video.i_sar_num * id->p_encoder->fmt_out.video.i_width,
             id->p_encoder->fmt_out.video.i_sar_den * id->p_encoder->fmt_out.video.i_height );

    id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
}
Exemplo n.º 28
0
static sout_stream_id_sys_t * AddOut( sout_stream_t *p_stream, const es_format_t *p_fmt )
{
    out_sout_stream_sys_t *p_sys = (out_sout_stream_sys_t *)p_stream->p_sys;
    bridge_t *p_bridge;
    bridged_es_t *p_es;
    int i;

    if ( p_sys->b_inited )
    {
        msg_Err( p_stream, "bridge-out can only handle 1 es at a time." );
        return NULL;
    }
    p_sys->b_inited = true;

    vlc_mutex_lock( &lock );

    p_bridge = var_GetAddress( p_stream->p_libvlc, p_sys->psz_name );
    if ( p_bridge == NULL )
    {
        p_bridge = xmalloc( sizeof( bridge_t ) );

        var_Create( p_stream->p_libvlc, p_sys->psz_name, VLC_VAR_ADDRESS );
        var_SetAddress( p_stream->p_libvlc, p_sys->psz_name, p_bridge );

        p_bridge->i_es_num = 0;
        p_bridge->pp_es = NULL;
    }

    for ( i = 0; i < p_bridge->i_es_num; i++ )
    {
        if ( p_bridge->pp_es[i]->b_empty && !p_bridge->pp_es[i]->b_changed )
            break;
    }

    if ( i == p_bridge->i_es_num )
    {
        p_bridge->pp_es = xrealloc( p_bridge->pp_es,
                          (p_bridge->i_es_num + 1) * sizeof(bridged_es_t *) );
        p_bridge->i_es_num++;
        p_bridge->pp_es[i] = xmalloc( sizeof(bridged_es_t) );
    }

    p_sys->p_es = p_es = p_bridge->pp_es[i];

    p_es->fmt = *p_fmt;
    p_es->fmt.i_id = p_sys->i_id;
    p_es->p_block = NULL;
    p_es->pp_last = &p_es->p_block;
    p_es->b_empty = false;

    p_es->id = NULL;
    p_es->i_last = VLC_TS_INVALID;
    p_es->b_changed = true;

    msg_Dbg( p_stream, "bridging out input codec=%4.4s id=%d pos=%d",
             (char*)&p_es->fmt.i_codec, p_es->fmt.i_id, i );

    vlc_mutex_unlock( &lock );

    return (sout_stream_id_sys_t *)p_sys;
}
Exemplo n.º 29
0
int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_t *id,
                                    block_t *in, block_t **out )
{
    sout_stream_sys_t *p_sys = p_stream->p_sys;
    bool b_need_duplicate = false;
    picture_t *p_pic;
    *out = NULL;

    if( unlikely( in == NULL ) )
    {
        if( p_sys->i_threads == 0 )
        {
            block_t *p_block;
            do {
                p_block = id->p_encoder->pf_encode_video(id->p_encoder, NULL );
                block_ChainAppend( out, p_block );
            } while( p_block );
        }
        else
        {
            /*
             * FIXME: we need EncoderThread() to flush buffers and signal us
             * when it's done so we can send the last frames to the chain
             */
        }
        return VLC_SUCCESS;
    }


    while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
    {

        if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
        {
            mtime_t current_date = mdate();
            if( unlikely( current_date + 50000 > p_pic->date ) )
            {
                msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
                         current_date + 50000 - p_pic->date );
                picture_Release( p_pic );
                continue;
            }
        }

        if( p_sys->b_master_sync )
        {
            mtime_t i_master_drift = p_sys->i_master_drift;
            mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
            mtime_t i_video_drift = p_pic->date - i_pts;

            if ( unlikely( i_video_drift > MASTER_SYNC_MAX_DRIFT
                  || i_video_drift < -MASTER_SYNC_MAX_DRIFT ) )
            {
                msg_Dbg( p_stream,
                    "video drift is too high (%"PRId64", resetting master sync",
                    i_video_drift );
                date_Set( &id->interpolated_pts, p_pic->date );
                i_pts = p_pic->date + 1;
            }
            i_video_drift = p_pic->date - i_pts;
            b_need_duplicate = false;

            /* Set the pts of the frame being encoded */
            p_pic->date = i_pts;

            if( unlikely( i_video_drift < (i_master_drift - 50000) ) )
            {
#if 0
                msg_Dbg( p_stream, "dropping frame (%i)",
                         (int)(i_video_drift - i_master_drift) );
#endif
                picture_Release( p_pic );
                continue;
            }
            else if( unlikely( i_video_drift > (i_master_drift + 50000) ) )
            {
#if 0
                msg_Dbg( p_stream, "adding frame (%i)",
                         (int)(i_video_drift - i_master_drift) );
#endif
                b_need_duplicate = true;
            }
        }
        if( unlikely (
             id->p_encoder->p_module &&
             !video_format_IsSimilar( &p_sys->fmt_input_video, &id->p_decoder->fmt_out.video )
            )
          )
        {
            msg_Info( p_stream, "aspect-ratio changed, reiniting. %i -> %i : %i -> %i.",
                        p_sys->fmt_input_video.i_sar_num, id->p_decoder->fmt_out.video.i_sar_num,
                        p_sys->fmt_input_video.i_sar_den, id->p_decoder->fmt_out.video.i_sar_den
                    );
            /* Close filters */
            if( id->p_f_chain )
                filter_chain_Delete( id->p_f_chain );
            id->p_f_chain = NULL;
            if( id->p_uf_chain )
                filter_chain_Delete( id->p_uf_chain );
            id->p_uf_chain = NULL;

            /* Reinitialize filters */
            id->p_encoder->fmt_out.video.i_width  = p_sys->i_width & ~1;
            id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
            id->p_encoder->fmt_out.video.i_sar_num = id->p_encoder->fmt_out.video.i_sar_den = 0;

            transcode_video_filter_init( p_stream, id );
            transcode_video_encoder_init( p_stream, id );
            conversion_video_filter_append( id );
            memcpy( &p_sys->fmt_input_video, &id->p_decoder->fmt_out.video, sizeof(video_format_t));
        }


        if( unlikely( !id->p_encoder->p_module ) )
        {
            if( id->p_f_chain )
                filter_chain_Delete( id->p_f_chain );
            if( id->p_uf_chain )
                filter_chain_Delete( id->p_uf_chain );
            id->p_f_chain = id->p_uf_chain = NULL;

            transcode_video_filter_init( p_stream, id );
            transcode_video_encoder_init( p_stream, id );
            conversion_video_filter_append( id );
            memcpy( &p_sys->fmt_input_video, &id->p_decoder->fmt_out.video, sizeof(video_format_t));

            if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
            {
                picture_Release( p_pic );
                transcode_video_close( p_stream, id );
                id->b_transcode = false;
                return VLC_EGENERIC;
            }
        }

        /* Run the filter and output chains; first with the picture,
         * and then with NULL as many times as we need until they
         * stop outputting frames.
         */
        for ( ;; ) {
            picture_t *p_filtered_pic = p_pic;

            /* Run filter chain */
            if( id->p_f_chain )
                p_filtered_pic = filter_chain_VideoFilter( id->p_f_chain, p_filtered_pic );
            if( !p_filtered_pic )
                break;

            for ( ;; ) {
                picture_t *p_user_filtered_pic = p_filtered_pic;

                /* Run user specified filter chain */
                if( id->p_uf_chain )
                    p_user_filtered_pic = filter_chain_VideoFilter( id->p_uf_chain, p_user_filtered_pic );
                if( !p_user_filtered_pic )
                    break;

                OutputFrame( p_sys, p_user_filtered_pic, b_need_duplicate, p_stream, id, out );
                b_need_duplicate = false;

                p_filtered_pic = NULL;
            }

            p_pic = NULL;
        }
    }

    if( p_sys->i_threads >= 1 )
    {
        /* Pick up any return data the encoder thread wants to output. */
        vlc_mutex_lock( &p_sys->lock_out );
        *out = p_sys->p_buffers;
        p_sys->p_buffers = NULL;
        vlc_mutex_unlock( &p_sys->lock_out );
    }

    return VLC_SUCCESS;
}
Exemplo n.º 30
0
static int AVI_ChunkRead_strf( stream_t *s, avi_chunk_t *p_chk )
{
    avi_chunk_t *p_strh;

    AVI_READCHUNK_ENTER;
    if( p_chk->common.p_father == NULL )
    {
        msg_Err( (vlc_object_t*)s, "malformed avi file" );
        AVI_READCHUNK_EXIT( VLC_EGENERIC );
    }
    if( !( p_strh = AVI_ChunkFind( p_chk->common.p_father, AVIFOURCC_strh, 0 ) ) )
    {
        msg_Err( (vlc_object_t*)s, "malformed avi file" );
        AVI_READCHUNK_EXIT( VLC_EGENERIC );
    }

    switch( p_strh->strh.i_type )
    {
        case( AVIFOURCC_auds ):
            p_chk->strf.auds.i_cat = AUDIO_ES;
            p_chk->strf.auds.p_wf = xmalloc( __MAX( p_chk->common.i_chunk_size, sizeof( WAVEFORMATEX ) ) );
            if ( !p_chk->strf.auds.p_wf )
            {
                AVI_READCHUNK_EXIT( VLC_ENOMEM );
            }
            AVI_READ2BYTES( p_chk->strf.auds.p_wf->wFormatTag );
            AVI_READ2BYTES( p_chk->strf.auds.p_wf->nChannels );
            AVI_READ4BYTES( p_chk->strf.auds.p_wf->nSamplesPerSec );
            AVI_READ4BYTES( p_chk->strf.auds.p_wf->nAvgBytesPerSec );
            AVI_READ2BYTES( p_chk->strf.auds.p_wf->nBlockAlign );
            AVI_READ2BYTES( p_chk->strf.auds.p_wf->wBitsPerSample );

            if( p_chk->strf.auds.p_wf->wFormatTag != WAVE_FORMAT_PCM
                 && p_chk->common.i_chunk_size > sizeof( WAVEFORMATEX ) )
            {
                AVI_READ2BYTES( p_chk->strf.auds.p_wf->cbSize );

                /* prevent segfault */
                if( p_chk->strf.auds.p_wf->cbSize >
                        p_chk->common.i_chunk_size - sizeof( WAVEFORMATEX ) )
                {
                    p_chk->strf.auds.p_wf->cbSize =
                        p_chk->common.i_chunk_size - sizeof( WAVEFORMATEX );
                }

                if( p_chk->strf.auds.p_wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE )
                {
                    msg_Dbg( s, "Extended header found" );
                }
            }
            else
            {
                p_chk->strf.auds.p_wf->cbSize = 0;
            }
            if( p_chk->strf.auds.p_wf->cbSize > 0 )
            {
                memcpy( &p_chk->strf.auds.p_wf[1] ,
                        p_buff + 8 + sizeof( WAVEFORMATEX ),    /*  8=fourcc+size */
                        p_chk->strf.auds.p_wf->cbSize );
            }
#ifdef AVI_DEBUG
            msg_Dbg( (vlc_object_t*)s,
                     "strf: audio:0x%4.4x channels:%d %dHz %dbits/sample %dkb/s",
                     p_chk->strf.auds.p_wf->wFormatTag,
                     p_chk->strf.auds.p_wf->nChannels,
                     p_chk->strf.auds.p_wf->nSamplesPerSec,
                     p_chk->strf.auds.p_wf->wBitsPerSample,
                     p_chk->strf.auds.p_wf->nAvgBytesPerSec * 8 / 1024 );
#endif
            break;
        case( AVIFOURCC_vids ):
            p_strh->strh.i_samplesize = 0; /* XXX for ffmpeg avi file */
            p_chk->strf.vids.i_cat = VIDEO_ES;
            p_chk->strf.vids.p_bih = xmalloc( __MAX( p_chk->common.i_chunk_size,
                                         sizeof( *p_chk->strf.vids.p_bih ) ) );
            if ( !p_chk->strf.vids.p_bih )
            {
                AVI_READCHUNK_EXIT( VLC_ENOMEM );
            }
            AVI_READ4BYTES( p_chk->strf.vids.p_bih->biSize );
            AVI_READ4BYTES( p_chk->strf.vids.p_bih->biWidth );
            AVI_READ4BYTES( p_chk->strf.vids.p_bih->biHeight );
            AVI_READ2BYTES( p_chk->strf.vids.p_bih->biPlanes );
            AVI_READ2BYTES( p_chk->strf.vids.p_bih->biBitCount );
            AVI_READFOURCC( p_chk->strf.vids.p_bih->biCompression );
            AVI_READ4BYTES( p_chk->strf.vids.p_bih->biSizeImage );
            AVI_READ4BYTES( p_chk->strf.vids.p_bih->biXPelsPerMeter );
            AVI_READ4BYTES( p_chk->strf.vids.p_bih->biYPelsPerMeter );
            AVI_READ4BYTES( p_chk->strf.vids.p_bih->biClrUsed );
            AVI_READ4BYTES( p_chk->strf.vids.p_bih->biClrImportant );
            if( p_chk->strf.vids.p_bih->biSize > p_chk->common.i_chunk_size )
            {
                p_chk->strf.vids.p_bih->biSize = p_chk->common.i_chunk_size;
            }
            if ( p_chk->common.i_chunk_size > sizeof(VLC_BITMAPINFOHEADER) )
            {
                uint64_t i_extrasize = p_chk->common.i_chunk_size - sizeof(VLC_BITMAPINFOHEADER);

                /* There's a color palette appended, set up VLC_BITMAPINFO */
                memcpy( &p_chk->strf.vids.p_bih[1],
                        p_buff + 8 + sizeof(VLC_BITMAPINFOHEADER), /* 8=fourrc+size */
                        i_extrasize );

                if ( !p_chk->strf.vids.p_bih->biClrUsed )
                    p_chk->strf.vids.p_bih->biClrUsed = (1 << p_chk->strf.vids.p_bih->biBitCount);

                if( i_extrasize / sizeof(uint32_t) > UINT32_MAX )
                    p_chk->strf.vids.p_bih->biClrUsed = UINT32_MAX;
                else
                {
                    p_chk->strf.vids.p_bih->biClrUsed =
                            __MIN( i_extrasize / sizeof(uint32_t),
                                   p_chk->strf.vids.p_bih->biClrUsed );
                }

                /* stay within VLC's limits */
                p_chk->strf.vids.p_bih->biClrUsed =
                    __MIN( VIDEO_PALETTE_COLORS_MAX, p_chk->strf.vids.p_bih->biClrUsed );
            }
            else p_chk->strf.vids.p_bih->biClrUsed = 0;
#ifdef AVI_DEBUG
            msg_Dbg( (vlc_object_t*)s,
                     "strf: video:%4.4s %"PRIu32"x%"PRIu32" planes:%d %dbpp",
                     (char*)&p_chk->strf.vids.p_bih->biCompression,
                     (uint32_t)p_chk->strf.vids.p_bih->biWidth,
                     (uint32_t)p_chk->strf.vids.p_bih->biHeight,
                     p_chk->strf.vids.p_bih->biPlanes,
                     p_chk->strf.vids.p_bih->biBitCount );
#endif
            break;
        case AVIFOURCC_iavs:
        case AVIFOURCC_ivas:
            p_chk->strf.common.i_cat = UNKNOWN_ES;
            break;
        case( AVIFOURCC_txts ):
            p_chk->strf.common.i_cat = SPU_ES;
            break;
        default:
            msg_Warn( (vlc_object_t*)s, "unknown stream type: %4.4s",
                    (char*)&p_strh->strh.i_type );
            p_chk->strf.common.i_cat = UNKNOWN_ES;
            break;
    }
    AVI_READCHUNK_EXIT( VLC_SUCCESS );
}