[FFmpeg-user] Help with a simple player code

Ignacio Gonzalez mylaneza at gmail.com
Thu Aug 30 00:06:56 CEST 2012


Hello everybody, I'm reading the tutorial of ffmpeg to display a video:
http://dranger.com/ffmpeg/tutorial02.html

I know almost all functions used in this tutorial are deprecated or changed
their names. I'm using ffmpeg 0.10.4.

My problem is that any video that i am trying to play the display only saws
green.

This is my code:

int load( ){
    avcodec_register_all();
    av_register_all();
    avformat_network_init();
    if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER ) ) {
        printf("Could not initialize SDL - %s\n", SDL_GetError());
        return -1;
    }
    return 0;
}

int play( char const *file ){

    SDL_Surface *screen = NULL;
    SDL_Overlay     *bmp;
    AVFormatContext *input = NULL ;
    AVCodecContext *videoDecoderContext;
    AVCodecContext *audioDecoderContext;
    AVCodec *videoDecoder;
    AVCodec *audioDecoder;
    int res; //Para checar resultados
    int video_stream_index;
    int audio_stream_index;
    AVPacket packet;
    AVFrame *frame;
    int frameFinished;
    int sdl_flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;

    input = avformat_alloc_context();
    if( !input )
        return -1;

    res = avformat_open_input( &input , file , NULL , NULL );
    if( res < 0 )
        return -1;

    res = avformat_find_stream_info( input , NULL );
    if( res < 0 )
        return -1;

    video_stream_index = av_find_best_stream(input,
AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);
    audio_stream_index = av_find_best_stream(input,
AVMEDIA_TYPE_AUDIO,-1,-1,NULL,0);

    if( video_stream_index >= 0 ){
        videoDecoderContext = input->streams[ video_stream_index ]->codec;
        videoDecoder = avcodec_find_decoder( videoDecoderContext->codec_id
);
        res = avcodec_open2( videoDecoderContext, videoDecoder , NULL );
        if( res < 0 )
            return -1;

        screen = SDL_SetVideoMode( videoDecoderContext->width ,
videoDecoderContext->height , 0, sdl_flags );

        if(!screen) {
            return -1;
        }
    }
    if( audio_stream_index >= 0 ){
        audioDecoderContext = input->streams[ audio_stream_index ]->codec;
        audioDecoder = avcodec_find_decoder( audioDecoderContext->codec_id
);
        res = avcodec_open2( audioDecoderContext, audioDecoder , NULL );
        if( res < 0 )
            return -1;
    }


    bmp = SDL_CreateYUVOverlay( videoDecoderContext->width,
videoDecoderContext->height , SDL_YV12_OVERLAY, screen );

    frame = avcodec_alloc_frame();

    av_init_packet(&packet);

    while(av_read_frame(input, &packet) >= 0 ) {

        if( packet.stream_index== video_stream_index ) {

            avcodec_decode_video2( videoDecoderContext , frame ,
&frameFinished, &packet );

            if(frameFinished) {
                SDL_LockYUVOverlay(bmp);
                SDL_Rect rect;
                AVPicture pict;
                struct SwsContext *img_convert_ctx;
                pict.data[0] = bmp->pixels[0];
                pict.data[1] = bmp->pixels[2];
                pict.data[2] = bmp->pixels[1];

                pict.linesize[0] = bmp->pitches[0];
                pict.linesize[1] = bmp->pitches[2];
                pict.linesize[2] = bmp->pitches[1];

                // Convert the image into YUV format that SDL uses


                   * sws_getCachedContext(    img_convert_ctx,
                                            videoDecoderContext->width ,
                                            videoDecoderContext->height ,
                                            videoDecoderContext->pix_fmt,
                                            videoDecoderContext->width ,
                                            videoDecoderContext->height ,
                                            PIX_FMT_YUV420P,
                                            0 ,
                                            NULL,
                                            NULL,
                                            NULL);*

                    sws_scale(    img_convert_ctx,
                                (const uint8_t * const * )frame->data,
                                frame->linesize,
                                0,
                                videoDecoderContext->height,
                                pict.data,
                                pict.linesize);


                SDL_UnlockYUVOverlay(bmp);
                rect.x = 0;
                rect.y = 0;
                rect.w = videoDecoderContext->width;
                rect.h = videoDecoderContext->height;

                SDL_DisplayYUVOverlay(bmp, &rect);
            }
        }
        // Free the packet that was allocated by av_read_frame

        av_free_packet(&packet);
    }


    return 0;
}

When i comment the swscale functions for converting the pixel format, my
code compiles but the display is green, when uncomment the functions, my
program crashes in the sws_getCachedContext, can anybody tell me what am i
doing wrong or what is missing?


More information about the ffmpeg-user mailing list