예제 #1
0
파일: faad.c 프로젝트: Kafay/vlc
/*****************************************************************************
 * DoReordering: do some channel re-ordering (the ac3 channel order is
 *   different from the aac one).
 *****************************************************************************/
static void DoReordering( uint32_t *p_out, uint32_t *p_in, int i_samples,
                          int i_nb_channels, uint32_t *pi_chan_positions )
{
    int pi_chan_table[MAX_CHANNEL_POSITIONS];
    int i, j, k;

    /* Find the channels mapping */
    for( i = 0, j = 0; i < MAX_CHANNEL_POSITIONS; i++ )
    {
        for( k = 0; k < i_nb_channels; k++ )
        {
            if( pi_channels_ordered[i] == pi_chan_positions[k] )
            {
                pi_chan_table[k] = j++;
                break;
            }
        }
    }

    /* Do the actual reordering */
    if( vlc_CPU() & CPU_CAPABILITY_FPU )
        for( i = 0; i < i_samples; i++ )
            for( j = 0; j < i_nb_channels; j++ )
                p_out[i * i_nb_channels + pi_chan_table[j]] =
                    p_in[i * i_nb_channels + j];
    else
        for( i = 0; i < i_samples; i++ )
            for( j = 0; j < i_nb_channels; j++ )
                ((uint16_t *)p_out)[i * i_nb_channels + pi_chan_table[j]] =
                    ((uint16_t *)p_in)[i * i_nb_channels + j];
}
예제 #2
0
static int Open(vlc_object_t *object)
{
    filter_t *filter = (filter_t *)object;
    const vlc_fourcc_t fourcc = filter->fmt_in.video.i_chroma;

    const vlc_chroma_description_t *chroma = vlc_fourcc_GetChromaDescription(fourcc);
    if (!chroma || chroma->plane_count < 3 || chroma->pixel_size != 1) {
        msg_Err(filter, "Unsupported chroma (%4.4s)", (char*)&fourcc);
        return VLC_EGENERIC;
    }

    filter_sys_t *sys = malloc(sizeof(*sys));
    if (!sys)
        return VLC_ENOMEM;

    vlc_mutex_init(&sys->lock);
    sys->chroma   = chroma;
    sys->strength = var_CreateGetFloatCommand(filter,   CFG_PREFIX "strength");
    sys->radius   = var_CreateGetIntegerCommand(filter, CFG_PREFIX "radius");
    var_AddCallback(filter, CFG_PREFIX "strength", Callback, NULL);
    var_AddCallback(filter, CFG_PREFIX "radius",   Callback, NULL);
    sys->cfg.buf = NULL;

    struct vf_priv_s *cfg = &sys->cfg;
    cfg->thresh      = 0.0;
    cfg->radius      = 0;
    cfg->buf         = NULL;
    cfg->filter_line = filter_line_c;
    cfg->blur_line   = blur_line_c;

#if HAVE_SSE2 && HAVE_6REGS
    if (vlc_CPU() & CPU_CAPABILITY_SSE2)
        cfg->blur_line = blur_line_sse2;
#endif
#if HAVE_MMX2
    if (vlc_CPU() & CPU_CAPABILITY_MMXEXT)
        cfg->filter_line = filter_line_mmx2;
#endif
#if HAVE_SSSE3
    if (vlc_CPU() & CPU_CAPABILITY_SSSE3)
        cfg->filter_line = filter_line_ssse3;
#endif

    filter->p_sys           = sys;
    filter->pf_video_filter = Filter;
    return VLC_SUCCESS;
}
예제 #3
0
파일: i422_yuy2.c 프로젝트: CSRedRat/vlc
/*****************************************************************************
 * Activate: allocate a chroma function
 *****************************************************************************
 * This function allocates and initializes a chroma function
 *****************************************************************************/
static int Activate( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t *)p_this;

#if CPU_CAPABILITY
    if( !(vlc_CPU() & CPU_CAPABILITY) )
        return VLC_EGENERIC;
#endif
    if( p_filter->fmt_in.video.i_width & 1
     || p_filter->fmt_in.video.i_height & 1 )
    {
        return -1;
    }

    switch( p_filter->fmt_in.video.i_chroma )
    {
        case VLC_CODEC_I422:
            switch( p_filter->fmt_out.video.i_chroma )
            {
                case VLC_CODEC_YUYV:
                    p_filter->pf_video_filter = I422_YUY2_Filter;
                    break;

                case VLC_CODEC_YVYU:
                    p_filter->pf_video_filter = I422_YVYU_Filter;
                    break;

                case VLC_CODEC_UYVY:
                    p_filter->pf_video_filter = I422_UYVY_Filter;
                    break;

                case VLC_FOURCC('I','U','Y','V'):
                    p_filter->pf_video_filter = I422_IUYV_Filter;
                    break;

                case VLC_CODEC_CYUV:
                    p_filter->pf_video_filter = I422_cyuv_Filter;
                    break;

#if defined (MODULE_NAME_IS_i422_yuy2)
                case VLC_CODEC_Y211:
                    p_filter->pf_video_filter = I422_Y211_Filter;
                    break;
#endif

                default:
                    return -1;
            }
            break;

        default:
            return -1;
    }
    return 0;
}
예제 #4
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 |= AV_CPU_FLAG_MMX;
    }
    if( !(i_cpu & CPU_CAPABILITY_MMXEXT) )
    {
        p_context->dsp_mask |= AV_CPU_FLAG_MMX2;
    }
    if( !(i_cpu & CPU_CAPABILITY_3DNOW) )
    {
        p_context->dsp_mask |= AV_CPU_FLAG_3DNOW;
    }
    if( !(i_cpu & CPU_CAPABILITY_SSE) )
    {
        p_context->dsp_mask |= AV_CPU_FLAG_SSE;
    }
    if( !(i_cpu & CPU_CAPABILITY_SSE2) )
    {
        p_context->dsp_mask |= AV_CPU_FLAG_SSE2;
    }
#ifdef AV_CPU_FLAG_SSE3
    if( !(i_cpu & CPU_CAPABILITY_SSE3) )
        p_context->dsp_mask |= AV_CPU_FLAG_SSE3;
#endif
#ifdef AV_CPU_FLAG_SSSE3
    if( !(i_cpu & CPU_CAPABILITY_SSSE3) )
        p_context->dsp_mask |= AV_CPU_FLAG_SSSE3;
#endif
#ifdef AV_CPU_FLAG_SSE4
    if( !(i_cpu & CPU_CAPABILITY_SSE4_1) )
        p_context->dsp_mask |= AV_CPU_FLAG_SSE4;
#endif
#ifdef AV_CPU_FLAG_SSE42
    if( !(i_cpu & CPU_CAPABILITY_SSE4_2) )
        p_context->dsp_mask |= AV_CPU_FLAG_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;
}
예제 #5
0
파일: libmpeg2.c 프로젝트: Kafay/vlc
/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*)p_this;
    decoder_sys_t *p_sys;
    uint32_t i_accel = 0;

    if( p_dec->fmt_in.i_codec != VLC_CODEC_MPGV )
        return VLC_EGENERIC;

    /* Select onl recognized original format (standard mpeg video) */
    switch( p_dec->fmt_in.i_original_fourcc )
    {
    case VLC_FOURCC('m','p','g','1'):
    case VLC_FOURCC('m','p','g','2'):
    case VLC_FOURCC('m','p','g','v'):
    case VLC_FOURCC('P','I','M','1'):
    case VLC_FOURCC('h','d','v','2'):
        break;
    default:
        if( p_dec->fmt_in.i_original_fourcc )
            return VLC_EGENERIC;
        break;
    }

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

    /* Initialize the thread properties */
    p_sys->p_mpeg2dec = NULL;
    p_sys->p_synchro  = NULL;
    p_sys->p_info     = NULL;
    p_sys->i_current_pts  = 0;
    p_sys->i_previous_pts = 0;
    p_sys->i_current_dts  = 0;
    p_sys->i_previous_dts = 0;
    p_sys->b_garbage_pic = false;
    p_sys->b_slice_i  = false;
    p_sys->b_second_field = false;
    p_sys->b_skip     = false;
    p_sys->b_preroll = false;
    DpbInit( p_dec );

    p_sys->i_cc_pts = 0;
    p_sys->i_cc_dts = 0;
    p_sys->i_cc_flags = 0;
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
    p_dec->pf_get_cc = GetCc;
    cc_Init( &p_sys->cc );
#endif
    p_sys->p_gop_user_data = NULL;
    p_sys->i_gop_user_data = 0;

#if defined( __i386__ ) || defined( __x86_64__ )
    if( vlc_CPU() & CPU_CAPABILITY_MMX )
    {
        i_accel |= MPEG2_ACCEL_X86_MMX;
    }

    if( vlc_CPU() & CPU_CAPABILITY_3DNOW )
    {
        i_accel |= MPEG2_ACCEL_X86_3DNOW;
    }

    if( vlc_CPU() & CPU_CAPABILITY_MMXEXT )
    {
        i_accel |= MPEG2_ACCEL_X86_MMXEXT;
    }

#elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )
    if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC )
    {
        i_accel |= MPEG2_ACCEL_PPC_ALTIVEC;
    }

#else
    /* If we do not know this CPU, trust libmpeg2's feature detection */
    i_accel = MPEG2_ACCEL_DETECT;

#endif

    /* Set CPU acceleration features */
    mpeg2_accel( i_accel );

    /* Initialize decoder */
    p_sys->p_mpeg2dec = mpeg2_init();
    if( p_sys->p_mpeg2dec == NULL)
    {
        msg_Err( p_dec, "mpeg2_init() failed" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );

    p_dec->pf_decode_video = DecodeBlock;
    p_dec->fmt_out.i_cat = VIDEO_ES;
    p_dec->fmt_out.i_codec = 0;

    return VLC_SUCCESS;
}
예제 #6
0
파일: x264.c 프로젝트: shanewfx/vlc-arib
/*****************************************************************************
 * Open: probe the encoder
 *****************************************************************************/
static int  Open ( vlc_object_t *p_this )
{
    encoder_t     *p_enc = (encoder_t *)p_this;
    encoder_sys_t *p_sys;
    int i_val;
    char *psz_val;
    int i_qmin = 0, i_qmax = 0;
    x264_nal_t    *nal;
    int i, i_nal;

    if( p_enc->fmt_out.i_codec != VLC_CODEC_H264 &&
        !p_enc->b_force )
    {
        return VLC_EGENERIC;
    }
    /* X264_POINTVER or X264_VERSION are not available */
    msg_Dbg ( p_enc, "version x264 0.%d.X", X264_BUILD );

    config_ChainParse( p_enc, SOUT_CFG_PREFIX, ppsz_sout_options, p_enc->p_cfg );

    p_enc->fmt_out.i_cat = VIDEO_ES;
    p_enc->fmt_out.i_codec = VLC_CODEC_H264;
    p_enc->fmt_in.i_codec = VLC_CODEC_I420;

    p_enc->pf_encode_video = Encode;
    p_enc->pf_encode_audio = NULL;
    p_enc->p_sys = p_sys = malloc( sizeof( encoder_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;
    p_sys->i_interpolated_dts = 0;
    p_sys->psz_stat_name = NULL;
    p_sys->p_buffer = NULL;

    x264_param_default( &p_sys->param );
    p_sys->param.i_width  = p_enc->fmt_in.video.i_width;
    p_sys->param.i_height = p_enc->fmt_in.video.i_height;

    p_sys->param.rc.f_qcompress = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qcomp" );

    /* transcode-default bitrate is 0,
     * set more to ABR if user specifies bitrate */
    if( p_enc->fmt_out.i_bitrate > 0 )
    {
        p_sys->param.rc.i_bitrate = p_enc->fmt_out.i_bitrate / 1000;
        p_sys->param.rc.i_rc_method = X264_RC_ABR;
    }
    else /* Set default to CRF */
    {
        i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "crf" );
        if( i_val > 0 && i_val <= 51 )
        {
            p_sys->param.rc.f_rf_constant = i_val;
            p_sys->param.rc.i_rc_method = X264_RC_CRF;
        }
    }

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpstep" );
    if( i_val >= 0 && i_val <= 51 ) p_sys->param.rc.i_qp_step = i_val;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpmin" );
    if( i_val >= 0 && i_val <= 51 )
    {
        i_qmin = i_val;
        p_sys->param.rc.i_qp_min = i_qmin;
    }
    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpmax" );
    if( i_val >= 0 && i_val <= 51 )
    {
        i_qmax = i_val;
        p_sys->param.rc.i_qp_max = i_qmax;
    }

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qp" );
    if( i_val >= 0 && i_val <= 51 )
    {
        if( i_qmin > i_val ) i_qmin = i_val;
        if( i_qmax < i_val ) i_qmax = i_val;

        /* User defined QP-value, so change ratecontrol method */
        p_sys->param.rc.i_rc_method = X264_RC_CQP;
        p_sys->param.rc.i_qp_constant = i_val;
        p_sys->param.rc.i_qp_min = i_qmin;
        p_sys->param.rc.i_qp_max = i_qmax;
    }


    p_sys->param.rc.f_rate_tolerance = var_GetFloat( p_enc,
                            SOUT_CFG_PREFIX "ratetol" );
    p_sys->param.rc.f_vbv_buffer_init = var_GetFloat( p_enc,
                            SOUT_CFG_PREFIX "vbv-init" );
    p_sys->param.rc.i_vbv_buffer_size = var_GetInteger( p_enc,
                            SOUT_CFG_PREFIX "vbv-bufsize" );

    /* max bitrate = average bitrate -> CBR */
    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "vbv-maxrate" );

    if( !i_val && p_sys->param.rc.i_rc_method == X264_RC_ABR )
        p_sys->param.rc.i_vbv_max_bitrate = p_sys->param.rc.i_bitrate;
    else if ( i_val )
        p_sys->param.rc.i_vbv_max_bitrate = i_val;

    p_sys->param.b_cabac = var_GetBool( p_enc, SOUT_CFG_PREFIX "cabac" );

    /* disable deblocking when nf (no loop filter) is enabled */
    p_sys->param.b_deblocking_filter = !var_GetBool( p_enc, SOUT_CFG_PREFIX "nf" );

    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "deblock" );
    if( psz_val )
    {
        char *p = strchr( psz_val, ':' );
        p_sys->param.i_deblocking_filter_alphac0 = atoi( psz_val );
        p_sys->param.i_deblocking_filter_beta = p ?
                    atoi( p+1 ) : p_sys->param.i_deblocking_filter_alphac0;
        free( psz_val );
    }

    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "psy-rd" );
    if( psz_val )
    {
        char *p = strchr( psz_val, ':' );
        p_sys->param.analyse.f_psy_rd = us_atof( psz_val );
        p_sys->param.analyse.f_psy_trellis = p ? us_atof( p+1 ) : 0;
        free( psz_val );
    }

    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "level" );
    if( psz_val )
    {
        if( us_atof (psz_val) < 6 )
            p_sys->param.i_level_idc = (int) (10 * us_atof (psz_val)
                                              + .5);
        else
            p_sys->param.i_level_idc = atoi (psz_val);
        free( psz_val );
    }

    p_sys->param.b_interlaced = var_GetBool( p_enc, SOUT_CFG_PREFIX "interlaced" );
    p_sys->param.rc.f_ip_factor = var_GetFloat( p_enc, SOUT_CFG_PREFIX "ipratio" );
    p_sys->param.rc.f_pb_factor = var_GetFloat( p_enc, SOUT_CFG_PREFIX "pbratio" );
    p_sys->param.rc.f_complexity_blur = var_GetFloat( p_enc, SOUT_CFG_PREFIX "cplxblur" );
    p_sys->param.rc.f_qblur = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qblur" );
    p_sys->param.rc.i_aq_mode = var_GetInteger( p_enc, SOUT_CFG_PREFIX "aq-mode" );
    p_sys->param.rc.f_aq_strength = var_GetFloat( p_enc, SOUT_CFG_PREFIX "aq-strength" );

    if( var_GetBool( p_enc, SOUT_CFG_PREFIX "verbose" ) )
        p_sys->param.i_log_level = X264_LOG_DEBUG;

    if( var_GetBool( p_enc, SOUT_CFG_PREFIX "quiet" ) )
        p_sys->param.i_log_level = X264_LOG_NONE;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "sps-id" );
    if( i_val >= 0 ) p_sys->param.i_sps_id = i_val;

    if( var_GetBool( p_enc, SOUT_CFG_PREFIX "aud" ) )
        p_sys->param.b_aud = true;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "keyint" );
    if( i_val > 0 ) p_sys->param.i_keyint_max = i_val;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "min-keyint" );
    if( i_val > 0 ) p_sys->param.i_keyint_min = i_val;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "bframes" );
    if( i_val >= 0 && i_val <= 16 )
        p_sys->param.i_bframe = i_val;

#if X264_BUILD >= 78
    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "bpyramid" );
    p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NONE;
    if( !strcmp( psz_val, "none" ) )
    {
       p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NONE;
    } else if ( !strcmp( psz_val, "strict" ) )
    {
       p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_STRICT;
    } else if ( !strcmp( psz_val, "normal" ) )
    {
       p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NORMAL;
    }
    free( psz_val );
#else
    p_sys->param.b_bframe_pyramid = var_GetBool( p_enc, SOUT_CFG_PREFIX "bpyramid" );
 #endif

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "ref" );
    if( i_val > 0 && i_val <= 15 )
        p_sys->param.i_frame_reference = i_val;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "scenecut" );
    if( i_val >= -1 && i_val <= 100 )
        p_sys->param.i_scenecut_threshold = i_val;

    p_sys->param.b_deterministic = var_GetBool( p_enc,
                        SOUT_CFG_PREFIX "non-deterministic" );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "subme" );
    if( i_val >= 1 && i_val <= SUBME_MAX )
        p_sys->param.analyse.i_subpel_refine = i_val;

    //TODO: psz_val == NULL ?
    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "me" );
    if( !strcmp( psz_val, "dia" ) )
    {
        p_sys->param.analyse.i_me_method = X264_ME_DIA;
    }
    else if( !strcmp( psz_val, "hex" ) )
    {
        p_sys->param.analyse.i_me_method = X264_ME_HEX;
    }
    else if( !strcmp( psz_val, "umh" ) )
    {
        p_sys->param.analyse.i_me_method = X264_ME_UMH;
    }
    else if( !strcmp( psz_val, "esa" ) )
    {
        p_sys->param.analyse.i_me_method = X264_ME_ESA;
    }
    else if( !strcmp( psz_val, "tesa" ) )
    {
        p_sys->param.analyse.i_me_method = X264_ME_TESA;
    }
    free( psz_val );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "merange" );
    if( i_val >= 0 && i_val <= 64 )
        p_sys->param.analyse.i_me_range = i_val;

    p_sys->param.analyse.i_mv_range = var_GetInteger( p_enc,
                                    SOUT_CFG_PREFIX "mvrange" );
    p_sys->param.analyse.i_mv_range_thread = var_GetInteger( p_enc,
                                    SOUT_CFG_PREFIX "mvrange-thread" );

    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "direct" );
    if( !strcmp( psz_val, "none" ) )
    {
        p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_NONE;
    }
    else if( !strcmp( psz_val, "spatial" ) )
    {
        p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;
    }
    else if( !strcmp( psz_val, "temporal" ) )
    {
        p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_TEMPORAL;
    }
    else if( !strcmp( psz_val, "auto" ) )
    {
        p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
    }
    free( psz_val );

    p_sys->param.analyse.b_psnr = var_GetBool( p_enc, SOUT_CFG_PREFIX "psnr" );
    p_sys->param.analyse.b_ssim = var_GetBool( p_enc, SOUT_CFG_PREFIX "ssim" );
    p_sys->param.analyse.b_weighted_bipred = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "weightb" );
    p_sys->param.i_bframe_adaptive = var_GetInteger( p_enc,
                                    SOUT_CFG_PREFIX "b-adapt" );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "b-bias" );
    if( i_val >= -100 && i_val <= 100 )
        p_sys->param.i_bframe_bias = i_val;

    p_sys->param.analyse.b_chroma_me = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "chroma-me" );
    p_sys->param.analyse.i_chroma_qp_offset = var_GetInteger( p_enc,
                                    SOUT_CFG_PREFIX "chroma-qp-offset" );
    p_sys->param.analyse.b_mixed_references = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "mixed-refs" );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "trellis" );
    if( i_val >= 0 && i_val <= 2 )
        p_sys->param.analyse.i_trellis = i_val;

    p_sys->param.analyse.b_fast_pskip = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "fast-pskip" );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "nr" );
    if( i_val >= 0 && i_val <= 1000 )
        p_sys->param.analyse.i_noise_reduction = i_val;

    p_sys->param.analyse.b_dct_decimate = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "dct-decimate" );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "deadzone-inter" );
    if( i_val >= 0 && i_val <= 32 )
        p_sys->param.analyse.i_luma_deadzone[0] = i_val;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "deadzone-intra" );
    if( i_val >= 0 && i_val <= 32 )
        p_sys->param.analyse.i_luma_deadzone[1] = i_val;

    if( !var_GetBool( p_enc, SOUT_CFG_PREFIX "asm" ) )
        p_sys->param.cpu = 0;

#ifndef X264_ANALYSE_BSUB16x16
#   define X264_ANALYSE_BSUB16x16 0
#endif
    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "partitions" );
    if( !strcmp( psz_val, "none" ) )
    {
        p_sys->param.analyse.inter = 0;
    }
    else if( !strcmp( psz_val, "fast" ) )
    {
        p_sys->param.analyse.inter = X264_ANALYSE_I4x4;
    }
    else if( !strcmp( psz_val, "normal" ) )
    {
        p_sys->param.analyse.inter =
            X264_ANALYSE_I4x4 |
            X264_ANALYSE_PSUB16x16;
#ifdef X264_ANALYSE_I8x8
        p_sys->param.analyse.inter |= X264_ANALYSE_I8x8;
#endif
    }
    else if( !strcmp( psz_val, "slow" ) )
    {
        p_sys->param.analyse.inter =
            X264_ANALYSE_I4x4 |
            X264_ANALYSE_PSUB16x16 |
            X264_ANALYSE_BSUB16x16;
#ifdef X264_ANALYSE_I8x8
        p_sys->param.analyse.inter |= X264_ANALYSE_I8x8;
#endif
    }
    else if( !strcmp( psz_val, "all" ) )
    {
        p_sys->param.analyse.inter = ~0;
    }
    free( psz_val );

    p_sys->param.analyse.b_transform_8x8 = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "8x8dct" );

    if( p_enc->fmt_in.video.i_aspect > 0 )
    {
        int64_t i_num, i_den;
        unsigned int i_dst_num, i_dst_den;

        i_num = p_enc->fmt_in.video.i_aspect *
            (int64_t)p_enc->fmt_in.video.i_height;
        i_den = VOUT_ASPECT_FACTOR * p_enc->fmt_in.video.i_width;
        vlc_ureduce( &i_dst_num, &i_dst_den, i_num, i_den, 0 );

        p_sys->param.vui.i_sar_width = i_dst_num;
        p_sys->param.vui.i_sar_height = i_dst_den;
    }

    if( p_enc->fmt_in.video.i_frame_rate_base > 0 )
    {
        p_sys->param.i_fps_num = p_enc->fmt_in.video.i_frame_rate;
        p_sys->param.i_fps_den = p_enc->fmt_in.video.i_frame_rate_base;
    }

    /* x264 vbv-bufsize = 0 (default). if not provided set period
       in seconds for local maximum bitrate (cache/bufsize) based
       on average bitrate when use has told bitrate.
       vbv-buffer size is set to bitrate * secods between keyframes */
    if( !p_sys->param.rc.i_vbv_buffer_size &&
         p_sys->param.rc.i_rc_method == X264_RC_ABR &&
         p_sys->param.i_fps_num )
    {
        p_sys->param.rc.i_vbv_buffer_size = p_sys->param.rc.i_bitrate *
            p_sys->param.i_fps_den;
        p_sys->param.rc.i_vbv_buffer_size *= p_sys->param.i_keyint_max;
        p_sys->param.rc.i_vbv_buffer_size /= p_sys->param.i_fps_num;
    }

    /* Check if user has given some profile (baseline,main,high) to limit
     * settings, and apply those*/
    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "profile" );
    if( psz_val )
    {
        if( !strcasecmp( psz_val, "baseline" ) )
        {
            msg_Dbg( p_enc, "Limiting to baseline profile");
            p_sys->param.analyse.b_transform_8x8 = 0;
            p_sys->param.b_cabac = 0;
            p_sys->param.i_bframe = 0;
        }
        else if (!strcasecmp( psz_val, "main" ) )
        {
            msg_Dbg( p_enc, "Limiting to main-profile");
            p_sys->param.analyse.b_transform_8x8 = 0;
        }
        /* high profile don't restrict stuff*/
    }
    free( psz_val );


    unsigned i_cpu = vlc_CPU();
    if( !(i_cpu & CPU_CAPABILITY_MMX) )
    {
        p_sys->param.cpu &= ~X264_CPU_MMX;
    }
    if( !(i_cpu & CPU_CAPABILITY_MMXEXT) )
    {
        p_sys->param.cpu &= ~X264_CPU_MMXEXT;
    }
    if( !(i_cpu & CPU_CAPABILITY_SSE) )
    {
        p_sys->param.cpu &= ~X264_CPU_SSE;
    }
    if( !(i_cpu & CPU_CAPABILITY_SSE2) )
    {
        p_sys->param.cpu &= ~X264_CPU_SSE2;
    }

    /* BUILD 29 adds support for multi-threaded encoding while BUILD 49 (r543)
       also adds support for threads = 0 for automatically selecting an optimal
       value (cores * 1.5) based on detected CPUs. Default behavior for x264 is
       threads = 1, however VLC usage differs and uses threads = 0 (auto) by
       default unless ofcourse transcode threads is explicitly specified.. */
    p_sys->param.i_threads = p_enc->i_threads;

    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "stats" );
    if( psz_val )
    {
        p_sys->param.rc.psz_stat_in  =
        p_sys->param.rc.psz_stat_out =
        p_sys->psz_stat_name         = psz_val;
    }

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "pass" );
    if( i_val > 0 && i_val <= 3 )
    {
        p_sys->param.rc.b_stat_write = i_val & 1;
        p_sys->param.rc.b_stat_read = i_val & 2;
    }

    /* We need to initialize pthreadw32 before we open the encoder,
       but only once for the whole application. Since pthreadw32
       doesn't keep a refcount, do it ourselves. */
#ifdef PTW32_STATIC_LIB
    vlc_value_t lock, count;

    var_Create( p_enc->p_libvlc, "pthread_win32_mutex", VLC_VAR_MUTEX );
    var_Get( p_enc->p_libvlc, "pthread_win32_mutex", &lock );
    vlc_mutex_lock( lock.p_address );

    var_Create( p_enc->p_libvlc, "pthread_win32_count", VLC_VAR_INTEGER );
    var_Get( p_enc->p_libvlc, "pthread_win32_count", &count );

    if( count.i_int == 0 )
    {
        msg_Dbg( p_enc, "initializing pthread-win32" );
        if( !pthread_win32_process_attach_np() || !pthread_win32_thread_attach_np() )
        {
            msg_Warn( p_enc, "pthread Win32 Initialization failed" );
            vlc_mutex_unlock( lock.p_address );
            return VLC_EGENERIC;
        }
    }

    count.i_int++;
    var_Set( p_enc->p_libvlc, "pthread_win32_count", count );
    vlc_mutex_unlock( lock.p_address );

#endif

    /* Set lookahead value to lower than default,
     * as rtp-output without mux doesn't handle
     * difference that well yet*/
    p_sys->param.rc.i_lookahead=5;

    /* Open the encoder */
    p_sys->h = x264_encoder_open( &p_sys->param );

    if( p_sys->h == NULL )
    {
        msg_Err( p_enc, "cannot open x264 encoder" );
        Close( VLC_OBJECT(p_enc) );
        return VLC_EGENERIC;
    }

    /* alloc mem */
    p_sys->i_buffer = 4 * p_enc->fmt_in.video.i_width *
        p_enc->fmt_in.video.i_height + 1000;
    p_sys->p_buffer = malloc( p_sys->i_buffer );
    if( !p_sys->p_buffer )
    {
        Close( VLC_OBJECT(p_enc) );
        return VLC_ENOMEM;
    }

    /* get the globals headers */
    p_enc->fmt_out.i_extra = 0;
    p_enc->fmt_out.p_extra = NULL;

    p_enc->fmt_out.i_extra = x264_encoder_headers( p_sys->h, &nal, &i_nal );
    p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
    if( !p_enc->fmt_out.p_extra )
    {
        Close( VLC_OBJECT(p_enc) );
        return VLC_ENOMEM;
    }
    void *p_tmp = p_enc->fmt_out.p_extra;
    for( i = 0; i < i_nal; i++ )
    {
        memcpy( p_tmp, nal[i].p_payload, nal[i].i_payload );
        p_tmp += nal[i].i_payload;
    }

    return VLC_SUCCESS;
}
예제 #7
0
파일: switcher.c 프로젝트: Kafay/vlc
/*****************************************************************************
 * VideoCommand: Create/Delete a video encoder
 *****************************************************************************/
static mtime_t VideoCommand( sout_stream_t *p_stream, sout_stream_id_t *id )
{
    sout_stream_sys_t *p_sys = p_stream->p_sys;

    if ( p_sys->i_cmd == 0 && !(id->p_queued->i_flags & BLOCK_FLAG_TYPE_I) )
    {
        mtime_t i_dts = id->p_queued->i_dts;
        block_t *p_block = id->p_queued->p_next;

        while ( p_block != NULL )
        {
            if ( p_block->i_flags & BLOCK_FLAG_TYPE_I )
                return i_dts;
            i_dts = p_block->i_dts;
            p_block = p_block->p_next;
        }

        return 0;
    }

    p_sys->i_old_cmd = p_sys->i_cmd;

    if ( id->ff_enc )
    {
        vlc_avcodec_lock();
        avcodec_close( id->ff_enc_c );
        vlc_avcodec_unlock();
        av_free( id->ff_enc_c );
        av_free( id->p_frame );
        free( id->p_buffer_out );
        id->ff_enc = NULL;
    }

    if ( p_sys->i_cmd > 0 )
    {
        /* Create a new encoder. */
        int i_ff_codec = CODEC_ID_MPEG2VIDEO;
        int i_aspect_num, i_aspect_den;

        if( i_ff_codec == 0 )
        {
            msg_Err( p_stream, "cannot find encoder" );
            return 0;
        }

        id->ff_enc = avcodec_find_encoder( i_ff_codec );
        if( !id->ff_enc )
        {
            msg_Err( p_stream, "cannot find encoder (avcodec)" );
            return 0;
        }

        id->ff_enc_c = avcodec_alloc_context();

        /* Set CPU capabilities */
        unsigned i_cpu = vlc_CPU();
        id->ff_enc_c->dsp_mask = 0;
        if( !(i_cpu & CPU_CAPABILITY_MMX) )
        {
            id->ff_enc_c->dsp_mask |= FF_MM_MMX;
        }
        if( !(i_cpu & CPU_CAPABILITY_MMXEXT) )
        {
            id->ff_enc_c->dsp_mask |= FF_MM_MMXEXT;
        }
        if( !(i_cpu & CPU_CAPABILITY_3DNOW) )
        {
            id->ff_enc_c->dsp_mask |= FF_MM_3DNOW;
        }
        if( !(i_cpu & CPU_CAPABILITY_SSE) )
        {
            id->ff_enc_c->dsp_mask |= FF_MM_SSE;
            id->ff_enc_c->dsp_mask |= FF_MM_SSE2;
        }

        id->ff_enc_c->width = p_sys->p_pictures[p_sys->i_cmd-1].format.i_width;
        id->ff_enc_c->height = p_sys->p_pictures[p_sys->i_cmd-1].format.i_height;
        av_reduce( &i_aspect_num, &i_aspect_den,
                   p_sys->i_aspect,
                   VOUT_ASPECT_FACTOR, 1 << 30 /* something big */ );
        av_reduce( &id->ff_enc_c->sample_aspect_ratio.num,
                   &id->ff_enc_c->sample_aspect_ratio.den,
                   i_aspect_num * (int64_t)id->ff_enc_c->height,
                   i_aspect_den * (int64_t)id->ff_enc_c->width, 1 << 30 );

#if LIBAVCODEC_BUILD >= 4754
        id->ff_enc_c->time_base.num = 1;
        id->ff_enc_c->time_base.den = 25; /* FIXME */
#else
        id->ff_enc_c->frame_rate    = 25; /* FIXME */
        id->ff_enc_c->frame_rate_base = 1;
#endif

        id->ff_enc_c->gop_size = 200;
        id->ff_enc_c->max_b_frames = 0;

        id->ff_enc_c->flags |= CODEC_FLAG_QSCALE
                            | CODEC_FLAG_INPUT_PRESERVED
                            | CODEC_FLAG_LOW_DELAY;

        id->ff_enc_c->mb_decision = FF_MB_DECISION_SIMPLE;
        id->ff_enc_c->pix_fmt = PIX_FMT_YUV420P;

        avcodec_lock();
        if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
        {
            avcodec_unlock();
            msg_Err( p_stream, "cannot open encoder" );
            return 0;
        }
        avcodec_unlock();

        id->p_buffer_out = malloc( id->ff_enc_c->width * id->ff_enc_c->height * 3 );
        id->p_frame = avcodec_alloc_frame();
        id->p_frame->linesize[0] = p_sys->p_pictures[p_sys->i_cmd-1].p[0].i_pitch;
        id->p_frame->linesize[1] = p_sys->p_pictures[p_sys->i_cmd-1].p[1].i_pitch;
        id->p_frame->linesize[2] = p_sys->p_pictures[p_sys->i_cmd-1].p[2].i_pitch;
        id->p_frame->data[0] = p_sys->p_pictures[p_sys->i_cmd-1].p[0].p_pixels;
        id->p_frame->data[1] = p_sys->p_pictures[p_sys->i_cmd-1].p[1].p_pixels;
        id->p_frame->data[2] = p_sys->p_pictures[p_sys->i_cmd-1].p[2].p_pixels;

        id->i_nb_pred = p_sys->i_gop;
    }

    return 0;
}
예제 #8
0
파일: switcher.c 프로젝트: Kafay/vlc
/*****************************************************************************
 * Add: Add an input elementary stream
 *****************************************************************************/
static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
{
    sout_stream_sys_t   *p_sys = p_stream->p_sys;
    sout_stream_id_t    *id;

    id = calloc( 1, sizeof( sout_stream_id_t ) );
    if( !id )
        return NULL;

    if( p_fmt->i_cat == VIDEO_ES &&
        ( p_fmt->i_codec == VLC_CODEC_MPGV ||
          p_fmt->i_codec == VLC_FOURCC('f', 'a', 'k', 'e') ) )
    {
        id->b_switcher_video = true;
        p_fmt->i_codec = VLC_CODEC_MPGV;
        msg_Dbg( p_stream, "creating video switcher for fcc=`%4.4s' cmd:%d",
                 (char*)&p_fmt->i_codec, p_sys->i_cmd );
    }
    else if ( p_fmt->i_cat == AUDIO_ES &&
              p_fmt->i_codec == VLC_CODEC_MPGA &&
              p_sys->b_audio )
    {
        int i_ff_codec = CODEC_ID_MP2;
        int i;

        id->b_switcher_audio = true;
        msg_Dbg( p_stream, "creating audio switcher for fcc=`%4.4s' cmd:%d",
                 (char*)&p_fmt->i_codec, p_sys->i_cmd );

        /* Allocate the encoder right now. */
        if( i_ff_codec == 0 )
        {
            msg_Err( p_stream, "cannot find encoder" );
            free( id );
            return NULL;
        }

        id->ff_enc = avcodec_find_encoder( i_ff_codec );
        if( !id->ff_enc )
        {
            msg_Err( p_stream, "cannot find encoder (avcodec)" );
            free( id );
            return NULL;
        }

        id->ff_enc_c = avcodec_alloc_context();

        /* Set CPU capabilities */
        unsigned i_cpu = vlc_CPU();
        id->ff_enc_c->dsp_mask = 0;
        if( !(i_cpu & CPU_CAPABILITY_MMX) )
        {
            id->ff_enc_c->dsp_mask |= FF_MM_MMX;
        }
        if( !(i_cpu & CPU_CAPABILITY_MMXEXT) )
        {
            id->ff_enc_c->dsp_mask |= FF_MM_MMXEXT;
        }
        if( !(i_cpu & CPU_CAPABILITY_3DNOW) )
        {
            id->ff_enc_c->dsp_mask |= FF_MM_3DNOW;
        }
        if( !(i_cpu & CPU_CAPABILITY_SSE) )
        {
            id->ff_enc_c->dsp_mask |= FF_MM_SSE;
            id->ff_enc_c->dsp_mask |= FF_MM_SSE2;
        }

        id->ff_enc_c->sample_rate = p_fmt->audio.i_rate;
        id->ff_enc_c->channels    = p_fmt->audio.i_channels;
        id->ff_enc_c->bit_rate    = p_fmt->i_bitrate;

        vlc_avcodec_lock();
        if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
        {
            avcodec_unlock();
            msg_Err( p_stream, "cannot open encoder" );
            av_free( id->ff_enc_c );
            free( id );
            return NULL;
        }
        avcodec_unlock();

        id->p_buffer_out = malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE * 2 );
        id->p_samples = calloc( id->ff_enc_c->frame_size * p_fmt->audio.i_channels,
                                sizeof(int16_t) );
        if( !id->p_buffer_out || !id->p_samples )
            goto error;

        for( i = 0; i < MAX_AUDIO; i++ )
        {
            if( p_sys->pp_audio_ids[i] == NULL )
            {
                p_sys->pp_audio_ids[i] = id;
                break;
            }
        }
        if( i == MAX_AUDIO )
        {
            msg_Err( p_stream, "too many audio streams!" );
            goto error;
        }
    }
    else
    {
        msg_Dbg( p_stream, "do not know what to do when switching (fcc=`%4.4s')",
                 (char*)&p_fmt->i_codec );
    }

    /* src format */
    memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );

    /* open output stream */
    id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );

    if( id->id != NULL )
        return id;

error:
    vlc_avcodec_lock();
    avcodec_close( id->ff_enc_c );
    vlc_avcodec_unlock();
    free( id->p_samples );
    free( id->p_buffer_out );
    av_free( id->ff_enc_c );
    free( id );
    return NULL;
}
예제 #9
0
/*****************************************************************************
 * OpenPostproc: probe and open the postproc
 *****************************************************************************/
static int OpenPostproc( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys;
    vlc_value_t val, val_orig, text;
    unsigned i_cpu = vlc_CPU();
    int i_flags = 0;

    if( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma ||
        p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height ||
        p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width )
    {
        msg_Err( p_filter, "Filter input and output formats must be identical" );
        return VLC_EGENERIC;
    }

    /* Set CPU capabilities */
    if( i_cpu & CPU_CAPABILITY_MMX )
        i_flags |= PP_CPU_CAPS_MMX;
    if( i_cpu & CPU_CAPABILITY_MMXEXT )
        i_flags |= PP_CPU_CAPS_MMX2;
    if( i_cpu & CPU_CAPABILITY_3DNOW )
        i_flags |= PP_CPU_CAPS_3DNOW;
    if( i_cpu & CPU_CAPABILITY_ALTIVEC )
        i_flags |= PP_CPU_CAPS_ALTIVEC;

    switch( p_filter->fmt_in.video.i_chroma )
    {
        case VLC_CODEC_I444:
        case VLC_CODEC_J444:
        /* case VLC_CODEC_YUVA:
           FIXME: Should work but alpha plane needs to be copied manually and
                  I'm kind of feeling too lazy to write the code to do that ATM
                  (i_pitch vs i_visible_pitch...). */
            i_flags |= PP_FORMAT_444;
            break;
        case VLC_CODEC_I422:
        case VLC_CODEC_J422:
            i_flags |= PP_FORMAT_422;
            break;
        case VLC_CODEC_I411:
            i_flags |= PP_FORMAT_411;
            break;
        case VLC_CODEC_I420:
        case VLC_CODEC_J420:
        case VLC_CODEC_YV12:
            i_flags |= PP_FORMAT_420;
            break;
        default:
            msg_Err( p_filter, "Unsupported input chroma (%4.4s)",
                      (char*)&p_filter->fmt_in.video.i_chroma );
            return VLC_EGENERIC;
    }

    p_sys = malloc( sizeof( filter_sys_t ) );
    if( !p_sys ) return VLC_ENOMEM;
    p_filter->p_sys = p_sys;

    p_sys->pp_context = pp_get_context( p_filter->fmt_in.video.i_width,
                                        p_filter->fmt_in.video.i_height,
                                        i_flags );
    if( !p_sys->pp_context )
    {
        msg_Err( p_filter, "Error while creating post processing context." );
        free( p_sys );
        return VLC_EGENERIC;
    }

    config_ChainParse( p_filter, FILTER_PREFIX, ppsz_filter_options,
                       p_filter->p_cfg );

    var_Create( p_filter, FILTER_PREFIX "q", VLC_VAR_INTEGER |
                VLC_VAR_HASCHOICE | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND );

    text.psz_string = _("Post processing");
    var_Change( p_filter, FILTER_PREFIX "q", VLC_VAR_SETTEXT, &text, NULL );

    var_Get( p_filter, FILTER_PREFIX "q", &val_orig );
    var_Change( p_filter, FILTER_PREFIX "q", VLC_VAR_DELCHOICE, &val_orig, NULL );

    val.psz_string = var_GetNonEmptyString( p_filter, FILTER_PREFIX "name" );
    if( val_orig.i_int )
    {
        p_sys->pp_mode = pp_get_mode_by_name_and_quality( val.psz_string ?
                                                          val.psz_string :
                                                          "default",
                                                          val_orig.i_int );

        if( !p_sys->pp_mode )
        {
            msg_Err( p_filter, "Error while creating post processing mode." );
            free( val.psz_string );
            pp_free_context( p_sys->pp_context );
            free( p_sys );
            return VLC_EGENERIC;
        }
    }
    else
    {
        p_sys->pp_mode = NULL;
    }
    free( val.psz_string );

    for( val.i_int = 0; val.i_int <= PP_QUALITY_MAX; val.i_int++ )
    {
        switch( val.i_int )
        {
            case 0:
                text.psz_string = _("Disable");
                break;
            case 1:
                text.psz_string = _("Lowest");
                break;
            case PP_QUALITY_MAX:
                text.psz_string = _("Highest");
                break;
            default:
                text.psz_string = NULL;
                break;
        }
        var_Change( p_filter, FILTER_PREFIX "q", VLC_VAR_ADDCHOICE,
                    &val, text.psz_string?&text:NULL );
    }

    vlc_mutex_init( &p_sys->lock );

    /* Add the callback at the end to prevent crashes */
    var_AddCallback( p_filter, FILTER_PREFIX "q", PPQCallback, NULL );
    var_AddCallback( p_filter, FILTER_PREFIX "name", PPNameCallback, NULL );

    p_filter->pf_video_filter = PostprocPict;
    p_sys->b_had_matrix = true;

    return VLC_SUCCESS;
}
예제 #10
0
int Open( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t*)p_this;
    filter_sys_t *p_sys;

    const vlc_fourcc_t fourcc = p_filter->fmt_in.video.i_chroma;
    const vlc_chroma_description_t *chroma = vlc_fourcc_GetChromaDescription( fourcc );
    if( !vlc_fourcc_IsYUV( fourcc ) ||
        !chroma || chroma->plane_count != 3 || chroma->pixel_size > 2 )
    {
        msg_Err( p_filter, "Unsupported chroma (%4.4s)", (char*)&fourcc );
        return VLC_EGENERIC;
    }

    /* */
    p_sys = p_filter->p_sys = malloc( sizeof( *p_sys ) );
    if( !p_sys )
        return VLC_ENOMEM;

    p_sys->chroma = chroma;
    p_sys->i_mode = DEINTERLACE_BLEND;
    p_sys->b_double_rate = false;
    p_sys->b_half_height = true;
    p_sys->b_use_frame_history = false;
    for( int i = 0; i < METADATA_SIZE; i++ )
    {
        p_sys->meta.pi_date[i] = VLC_TS_INVALID;
        p_sys->meta.pi_nb_fields[i] = 2;
        p_sys->meta.pb_top_field_first[i] = true;
    }
    p_sys->i_frame_offset = 0; /* start with default value (first-ever frame
                                  cannot have offset) */
    for( int i = 0; i < HISTORY_SIZE; i++ )
        p_sys->pp_history[i] = NULL;

    IVTCClearState( p_filter );

#if defined(CAN_COMPILE_C_ALTIVEC)
    if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_ALTIVEC) )
    {
        p_sys->pf_merge = MergeAltivec;
        p_sys->pf_end_merge = NULL;
    }
    else
#endif
#if defined(CAN_COMPILE_SSE)
    if( (vlc_CPU() & CPU_CAPABILITY_SSE2) )
    {
        p_sys->pf_merge = chroma->pixel_size == 1 ? Merge8BitSSE2 : Merge16BitSSE2;
        p_sys->pf_end_merge = EndMMX;
    }
    else
#endif
#if defined(CAN_COMPILE_MMXEXT)
    if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_MMXEXT) )
    {
        p_sys->pf_merge = MergeMMXEXT;
        p_sys->pf_end_merge = EndMMX;
    }
    else
#endif
#if defined(CAN_COMPILE_3DNOW)
    if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_3DNOW) )
    {
        p_sys->pf_merge = Merge3DNow;
        p_sys->pf_end_merge = End3DNow;
    }
    else
#endif
#if defined __ARM_NEON__ // FIXME: runtime detect support
    if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_NEON) )
    {
        p_sys->pf_merge = MergeNEON;
        p_sys->pf_end_merge = NULL;
    }
    else
#endif
    {
        p_sys->pf_merge = chroma->pixel_size == 1 ? Merge8BitGeneric : Merge16BitGeneric;
        p_sys->pf_end_merge = NULL;
    }

    /* */
    config_ChainParse( p_filter, FILTER_CFG_PREFIX, ppsz_filter_options,
                       p_filter->p_cfg );

    char *psz_mode = var_GetNonEmptyString( p_filter, FILTER_CFG_PREFIX "mode" );
    SetFilterMethod( p_filter, psz_mode );
    free( psz_mode );

    if( p_sys->i_mode == DEINTERLACE_PHOSPHOR )
    {
        int i_c420 = var_GetInteger( p_filter,
                                     FILTER_CFG_PREFIX "phosphor-chroma" );
        if( i_c420 != PC_LATEST  &&  i_c420 != PC_ALTLINE  &&
            i_c420 != PC_BLEND   && i_c420 != PC_UPCONVERT )
        {
            msg_Dbg( p_filter, "Phosphor 4:2:0 input chroma mode not set"\
                               "or out of range (valid: 1, 2, 3 or 4), "\
                               "using default" );
            i_c420 = PC_ALTLINE;
        }
        msg_Dbg( p_filter, "using Phosphor 4:2:0 input chroma mode %d",
                           i_c420 );
        /* This maps directly to the phosphor_chroma_t enum. */
        p_sys->phosphor.i_chroma_for_420 = i_c420;

        int i_dimmer = var_GetInteger( p_filter,
                                       FILTER_CFG_PREFIX "phosphor-dimmer" );
        if( i_dimmer < 1  ||  i_dimmer > 4 )
        {
            msg_Dbg( p_filter, "Phosphor dimmer strength not set "\
                               "or out of range (valid: 1, 2, 3 or 4), "\
                               "using default" );
            i_dimmer = 2; /* low */
        }
        msg_Dbg( p_filter, "using Phosphor dimmer strength %d", i_dimmer );
        /* The internal value ranges from 0 to 3. */
        p_sys->phosphor.i_dimmer_strength = i_dimmer - 1;
    }
    else
    {
        p_sys->phosphor.i_chroma_for_420 = PC_ALTLINE;
        p_sys->phosphor.i_dimmer_strength = 1;
    }

    /* */
    video_format_t fmt;
    GetOutputFormat( p_filter, &fmt, &p_filter->fmt_in.video );
    if( !p_filter->b_allow_fmt_out_change &&
        ( fmt.i_chroma != p_filter->fmt_in.video.i_chroma ||
          fmt.i_height != p_filter->fmt_in.video.i_height ) )
    {
        Close( VLC_OBJECT(p_filter) );
        return VLC_EGENERIC;
    }
    p_filter->fmt_out.video = fmt;
    p_filter->fmt_out.i_codec = fmt.i_chroma;
    p_filter->pf_video_filter = Deinterlace;
    p_filter->pf_video_flush  = Flush;
    p_filter->pf_video_mouse  = Mouse;

    msg_Dbg( p_filter, "deinterlacing" );

    return VLC_SUCCESS;
}
예제 #11
0
파일: faad.c 프로젝트: Kafay/vlc
/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*)p_this;
    decoder_sys_t *p_sys = p_dec->p_sys;
    faacDecConfiguration *cfg;

    if( p_dec->fmt_in.i_codec != VLC_CODEC_MP4A )
    {
        return VLC_EGENERIC;
    }

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

    /* Open a faad context */
    if( ( p_sys->hfaad = faacDecOpen() ) == NULL )
    {
        msg_Err( p_dec, "cannot initialize faad" );
        return VLC_EGENERIC;
    }

    /* Misc init */
    aout_DateSet( &p_sys->date, 0 );
    p_dec->fmt_out.i_cat = AUDIO_ES;

    if (vlc_CPU() & CPU_CAPABILITY_FPU)
        p_dec->fmt_out.i_codec = VLC_CODEC_FL32;
    else
        p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
    p_dec->pf_decode_audio = DecodeBlock;

    p_dec->fmt_out.audio.i_physical_channels =
        p_dec->fmt_out.audio.i_original_channels = 0;

    if( 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 )
        {
            msg_Err( p_dec, "Failed to initialize faad using extra data" );
            return VLC_EGENERIC;
        }

        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];
        aout_DateInit( &p_sys->date, i_rate );
    }
    else
    {
        /* Will be initalised from first frame */
        p_dec->fmt_out.audio.i_rate = 0;
        p_dec->fmt_out.audio.i_channels = 0;
    }

    /* Set the faad config */
    cfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
    if (vlc_CPU() & CPU_CAPABILITY_FPU)
        cfg->outputFormat = FAAD_FMT_FLOAT;
    else
        cfg->outputFormat = FAAD_FMT_16BIT;
    faacDecSetConfiguration( p_sys->hfaad, cfg );

    /* buffer */
    p_sys->i_buffer = p_sys->i_buffer_size = 0;
    p_sys->p_buffer = NULL;

    /* Faad2 can't deal with truncated data (eg. from MPEG TS) */
    p_dec->b_need_packetized = true;

    p_sys->b_sbr = p_sys->b_ps = false;
    return VLC_SUCCESS;
}
예제 #12
0
파일: alsa.c 프로젝트: FLYKingdom/vlc
/*****************************************************************************
 * Open: create a handle and open an alsa device
 *****************************************************************************
 * This function opens an alsa device, through the alsa API.
 *
 * Note: the only heap-allocated string is psz_device. All the other pointers
 * are references to psz_device or to stack-allocated data.
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    aout_instance_t * p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys;
    vlc_value_t val;

    char psz_default_iec_device[128]; /* Buffer used to store the default
                                         S/PDIF device */
    char * psz_device, * psz_iec_device; /* device names for PCM and S/PDIF
                                            output */

    int i_vlc_pcm_format; /* Audio format for VLC's data */
    int i_snd_pcm_format; /* Audio format for ALSA's data */

    snd_pcm_uframes_t i_buffer_size = 0;
    snd_pcm_uframes_t i_period_size = 0;
    int i_channels = 0;

    snd_pcm_hw_params_t *p_hw;
    snd_pcm_sw_params_t *p_sw;

    int i_snd_rc = -1;
    unsigned int i_old_rate;
    bool b_retry = true;

    /* Allocate structures */
    p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) );
    if( p_sys == NULL )
        return VLC_ENOMEM;
    p_sys->b_playing = false;
    p_sys->start_date = 0;
    vlc_cond_init( &p_sys->wait );
    vlc_mutex_init( &p_sys->lock );

    /* Get device name */
    if( (psz_device = config_GetPsz( p_aout, "alsa-audio-device" )) == NULL )
    {
        msg_Err( p_aout, "no audio device given (maybe \"default\" ?)" );
        dialog_Fatal( p_aout, _("No Audio Device"), "%s",
                        _("No audio device name was given. You might want to " \
                          "enter \"default\".") );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* Choose the IEC device for S/PDIF output:
       if the device is overriden by the user then it will be the one
       otherwise we compute the default device based on the output format. */
    if( AOUT_FMT_NON_LINEAR( &p_aout->output.output )
        && !strcmp( psz_device, DEFAULT_ALSA_DEVICE ) )
    {
        snprintf( psz_default_iec_device, sizeof(psz_default_iec_device),
                  "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x",
                  IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO,
                  IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
                  0,
                  ( p_aout->output.output.i_rate == 48000 ?
                    IEC958_AES3_CON_FS_48000 :
                    ( p_aout->output.output.i_rate == 44100 ?
                      IEC958_AES3_CON_FS_44100 : IEC958_AES3_CON_FS_32000 ) ) );
        psz_iec_device = psz_default_iec_device;
    }
    else if( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
    {
        psz_iec_device = psz_device;
    }
    else
    {
        psz_iec_device = NULL;
    }

    /* Choose the linear PCM format (read the comment above about FPU
       and float32) */
    if( vlc_CPU() & CPU_CAPABILITY_FPU )
    {
        i_vlc_pcm_format = VLC_CODEC_FL32;
        i_snd_pcm_format = SND_PCM_FORMAT_FLOAT;
    }
    else
    {
        i_vlc_pcm_format = VLC_CODEC_S16N;
        i_snd_pcm_format = SND_PCM_FORMAT_S16;
    }

    /* If the variable doesn't exist then it's the first time we're called
       and we have to probe the available audio formats and channels */
    if ( var_Type( p_aout, "audio-device" ) == 0 )
    {
        Probe( p_aout, psz_device, psz_iec_device, &i_snd_pcm_format );
    }

    if ( var_Get( p_aout, "audio-device", &val ) < 0 )
    {
        free( p_sys );
        free( psz_device );
        return VLC_EGENERIC;
    }

    p_aout->output.output.i_format = i_vlc_pcm_format;
    if ( val.i_int == AOUT_VAR_5_1 )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
               | AOUT_CHAN_LFE;
        free( psz_device );
        psz_device = strdup( "surround51" );
    }
    else if ( val.i_int == AOUT_VAR_2F2R )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
        free( psz_device );
        psz_device = strdup( "surround40" );
    }
    else if ( val.i_int == AOUT_VAR_STEREO )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    }
    else if ( val.i_int == AOUT_VAR_MONO )
    {
        p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
    }
    else if( val.i_int != AOUT_VAR_SPDIF )
    {
        /* This should not happen ! */
        msg_Err( p_aout, "internal: can't find audio-device (%i)", val.i_int );
        free( p_sys );
        free( psz_device );
        return VLC_EGENERIC;
    }

#ifdef ALSA_DEBUG
    snd_output_stdio_attach( &p_sys->p_snd_stderr, stderr, 0 );
#endif

    /* Open the device */
    if ( val.i_int == AOUT_VAR_SPDIF )
    {
        if ( ( i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_iec_device,
                            SND_PCM_STREAM_PLAYBACK, 0 ) ) < 0 )
        {
            msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
                             psz_iec_device, snd_strerror( i_snd_rc ) );
            dialog_Fatal( p_aout, _("Audio output failed"),
                            _("VLC could not open the ALSA device \"%s\" (%s)."),
                            psz_iec_device, snd_strerror( i_snd_rc ) );
            free( p_sys );
            free( psz_device );
            return VLC_EGENERIC;
        }
        i_buffer_size = ALSA_SPDIF_BUFFER_SIZE;
        i_snd_pcm_format = SND_PCM_FORMAT_S16;
        i_channels = 2;

        i_vlc_pcm_format = VLC_CODEC_SPDIFL;
        p_aout->output.i_nb_samples = i_period_size = ALSA_SPDIF_PERIOD_SIZE;
        p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
        p_aout->output.output.i_frame_length = A52_FRAME_NB;

        aout_VolumeNoneInit( p_aout );
    }
    else
    {
        int i;

        msg_Dbg( p_aout, "opening ALSA device `%s'", psz_device );

        /* Since it seems snd_pcm_close hasn't really released the device at
          the time it returns, probe if the device is available in loop for 1s.
          We cannot use blocking mode since the we would wait indefinitely when
          switching from a dmx device to surround51. */

        for( i = 10; i >= 0; i-- )
        {
            if ( ( i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_device,
                   SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) ) == -EBUSY )
            {
                if( i ) msleep( 100000 /* 100ms */ );
                else
                {
                    msg_Err( p_aout, "audio device: %s is already in use",
                              psz_device );
                    dialog_Fatal( p_aout, _("Audio output failed"),
                                    _("The audio device \"%s\" is already in use."),
                                    psz_device );
                }
                continue;
            }
            break;
        }
        if( i_snd_rc < 0 )
        {
            msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
                             psz_device, snd_strerror( i_snd_rc ) );
            dialog_Fatal( p_aout, _("Audio output failed"),
                            _("VLC could not open the ALSA device \"%s\" (%s)."),
                            psz_device, snd_strerror( i_snd_rc ) );
            free( p_sys );
            free( psz_device );
            return VLC_EGENERIC;
        }

        /* We want blocking mode */
        snd_pcm_nonblock( p_sys->p_snd_pcm, 0 );

        i_buffer_size = ALSA_DEFAULT_BUFFER_SIZE;
        i_channels = aout_FormatNbChannels( &p_aout->output.output );

        p_aout->output.i_nb_samples = i_period_size = ALSA_DEFAULT_PERIOD_SIZE;

        aout_VolumeSoftInit( p_aout );
    }

    /* Free psz_device so that all the remaining data is stack-allocated */
    free( psz_device );

    p_aout->output.pf_play = Play;

    snd_pcm_hw_params_alloca(&p_hw);
    snd_pcm_sw_params_alloca(&p_sw);

    /* Due to some bugs in alsa with some drivers, we need to retry in s16l
       if snd_pcm_hw_params fails in fl32 */
    while ( b_retry )
    {
        b_retry = false;

        /* Get Initial hardware parameters */
        if ( ( i_snd_rc = snd_pcm_hw_params_any( p_sys->p_snd_pcm, p_hw ) ) < 0 )
        {
            msg_Err( p_aout, "unable to retrieve initial hardware parameters (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set format. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm, p_hw,
                                                    i_snd_pcm_format ) ) < 0 )
        {
            if( i_snd_pcm_format != SND_PCM_FORMAT_S16 )
            {
                i_snd_pcm_format = SND_PCM_FORMAT_S16;
                i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm,
                                                     p_hw, i_snd_pcm_format );
            }
            if ( i_snd_rc < 0 )
            {
                msg_Err( p_aout, "unable to set stream sample size and "
                     "word order (%s)", snd_strerror( i_snd_rc ) );
                goto error;
            }
        }
        if( i_vlc_pcm_format != VLC_CODEC_SPDIFL )
        switch( i_snd_pcm_format )
        {
        case SND_PCM_FORMAT_FLOAT:
            i_vlc_pcm_format = VLC_CODEC_FL32;
            break;
        case SND_PCM_FORMAT_S16:
            i_vlc_pcm_format = VLC_CODEC_S16N;
            break;
        }
        p_aout->output.output.i_format = i_vlc_pcm_format;

        if ( ( i_snd_rc = snd_pcm_hw_params_set_access( p_sys->p_snd_pcm, p_hw,
                                    SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set interleaved stream format (%s)",
                             snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set channels. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_channels( p_sys->p_snd_pcm, p_hw,
                                                      i_channels ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set number of output channels (%s)",
                             snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set rate. */
        i_old_rate = p_aout->output.output.i_rate;
        i_snd_rc = snd_pcm_hw_params_set_rate_near( p_sys->p_snd_pcm, p_hw,
                                                &p_aout->output.output.i_rate,
                                                NULL );
        if( i_snd_rc < 0 || p_aout->output.output.i_rate != i_old_rate )
        {
            msg_Warn( p_aout, "The rate %d Hz is not supported by your " \
                "hardware. Using %d Hz instead.\n", i_old_rate, \
                p_aout->output.output.i_rate );
        }

        /* Set period size. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm,
                                    p_hw, &i_period_size, NULL ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set period size (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }
        p_aout->output.i_nb_samples = i_period_size;

/* Set buffer size. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm,
                                    p_hw, &i_buffer_size ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set buffer size (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Commit hardware parameters. */
        if ( ( i_snd_rc = snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw ) ) < 0 )
        {
            if ( b_retry == false &&
                                i_snd_pcm_format == SND_PCM_FORMAT_FLOAT)
            {
                b_retry = true;
                i_snd_pcm_format = SND_PCM_FORMAT_S16;
                p_aout->output.output.i_format = VLC_CODEC_S16N;
                msg_Warn( p_aout, "unable to commit hardware configuration "
                                  "with fl32 samples. Retrying with s16l (%s)",                                     snd_strerror( i_snd_rc ) );
            }
            else
            {
                msg_Err( p_aout, "unable to commit hardware configuration (%s)",
                         snd_strerror( i_snd_rc ) );
                goto error;
            }
        }
    }

    if( ( i_snd_rc = snd_pcm_hw_params_get_period_time( p_hw,
                                    &p_sys->i_period_time, NULL ) ) < 0 )
    {
        msg_Err( p_aout, "unable to get period time (%s)",
                         snd_strerror( i_snd_rc ) );
        goto error;
    }

    /* Get Initial software parameters */
    snd_pcm_sw_params_current( p_sys->p_snd_pcm, p_sw );

    i_snd_rc = snd_pcm_sw_params_set_sleep_min( p_sys->p_snd_pcm, p_sw, 0 );

    i_snd_rc = snd_pcm_sw_params_set_avail_min( p_sys->p_snd_pcm, p_sw,
                                                p_aout->output.i_nb_samples );
    /* start playing when one period has been written */
    i_snd_rc = snd_pcm_sw_params_set_start_threshold( p_sys->p_snd_pcm, p_sw,
                                                      ALSA_DEFAULT_PERIOD_SIZE);
    if( i_snd_rc < 0 )
    {
        msg_Err( p_aout, "unable to set start threshold (%s)",
                          snd_strerror( i_snd_rc ) );
        goto error;
    }

    /* Commit software parameters. */
    if ( snd_pcm_sw_params( p_sys->p_snd_pcm, p_sw ) < 0 )
    {
        msg_Err( p_aout, "unable to set software configuration" );
        goto error;
    }

#ifdef ALSA_DEBUG
    snd_output_printf( p_sys->p_snd_stderr, "\nALSA hardware setup:\n\n" );
    snd_pcm_dump_hw_setup( p_sys->p_snd_pcm, p_sys->p_snd_stderr );
    snd_output_printf( p_sys->p_snd_stderr, "\nALSA software setup:\n\n" );
    snd_pcm_dump_sw_setup( p_sys->p_snd_pcm, p_sys->p_snd_stderr );
    snd_output_printf( p_sys->p_snd_stderr, "\n" );
#endif

    /* Create ALSA thread and wait for its readiness. */
    if( vlc_thread_create( p_aout, "aout", ALSAThread,
                           VLC_THREAD_PRIORITY_OUTPUT ) )
    {
        msg_Err( p_aout, "cannot create ALSA thread (%m)" );
        goto error;
    }

    return 0;

error:
    snd_pcm_close( p_sys->p_snd_pcm );
#ifdef ALSA_DEBUG
    snd_output_close( p_sys->p_snd_stderr );
#endif
    free( p_sys );
    return VLC_EGENERIC;
}
예제 #13
0
int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src,
                 int i_order, int i_field )
{
    VLC_UNUSED(p_src);

    filter_sys_t *p_sys = p_filter->p_sys;

    /* */
    assert( i_order >= 0 && i_order <= 2 ); /* 2 = soft field repeat */
    assert( i_field == 0 || i_field == 1 );

    /* As the pitches must match, use ONLY pictures coming from picture_New()! */
    picture_t *p_prev = p_sys->pp_history[0];
    picture_t *p_cur  = p_sys->pp_history[1];
    picture_t *p_next = p_sys->pp_history[2];

    /* Account for soft field repeat.

       The "parity" parameter affects the algorithm like this (from yadif.h):
       uint8_t *prev2= parity ? prev : cur ;
       uint8_t *next2= parity ? cur  : next;

       The original parity expression that was used here is:
       (i_field ^ (i_order == i_field)) & 1

       Truth table:
       i_field = 0, i_order = 0  => 1
       i_field = 1, i_order = 1  => 0
       i_field = 1, i_order = 0  => 1
       i_field = 0, i_order = 1  => 0

       => equivalent with e.g.  (1 - i_order)  or  (i_order + 1) % 2

       Thus, in a normal two-field frame,
             parity 1 = first field  (i_order == 0)
             parity 0 = second field (i_order == 1)

       Now, with three fields, where the third is a copy of the first,
             i_order = 0  =>  parity 1 (as usual)
             i_order = 1  =>  due to the repeat, prev = cur, but also next = cur.
                              Because in such a case there is no motion
                              (otherwise field repeat makes no sense),
                              we don't actually need to invoke Yadif's filter().
                              Thus, set "parity" to 2, and use this to bypass
                              the filter.
             i_order = 2  =>  parity 0 (as usual)
    */
    int yadif_parity;
    if( p_cur  &&  p_cur->i_nb_fields > 2 )
        yadif_parity = (i_order + 1) % 3; /* 1, *2*, 0; where 2 is a special
                                             value meaning "bypass filter". */
    else
        yadif_parity = (i_order + 1) % 2; /* 1, 0 */

    /* Filter if we have all the pictures we need */
    if( p_prev && p_cur && p_next )
    {
        /* */
        void (*filter)(uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next,
                       int w, int prefs, int mrefs, int parity, int mode);

        filter = yadif_filter_line_c;
#if defined(HAVE_YADIF_MMX)
        if( vlc_CPU() & CPU_CAPABILITY_MMX )
            filter = yadif_filter_line_mmx;
#endif
#if defined(HAVE_YADIF_SSE2)
        if( vlc_CPU() & CPU_CAPABILITY_SSE2 )
            filter = yadif_filter_line_sse2;
#endif
#if defined(HAVE_YADIF_SSSE3)
        if( vlc_CPU() & CPU_CAPABILITY_SSSE3 )
            filter = yadif_filter_line_ssse3;
#endif

        for( int n = 0; n < p_dst->i_planes; n++ )
        {
            const plane_t *prevp = &p_prev->p[n];
            const plane_t *curp  = &p_cur->p[n];
            const plane_t *nextp = &p_next->p[n];
            plane_t *dstp        = &p_dst->p[n];

            for( int y = 1; y < dstp->i_visible_lines - 1; y++ )
            {
                if( (y % 2) == i_field  ||  yadif_parity == 2 )
                {
                    vlc_memcpy( &dstp->p_pixels[y * dstp->i_pitch],
                                &curp->p_pixels[y * curp->i_pitch], dstp->i_visible_pitch );
                }
                else
                {
                    int mode;
                    /* Spatial checks only when enough data */
                    mode = (y >= 2 && y < dstp->i_visible_lines - 2) ? 0 : 2;

                    assert( prevp->i_pitch == curp->i_pitch && curp->i_pitch == nextp->i_pitch );
                    filter( &dstp->p_pixels[y * dstp->i_pitch],
                            &prevp->p_pixels[y * prevp->i_pitch],
                            &curp->p_pixels[y * curp->i_pitch],
                            &nextp->p_pixels[y * nextp->i_pitch],
                            dstp->i_visible_pitch,
                            y < dstp->i_visible_lines - 2  ? curp->i_pitch : -curp->i_pitch,
                            y  - 1  ?  -curp->i_pitch : curp->i_pitch,
                            yadif_parity,
                            mode );
                }

                /* We duplicate the first and last lines */
                if( y == 1 )
                    vlc_memcpy(&dstp->p_pixels[(y-1) * dstp->i_pitch],
                               &dstp->p_pixels[ y    * dstp->i_pitch],
                               dstp->i_pitch);
                else if( y == dstp->i_visible_lines - 2 )
                    vlc_memcpy(&dstp->p_pixels[(y+1) * dstp->i_pitch],
                               &dstp->p_pixels[ y    * dstp->i_pitch],
                               dstp->i_pitch);
            }
        }

        p_sys->i_frame_offset = 1; /* p_cur will be rendered at next frame, too */

        return VLC_SUCCESS;
    }
    else if( !p_prev && !p_cur && p_next )
    {
        /* NOTE: For the first frame, we use the default frame offset
                 as set by Open() or SetFilterMethod(). It is always 0. */

        /* FIXME not good as it does not use i_order/i_field */
        RenderX( p_dst, p_next );
        return VLC_SUCCESS;
    }
    else
    {
        p_sys->i_frame_offset = 1; /* p_cur will be rendered at next frame */

        return VLC_EGENERIC;
    }
}
예제 #14
0
파일: chroma_yuv.c 프로젝트: CSRedRat/vlc
static int Open (vlc_object_t *obj)
{
    filter_t *filter = (filter_t *)obj;

    if (!(vlc_CPU() & CPU_CAPABILITY_NEON))
        return VLC_EGENERIC;
    if ((filter->fmt_in.video.i_width != filter->fmt_out.video.i_width)
     || (filter->fmt_in.video.i_height != filter->fmt_out.video.i_height))
        return VLC_EGENERIC;

    switch (filter->fmt_in.video.i_chroma)
    {
        /* Planar to packed */
        case VLC_CODEC_I420:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_YUYV:
                    filter->pf_video_filter = I420_YUYV_Filter;
                    break;
                case VLC_CODEC_UYVY:
                    filter->pf_video_filter = I420_UYVY_Filter;
                    break;
                case VLC_CODEC_YVYU:
                    filter->pf_video_filter = I420_YVYU_Filter;
                    break;
                case VLC_CODEC_VYUY:
                    filter->pf_video_filter = I420_VYUY_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }
            break;

        case VLC_CODEC_YV12:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_YUYV:
                    filter->pf_video_filter = I420_YVYU_Filter;
                    break;
                case VLC_CODEC_UYVY:
                    filter->pf_video_filter = I420_VYUY_Filter;
                    break;
                case VLC_CODEC_YVYU:
                    filter->pf_video_filter = I420_YUYV_Filter;
                    break;
                case VLC_CODEC_VYUY:
                    filter->pf_video_filter = I420_UYVY_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }
            break;

        case VLC_CODEC_I422:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_YUYV:
                    filter->pf_video_filter = I422_YUYV_Filter;
                    break;
                case VLC_CODEC_UYVY:
                    filter->pf_video_filter = I422_UYVY_Filter;
                    break;
                case VLC_CODEC_YVYU:
                    filter->pf_video_filter = I422_YVYU_Filter;
                    break;
                case VLC_CODEC_VYUY:
                    filter->pf_video_filter = I422_VYUY_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }
            break;

        /* Packed to planar */
        case VLC_CODEC_YUYV:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_I422:
                    filter->pf_video_filter = YUYV_I422_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }

        case VLC_CODEC_UYVY:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_I422:
                    filter->pf_video_filter = UYVY_I422_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }

        case VLC_CODEC_YVYU:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_I422:
                    filter->pf_video_filter = YVYU_I422_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }


        case VLC_CODEC_VYUY:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_I422:
                    filter->pf_video_filter = VYUY_I422_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }

        default:
            return VLC_EGENERIC;
    }
    return VLC_SUCCESS;
}
예제 #15
0
파일: output.c 프로젝트: mahaserver/MHSVLC
/*****************************************************************************
 * aout_OutputNew : allocate a new output and rework the filter pipeline
 *****************************************************************************
 * This function is entered with the mixer lock.
 *****************************************************************************/
int aout_OutputNew( aout_instance_t * p_aout,
                    audio_sample_format_t * p_format )
{
    /* Retrieve user defaults. */
    int i_rate = config_GetInt( p_aout, "aout-rate" );
    vlc_value_t val, text;
    /* kludge to avoid a fpu error when rate is 0... */
    if( i_rate == 0 ) i_rate = -1;

    memcpy( &p_aout->output.output, p_format, sizeof(audio_sample_format_t) );
    if ( i_rate != -1 )
        p_aout->output.output.i_rate = i_rate;
    aout_FormatPrepare( &p_aout->output.output );

    aout_lock_output_fifo( p_aout );

    /* Find the best output plug-in. */
    p_aout->output.p_module = module_Need( p_aout, "audio output", "$aout", 0);

    if ( p_aout->output.p_module == NULL )
    {
        msg_Err( p_aout, "no suitable audio output module" );
        aout_unlock_output_fifo( p_aout );
        return -1;
    }

    if ( var_Type( p_aout, "audio-channels" ) ==
             (VLC_VAR_INTEGER | VLC_VAR_HASCHOICE) )
    {
        /* The user may have selected a different channels configuration. */
        var_Get( p_aout, "audio-channels", &val );

        if ( val.i_int == AOUT_VAR_CHAN_RSTEREO )
        {
            p_aout->output.output.i_original_channels |=
                                        AOUT_CHAN_REVERSESTEREO;
        }
        else if ( val.i_int == AOUT_VAR_CHAN_STEREO )
        {
            p_aout->output.output.i_original_channels =
                AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
        }
        else if ( val.i_int == AOUT_VAR_CHAN_LEFT )
        {
            p_aout->output.output.i_original_channels = AOUT_CHAN_LEFT;
        }
        else if ( val.i_int == AOUT_VAR_CHAN_RIGHT )
        {
            p_aout->output.output.i_original_channels = AOUT_CHAN_RIGHT;
        }
        else if ( val.i_int == AOUT_VAR_CHAN_DOLBYS )
        {
            p_aout->output.output.i_original_channels
                = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_DOLBYSTEREO;
        }
    }
    else if ( p_aout->output.output.i_physical_channels == AOUT_CHAN_CENTER
              && (p_aout->output.output.i_original_channels
                   & AOUT_CHAN_PHYSMASK) == (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) )
    {
        /* Mono - create the audio-channels variable. */
        var_Create( p_aout, "audio-channels",
                    VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
        text.psz_string = _("Audio Channels");
        var_Change( p_aout, "audio-channels", VLC_VAR_SETTEXT, &text, NULL );

        val.i_int = AOUT_VAR_CHAN_STEREO; text.psz_string = _("Stereo");
        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val, &text );
        val.i_int = AOUT_VAR_CHAN_LEFT; text.psz_string = _("Left");
        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val, &text );
        val.i_int = AOUT_VAR_CHAN_RIGHT; text.psz_string = _("Right");
        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val, &text );
        if ( p_aout->output.output.i_original_channels & AOUT_CHAN_DUALMONO )
        {
            /* Go directly to the left channel. */
            p_aout->output.output.i_original_channels = AOUT_CHAN_LEFT;
            val.i_int = AOUT_VAR_CHAN_LEFT;
            var_Set( p_aout, "audio-channels", val );
        }
        var_AddCallback( p_aout, "audio-channels", aout_ChannelsRestart,
                         NULL );
    }
    else if ( p_aout->output.output.i_physical_channels ==
               (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)
                && (p_aout->output.output.i_original_channels &
                     (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) )
    {
        /* Stereo - create the audio-channels variable. */
        var_Create( p_aout, "audio-channels",
                    VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
        text.psz_string = _("Audio Channels");
        var_Change( p_aout, "audio-channels", VLC_VAR_SETTEXT, &text, NULL );

        if ( p_aout->output.output.i_original_channels & AOUT_CHAN_DOLBYSTEREO )
        {
            val.i_int = AOUT_VAR_CHAN_DOLBYS;
            text.psz_string = _("Dolby Surround");
        }
        else
        {
            val.i_int = AOUT_VAR_CHAN_STEREO;
            text.psz_string = _("Stereo");
        }
        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val, &text );
        val.i_int = AOUT_VAR_CHAN_LEFT; text.psz_string = _("Left");
        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val, &text );
        val.i_int = AOUT_VAR_CHAN_RIGHT; text.psz_string = _("Right");
        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val, &text );
        val.i_int = AOUT_VAR_CHAN_RSTEREO; text.psz_string=_("Reverse stereo");
        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val, &text );
        if ( p_aout->output.output.i_original_channels & AOUT_CHAN_DUALMONO )
        {
            /* Go directly to the left channel. */
            p_aout->output.output.i_original_channels = AOUT_CHAN_LEFT;
            val.i_int = AOUT_VAR_CHAN_LEFT;
            var_Set( p_aout, "audio-channels", val );
        }
        var_AddCallback( p_aout, "audio-channels", aout_ChannelsRestart,
                         NULL );
    }
    val.b_bool = true;
    var_Set( p_aout, "intf-change", val );

    aout_FormatPrepare( &p_aout->output.output );

    /* Prepare FIFO. */
    aout_FifoInit( p_aout, &p_aout->output.fifo,
                   p_aout->output.output.i_rate );

    aout_unlock_output_fifo( p_aout );

    aout_FormatPrint( p_aout, "output", &p_aout->output.output );

    /* Calculate the resulting mixer output format. */
    memcpy( &p_aout->mixer.mixer, &p_aout->output.output,
            sizeof(audio_sample_format_t) );
    if ( !AOUT_FMT_NON_LINEAR(&p_aout->output.output) )
    {
        /* Non-S/PDIF mixer only deals with float32 or fixed32. */
        p_aout->mixer.mixer.i_format
                     = (vlc_CPU() & CPU_CAPABILITY_FPU) ?
                        VLC_FOURCC('f','l','3','2') :
                        VLC_FOURCC('f','i','3','2');
        aout_FormatPrepare( &p_aout->mixer.mixer );
    }
    else
    {
        p_aout->mixer.mixer.i_format = p_format->i_format;
    }

    aout_FormatPrint( p_aout, "mixer", &p_aout->mixer.mixer );

    /* Create filters. */
    p_aout->output.i_nb_filters = 0;
    if ( aout_FiltersCreatePipeline( p_aout, p_aout->output.pp_filters,
                                     &p_aout->output.i_nb_filters,
                                     &p_aout->mixer.mixer,
                                     &p_aout->output.output ) < 0 )
    {
        msg_Err( p_aout, "couldn't create audio output pipeline" );
        module_Unneed( p_aout, p_aout->output.p_module );
        return -1;
    }

    /* Prepare hints for the buffer allocator. */
    p_aout->mixer.output_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
    p_aout->mixer.output_alloc.i_bytes_per_sec
                        = p_aout->mixer.mixer.i_bytes_per_frame
                           * p_aout->mixer.mixer.i_rate
                           / p_aout->mixer.mixer.i_frame_length;

    aout_FiltersHintBuffers( p_aout, p_aout->output.pp_filters,
                             p_aout->output.i_nb_filters,
                             &p_aout->mixer.output_alloc );

    p_aout->output.b_error = 0;
    return 0;
}