| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 911 人关注过本帖
标题:求助:读到的视频文件信息,和文件不一致呀???
只看楼主 加入收藏
追梦人zmrghy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:406
专家分:190
注 册:2021-4-9
结帖率:97.26%
收藏
 问题点数:0 回复次数:1 
求助:读到的视频文件信息,和文件不一致呀???
小白自学编程,处处遇问题。。。。
自学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)
搜索更多相关主题的帖子: NULL int 视频 文件 return 
2022-05-25 10:24
追梦人zmrghy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:406
专家分:190
注 册:2021-4-9
收藏
得分:0 
前面部分是复制,后半部分根据提示输入。。。
就把括号忘记了。。。。。

图片附件: 游客没有浏览图片的权限,请 登录注册
2022-05-25 10:41
快速回复:求助:读到的视频文件信息,和文件不一致呀???
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023030 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved