#include <stdio.h>
#include <SDL/SDL.h>

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>


int main(int argc, char* argv[]){
    if(argc < 2){
        printf("User: %s streamId\n", argv[0]);
        return 0;
    }
    av_register_all();
    avformat_network_init();

    int err;
    err = SDL_Init(SDL_INIT_VIDEO);
    if(err < 0){
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
        return -1;
    }

    const char* filename = argv[1];

    AVFormatContext* format_context = NULL;

    err = avformat_open_input(&format_context, filename, NULL, NULL);
    if(err < 0){
        fprintf(stderr, "ffmpeg: unable to open input file\n");
        return -1;
    }

    err = avformat_find_stream_info(format_context, NULL);
    if(err < 0){
        fprintf(stderr, "ffmpeg: Unable to find stream info\n");
        return -1;
    }

    av_dump_format(format_context, 0, argv[1], 0);

    int video_stream;
    for(video_stream=0; video_stream < format_context->nb_streams; ++video_stream){
        if(format_context->streams[video_stream]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
            break;
        }
    }

    if(video_stream == format_context->nb_streams){
        fprintf(stderr, "ffmpeg: unable to find video stream\n");
        return -1;
    }

    AVCodecContext* codec_context = format_context->streams[video_stream]->codec;
    AVCodec* codec = avcodec_find_decoder(codec_context->codec_id);
    err = avcodec_open2(codec_context, codec, NULL);
    if(err < 0){
        fprintf(stderr, "ffmpeg: Unable to open codec\n");
        return -1;
    }

    SDL_Surface* screen = SDL_SetVideoMode(codec_context->width, codec_context->height, 0, 0);
    if(screen == NULL){
        fprintf(stderr, "Couldn't set video mode\n");
        return -1;
    }

    SDL_Overlay* bmp = SDL_CreateYUVOverlay(codec_context->width,
                                            codec_context->height,
                                            SDL_YV12_OVERLAY, screen);

    struct SwsContext* img_convert_context;
    img_convert_context = sws_getCachedContext(
            NULL,
            codec_context->width, codec_context->height,
            codec_context->pix_fmt,
            codec_context->width, codec_context->height,
            PIX_FMT_YUV420P, SWS_BICUBIC,
            NULL, NULL, NULL);
    if(img_convert_context == NULL){
        fprintf(stderr, "Cannot initialize the conversion context\n");
        return -1;
    }

    AVFrame* frame = av_frame_alloc();
    AVPacket packet;
    while(av_read_frame(format_context, &packet) >= 0){
        if(packet.stream_index == video_stream){
            int frame_finished;
            avcodec_decode_video2(codec_context, frame, &frame_finished, &packet);

            if(frame_finished){
                SDL_LockYUVOverlay(bmp);

                AVPicture pict;
                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];

                sws_scale(img_convert_context,
                        frame->data, frame->linesize,
                        0, codec_context->height,
                        pict.data, pict.linesize);
                SDL_UnlockYUVOverlay(bmp);

                SDL_Rect rect;
                rect.x = 0;
                rect.y = 0;
                rect.w = codec_context->width;
                rect.h = codec_context->height;
                SDL_DisplayYUVOverlay(bmp, &rect);
            }
        }

        av_free_packet(&packet);

        SDL_Event event;
        if(SDL_PollEvent(&event)){
            if(event.type == SDL_QUIT){
                break;
            }
        }
    }

    sws_freeContext(img_convert_context);
    av_free(frame);

    avcodec_close(codec_context);

    avformat_close_input(&format_context);

    SDL_Quit();

    return 0;
}

Изменить пасту