|
求助:读到的视频文件信息,和文件不一致呀???
小白自学编程,处处遇问题。。。。
自学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.lxdns.com/live/hks";
- 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.rar
(1.91 KB, 下载次数: 1)
|
上一篇: STrip = inet_ntoa(clientAddr.sin_addr);下一篇: 关于fstream的疑问
|