Ejemplo n.º 1
0
/*****************************************************************************
 * 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;
        }

#if LIBAVCODEC_VERSION_MAJOR < 54
        id->ff_enc_c = avcodec_alloc_context();
#else
        id->ff_enc_c = avcodec_alloc_context3( id->ff_enc );
#endif
        id->ff_enc_c->dsp_mask = GetVlcDspMask();
        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;

        vlc_avcodec_lock();
        int ret;
#if LIBAVCODEC_VERSION_MAJOR >= 54
        AVDictionary *options = NULL;
        if (p_sys->options)
            av_dict_copy(&options, p_sys->options, 0);
        ret = avcodec_open2( id->ff_enc_c, id->ff_enc, options ? &options : NULL );
#else
        ret = avcodec_open( id->ff_enc_c, id->ff_enc );
#endif
        vlc_avcodec_unlock();
#if LIBAVCODEC_VERSION_MAJOR >= 54
        AVDictionaryEntry *t = NULL;
        while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) {
            msg_Err( p_stream, "Unknown option \"%s\"", t->key );
        }
        av_dict_free(&options);
#endif
        if (ret)
        {
            msg_Err( p_stream, "cannot open encoder" );
            return 0;
        }

        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;
}
Ejemplo n.º 2
0
Archivo: avcodec.c Proyecto: AsamQi/vlc
/*****************************************************************************
 * 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();

    /* *** 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;

    /* set CPU capabilities */
#if LIBAVUTIL_VERSION_CHECK(51, 25, 0, 42, 100)
    av_set_cpu_flags_mask( INT_MAX & ~GetVlcDspMask() );
#else
    p_context->dsp_mask = GetVlcDspMask();
#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;
}
Ejemplo n.º 3
0
/*****************************************************************************
 * 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 )
    {
        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;
        }

#if LIBAVCODEC_VERSION_MAJOR < 54
        id->ff_enc_c = avcodec_alloc_context();
#else
        id->ff_enc_c = avcodec_alloc_context3( id->ff_enc );
#endif
        id->ff_enc_c->dsp_mask = GetVlcDspMask();
        id->ff_enc_c->sample_rate = p_fmt->audio.i_rate;
        id->ff_enc_c->time_base.num = 1;
        id->ff_enc_c->time_base.den = 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;

        int ret;
#if LIBAVCODEC_VERSION_MAJOR >= 54
        AVDictionary *options = NULL;
        if (p_sys->options)
            av_dict_copy(&options, p_sys->options, 0);
        vlc_avcodec_lock();
        ret = avcodec_open2( id->ff_enc_c, id->ff_enc, options ? &options : NULL );
        vlc_avcodec_unlock();
        AVDictionaryEntry *t = NULL;
        while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) {
            msg_Err( p_stream, "Unknown option \"%s\"", t->key );
        }
        av_dict_free(&options);
#else
        vlc_avcodec_lock();
        ret = avcodec_open( id->ff_enc_c, id->ff_enc );
        vlc_avcodec_unlock();
#endif

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

        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_stream->p_next->pf_add( p_stream->p_next, 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;
}