コード例 #1
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;
}
コード例 #2
0
/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*) p_this;
    unsigned i_codec_id;
    int i_cat, 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() */
    vlc_init_avcodec(p_this);

    /* *** ask ffmpeg for a decoder *** */
    char *psz_decoder = var_CreateGetString( p_this, "avcodec-codec" );
    if( psz_decoder && *psz_decoder )
    {
        p_codec = avcodec_find_decoder_by_name( psz_decoder );
        if( !p_codec )
            msg_Err( p_this, "Decoder `%s' not found", psz_decoder );
        else if( p_codec->id != i_codec_id )
        {
            msg_Err( p_this, "Decoder `%s' can't handle %4.4s",
                    psz_decoder, (char*)&p_dec->fmt_in.i_codec );
            p_codec = NULL;
        }
    }
    free( psz_decoder );
    if( !p_codec )
        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_context3(p_codec);
    if( !p_context )
        return VLC_ENOMEM;
    p_context->debug = var_InheritInteger( p_dec, "avcodec-debug" );
    p_context->opaque = (void *)p_this;

    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;
}
コード例 #3
0
ファイル: mux.c プロジェクト: tguillem/vlc
/*****************************************************************************
 * AddStream
 *****************************************************************************/
static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
    sout_mux_sys_t *p_sys = p_mux->p_sys;
    const es_format_t *fmt = p_input->p_fmt;
    unsigned i_codec_id;

    msg_Dbg( p_mux, "adding input" );

    if( !GetFfmpegCodec( fmt->i_cat, fmt->i_codec, &i_codec_id, NULL )
     || i_codec_id == AV_CODEC_ID_NONE )
    {
        msg_Dbg( p_mux, "couldn't find codec for fourcc '%4.4s'",
                 (char *)&fmt->i_codec );
        return VLC_EGENERIC;
    }

    unsigned opus_size[XIPH_MAX_HEADER_COUNT];
    void     *opus_packet[XIPH_MAX_HEADER_COUNT];
    if( fmt->i_codec == VLC_CODEC_OPUS )
    {
        unsigned count;
        /* Only transmits the first packet (OpusHead) */
        if( xiph_SplitHeaders(opus_size, opus_packet, &count, fmt->i_extra, fmt->p_extra ) ) {
            count = 0;
        }
        if (count != 2 || opus_size[0] < 19) {
            msg_Err(p_mux, "Invalid Opus header");
            return VLC_EGENERIC;
        }
    }

    if( fmt->i_cat != VIDEO_ES && fmt->i_cat != AUDIO_ES)
    {
        msg_Warn( p_mux, "Unhandled ES category" );
        return VLC_EGENERIC;
    }

    /* */
    p_input->p_sys = malloc( sizeof( int ) );
    if( unlikely(p_input->p_sys == NULL) )
        return VLC_ENOMEM;

    *((int *)p_input->p_sys) = p_sys->oc->nb_streams;

    /* */
    AVStream *stream = avformat_new_stream( p_sys->oc, NULL);
    if( !stream )
    {
        free( p_input->p_sys );
        return VLC_EGENERIC;
    }

#if (LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 5, 0))
    AVCodecParameters *codecpar = stream->codecpar;
#else
    AVCodecContext *codecpar = stream->codec;
#endif

    unsigned int i_bitrate = fmt->i_bitrate;
    unsigned int i_frame_rate = fmt->video.i_frame_rate;
    unsigned int i_frame_rate_base = fmt->video.i_frame_rate_base;
    switch( fmt->i_cat )
    {
    case AUDIO_ES:
        codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
        codecpar->channels = fmt->audio.i_channels;
        codecpar->sample_rate = fmt->audio.i_rate;
        stream->time_base = (AVRational){1, codecpar->sample_rate};
        if (fmt->i_bitrate == 0) {
            msg_Warn( p_mux, "Missing audio bitrate, assuming 64k" );
            i_bitrate = 64000;
        }
        break;

    case VIDEO_ES:
        if( !fmt->video.i_frame_rate || !fmt->video.i_frame_rate_base ) {
            msg_Warn( p_mux, "Missing frame rate, assuming 25fps" );
            i_frame_rate = 25;
            i_frame_rate_base = 1;
        } else
            msg_Dbg( p_mux, "Muxing framerate will be %d/%d = %.2f fps",
                    fmt->video.i_frame_rate,
                    fmt->video.i_frame_rate_base,
                    (double)fmt->video.i_frame_rate/(double)fmt->video.i_frame_rate_base );

        codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
        codecpar->width = fmt->video.i_visible_width;
        codecpar->height = fmt->video.i_visible_height;
        av_reduce( &codecpar->sample_aspect_ratio.num,
                   &codecpar->sample_aspect_ratio.den,
                   fmt->video.i_sar_num,
                   fmt->video.i_sar_den, 1 << 30 /* something big */ );
        msg_Dbg(p_mux, "Muxing aspect ratio will be %d/%d",
                fmt->video.i_sar_num, fmt->video.i_sar_den);
        stream->sample_aspect_ratio.den = codecpar->sample_aspect_ratio.den;
        stream->sample_aspect_ratio.num = codecpar->sample_aspect_ratio.num;
        stream->time_base.den = i_frame_rate;
        stream->time_base.num = i_frame_rate_base;
        if (fmt->i_bitrate == 0) {
            msg_Warn( p_mux, "Missing video bitrate, assuming 512k" );
            i_bitrate = 512000;
        } else
            msg_Dbg( p_mux, "Muxing video bitrate will be %d", fmt->i_bitrate );
        break;

    default:
        vlc_assert_unreachable();
    }

    codecpar->bit_rate = i_bitrate;
    codecpar->codec_tag = av_codec_get_tag( p_sys->oc->oformat->codec_tag, i_codec_id );
    if( !codecpar->codec_tag && i_codec_id == AV_CODEC_ID_MP2 )
    {
        i_codec_id = AV_CODEC_ID_MP3;
        codecpar->codec_tag = av_codec_get_tag( p_sys->oc->oformat->codec_tag, i_codec_id );
    }
    codecpar->codec_id = i_codec_id;

    if( fmt->i_extra )
    {
        if( fmt->i_codec == VLC_CODEC_OPUS )
        {
            codecpar->extradata_size = opus_size[0];
            codecpar->extradata = av_malloc( opus_size[0] );
            memcpy( codecpar->extradata, opus_packet[0], opus_size[0] );
        }
        else
        {
            codecpar->extradata_size = fmt->i_extra;
            codecpar->extradata = av_malloc( fmt->i_extra );
            memcpy( codecpar->extradata, fmt->p_extra, fmt->i_extra );
        }
    }

    return VLC_SUCCESS;
}