c语言图形界面如何播放视频

c语言图形界面如何播放视频

#include

#include

#include

#include

#include

int main(int argc, char *argv[]) {

AVFormatContext *pFormatCtx = NULL;

int videoStreamIndex;

AVCodecContext *pCodecCtx = NULL;

AVCodec *pCodec = NULL;

AVFrame *pFrame = NULL;

AVPacket packet;

struct SwsContext *sws_ctx = NULL;

SDL_Window *window = NULL;

SDL_Renderer *renderer = NULL;

SDL_Texture *texture = NULL;

SDL_Event event;

int quit = 0;

// Initialize FFmpeg

av_register_all();

// Open video file

if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0) {

fprintf(stderr, "Could not open file.n");

return -1;

}

// Retrieve stream information

if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {

fprintf(stderr, "Could not find stream information.n");

return -1;

}

// Find the first video stream

videoStreamIndex = -1;

for (int i = 0; i < pFormatCtx->nb_streams; i++) {

if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {

videoStreamIndex = i;

break;

}

}

if (videoStreamIndex == -1) {

fprintf(stderr, "Could not find video stream.n");

return -1;

}

// Get a pointer to the codec context for the video stream

pCodecCtx = avcodec_alloc_context3(NULL);

avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStreamIndex]->codecpar);

// Find the decoder for the video stream

pCodec = avcodec_find_decoder(pCodecCtx->codec_id);

if (pCodec == NULL) {

fprintf(stderr, "Unsupported codec.n");

return -1;

}

// Open codec

if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {

fprintf(stderr, "Could not open codec.n");

return -1;

}

// Allocate video frame

pFrame = av_frame_alloc();

// Initialize SDL

if (SDL_Init(SDL_INIT_VIDEO) < 0) {

fprintf(stderr, "Could not initialize SDL - %sn", SDL_GetError());

return -1;

}

// Create a window

window = SDL_CreateWindow("Video Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, pCodecCtx->width, pCodecCtx->height, SDL_WINDOW_SHOWN);

if (window == NULL) {

fprintf(stderr, "Could not create window - %sn", SDL_GetError());

return -1;

}

// Create a renderer

renderer = SDL_CreateRenderer(window, -1, 0);

if (renderer == NULL) {

fprintf(stderr, "Could not create renderer - %sn", SDL_GetError());

return -1;

}

// Create a texture

texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height);

if (texture == NULL) {

fprintf(stderr, "Could not create texture - %sn", SDL_GetError());

return -1;

}

// Read frames and display them

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

// Is this a packet from the video stream?

if (packet.stream_index == videoStreamIndex) {

// Decode video frame

int response = avcodec_send_packet(pCodecCtx, &packet);

if (response < 0) {

fprintf(stderr, "Error while sending a packet to the decoder: %sn", av_err2str(response));

return response;

}

while (response >= 0) {

response = avcodec_receive_frame(pCodecCtx, pFrame);

if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {

break;

} else if (response < 0) {

fprintf(stderr, "Error while receiving a frame from the decoder: %sn", av_err2str(response));

return response;

}

// Convert the image from its native format to YUV

sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);

AVFrame *pFrameYUV = av_frame_alloc();

uint8_t *buffer = (uint8_t *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1) * sizeof(uint8_t));

av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);

sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);

// Update the texture

SDL_UpdateYUVTexture(texture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0], pFrameYUV->data[1], pFrameYUV->linesize[1], pFrameYUV->data[2], pFrameYUV->linesize[2]);

// Free the YUV frame

av_free(buffer);

av_frame_free(&pFrame

相关数据