求助:读到的视频文件信息,和文件不一致呀???
小白自学编程,处处遇问题。。。。自学FFmpeg,一字一句地抄写代码。
反复核对,没有错误。。。。
读到的视频格式,高720 正解,宽328470768, 实际宽 1280
到底什么原因呀???
程序代码:
// FFmpegPlayer.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" extern "C" { #include"libavcodec\avcodec.h" #include"libavformat\avformat.h" #include"libswscale\swscale.h" #include"libavutil\imgutils.h" #include"libswresample\swresample.h" } AVFormatContext *fmt_ctx; //流队列中,视频流所在的位置 int video_index = -1; //视频解码上下文 AVCodecContext *video_codec_ctx; //输出缓存大小 int video_out_buffer_size; //输出缓存 uint8_t *video_out_buffer; //转码后输出的视频帧(如yur转rgb24) AVFrame *video_out_frame = av_frame_alloc(); //格式转换上下文 struct SwsContext *video_convert_ctx; //解码前数据包 AVPacket *packet = (AVPacket *)malloc(sizeof(AVPacket)); //初始化FFmpeg //@param *url 媒体地址(本地/网络地址) int init_ffmpeg(char *url) { av_register_all(); //注册组件 avformat_network_init(); //支持网络流 fmt_ctx = avformat_alloc_context(); //打开文件 if (avformat_open_input(&fmt_ctx, url, NULL, NULL) != 0) { return -1; } //查找流信息 if (avformat_find_stream_info(fmt_ctx, NULL) < 0) { return -1; } //找到流队列中,视频流所在位置 for (int i = 0; i < fmt_ctx->nb_streams; i++) { if (fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { video_index = i; break; } } //视频流没有找到 if (video_index == -1) { return -1; } //查找解码器 video_codec_ctx = fmt_ctx->streams[video_index]->codec; AVCodec *video_codec = avcodec_find_decoder(video_codec_ctx->codec_id); //解码器没找到 if (video_codec == NULL) { return -1; } //打开解码器 if (avcodec_open2(video_codec_ctx, video_codec, NULL) < 0) { return -1; } //计算输出缓存 video_out_buffer_size = av_image_get_buffer_size( AV_PIX_FMT_RGB24, video_codec_ctx->width, video_codec_ctx->height, 1); //输出缓存 video_out_buffer = new uint8_t[video_out_buffer_size]; //准备一些参数,在视频格式转换后,参数将被设置值 av_image_fill_arrays( video_out_frame->data, //转换后的数据 video_out_frame->linesize, video_out_buffer, //视频buffer AV_PIX_FMT_RGB24, //像素格式 video_codec_ctx->width, video_codec_ctx->height, 1); video_convert_ctx = sws_getContext( //图片格式转换上下文 video_codec_ctx->width, video_codec_ctx->height, video_codec_ctx->pix_fmt, video_codec_ctx->width, video_codec_ctx->height, AV_PIX_FMT_RGB24, //转码为RGB像素 SWS_BICUBIC, NULL, NULL, NULL); av_init_packet(packet); return 0; } //读取一帧 int read_frame() { int ret = -1; //从packet中解出一帧,0为未解出 int got_picture; //从packet中解出来的原始视频帧 AVFrame *original_video_frame = av_frame_alloc(); if (av_read_frame(fmt_ctx, packet) == 0) { if (packet->stream_index == video_index) { //解码,输入为packet, 输出为original_video_frame if (avcodec_decode_video2(video_codec_ctx, original_video_frame, &got_picture, packet) >= 0) { if (got_picture) { //图片格式转换(上面图片转换准备的参数,在这时使用) sws_scale(video_convert_ctx,//图片转换上下文 (const uint8_t* const*)original_video_frame->data, //原始数据 original_video_frame->linesize, //原始参数 0, //转码开始游标,一般为0 video_codec_ctx->height, //行数 video_out_frame->data, //转码后的数据 video_out_frame->linesize); ret = 1; } } } } av_free_packet(packet); av_free(original_video_frame); return ret; } //获取视频缓存大小 int get_video_buffer_size() { return video_out_buffer_size; } //获取视频帧 char *get_video_frame() { return (char *)video_out_buffer; } //获取视频宽度 int get_video_width() { return video_codec_ctx->width; } //获取视频高度 int get_video_height() { return video_codec_ctx->height; } //释放资源 void release() { sws_freeContext(video_convert_ctx); av_free(video_out_frame); av_free(video_out_buffer); avcodec_close(video_codec_ctx); avformat_close_input(&fmt_ctx); } int main() { //char url[] = "rtmp://live.hkstv.hk. char url[] = "F:\\KwDownload\\搞笑视频\\黑妹在外被狗咬.mp4"; int init_ret = init_ffmpeg(url); if (init_ret >= 0) { while (read_frame() < 0) //读取一帧,直到读到数据 { printf("未读取到数据\n"); } printf("高度:%d 宽度:%d 缓存大小:%d", get_video_height(), get_video_width, get_video_buffer_size); printf("\n==================================\n"); printf(get_video_frame()); //打印出来,虽然打印出来的东西年不懂,但证明已经获取到一帧数据了 } else { printf("初始化失败!"); } return 0; }
源代码文件
FFmpegPlayer.cpp
(4.51 KB)