#include <stdio.h> #include <string.h> extern "C" { #include "libavformat/avformat.h" #include "libavutil/dict.h" }; #pragma comment(lib, "avformat.lib") #pragma comment(lib, "avutil.lib") #pragma comment(lib, "avcodec.lib") int main() { AVFormatContext *pFormatCtx = NULL; AVCodecContext *pCodecCtx = NULL; AVCodec *pCodec; AVDictionaryEntry *dict = NULL; int iHour, iMinute, iSecond, iTotalSeconds;//HH:MM:SS int videoIndex, audioIndex; char *fileName = "bad.mp4"; //char *fileName = "Titanic.ts"; av_register_all();//注册全部组件 if (avformat_open_input(&pFormatCtx, fileName, NULL, NULL) != 0)//打开输入视频文件 { printf("Couldn't open input stream.\n"); return -1; } if (avformat_find_stream_info(pFormatCtx, NULL) < 0) { printf("Couldn't find stream information.\n"); return -1; } videoIndex = -1; for (int i = 0; i < pFormatCtx->nb_streams/*视音频流的个数*/; i++) { if (pFormatCtx->streams[i]/*视音频流*/->codec->codec_type == AVMEDIA_TYPE_VIDEO)//查找音频 { videoIndex = i; break; } } if (videoIndex == -1) { printf("Couldn't find a video stream.\n"); return -1; } pCodecCtx = pFormatCtx->streams[videoIndex]->codec; //指向AVCodecContext的指针 pCodec = avcodec_find_decoder(pCodecCtx->codec_id); //指向AVCodec的指针.查找解码器 if (pCodec == NULL) { printf("Codec not found.\n"); return -1; } //打开解码器 if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { printf("Could not open codec.\n"); return -1; } audioIndex = -1; for (int i = 0; i < pFormatCtx->nb_streams; i++) { if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { audioIndex = i; break; } } if (audioIndex == -1) { printf("Couldn't find a audio stream.\n"); return -1; } //打印结构体信息 puts("AVFormatContext信息:"); puts("---------------------------------------------"); printf("文件名:%s\n", pFormatCtx->filename); iTotalSeconds = (int)pFormatCtx->duration/*微秒*/ / 1000000; iHour = iTotalSeconds / 3600;//小时 iMinute = iTotalSeconds % 3600 / 60;//分钟 iSecond = iTotalSeconds % 60;//秒 printf("持续时间:%02d:%02d:%02d\n", iHour, iMinute, iSecond); printf("平均混合码率:%d kb/s\n", pFormatCtx->bit_rate / 1000); printf("视音频个数:%d\n", pFormatCtx->nb_streams); puts("---------------------------------------------"); puts("AVInputFormat信息:"); puts("---------------------------------------------"); printf("封装格式名称:%s\n", pFormatCtx->iformat->name); printf("封装格式长名称:%s\n", pFormatCtx->iformat->long_name); printf("封装格式扩展名:%s\n", pFormatCtx->iformat->extensions); printf("封装格式ID:%d\n", pFormatCtx->iformat->raw_codec_id); puts("---------------------------------------------"); puts("AVStream信息:"); puts("---------------------------------------------"); printf("视频流标识符:%d\n", pFormatCtx->streams[videoIndex]->index); printf("音频流标识符:%d\n", pFormatCtx->streams[audioIndex]->index); printf("视频流长度:%d微秒\n", pFormatCtx->streams[videoIndex]->duration); printf("音频流长度:%d微秒\n", pFormatCtx->streams[audioIndex]->duration); puts("---------------------------------------------"); puts("AVCodecContext信息:"); puts("---------------------------------------------"); printf("视频码率:%d kb/s\n", pCodecCtx->bit_rate / 1000); printf("视频大小:%d * %d\n", pCodecCtx->width, pCodecCtx->height); puts("---------------------------------------------"); puts("AVCodec信息:"); puts("---------------------------------------------"); printf("视频编码格式:%s\n", pCodec->name); printf("视频编码详细格式:%s\n", pCodec->long_name); puts("---------------------------------------------"); printf("视频时长:%d微秒\n", pFormatCtx->streams[videoIndex]->duration); printf("音频时长:%d微秒\n", pFormatCtx->streams[audioIndex]->duration); printf("音频采样率:%d\n", pFormatCtx->streams[audioIndex]->codec->sample_rate); printf("音频信道数目:%d\n", pFormatCtx->streams[audioIndex]->codec->channels); puts("AVFormatContext元数据:"); puts("---------------------------------------------"); while (dict = av_dict_get(pFormatCtx->metadata, "", dict, AV_DICT_IGNORE_SUFFIX)) { printf("[%s] = %s\n", dict->key, dict->value); } puts("---------------------------------------------"); puts("AVStream视频元数据:"); puts("---------------------------------------------"); dict = NULL; while (dict = av_dict_get(pFormatCtx->streams[videoIndex]->metadata, "", dict, AV_DICT_IGNORE_SUFFIX)) { printf("[%s] = %s\n", dict->key, dict->value); } puts("---------------------------------------------"); puts("AVStream音频元数据:"); puts("---------------------------------------------"); dict = NULL; while (dict = av_dict_get(pFormatCtx->streams[audioIndex]->metadata, "", dict, AV_DICT_IGNORE_SUFFIX)) { printf("[%s] = %s\n", dict->key, dict->value); } puts("---------------------------------------------"); av_dump_format(pFormatCtx, -1, fileName, 0); printf("\n\n编译信息:\n%s\n\n", avcodec_configuration()); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); return 0; }
虽然足够的简单,可是仍是报了”被声明为已否决”的erroride
在网上搜索到了解决方案:将VS的SDL检查关闭函数
这样error被下降为warning C4996编码
这样的解决方案是很冒险的。根据报错g:\coding\poet\ffmpegstudy\study.cpp(44): warning C4996: 'AVStream::codec': 被声明为已否决spa
咱们定位到所在代码:指针
if (pFormatCtx->streams[i]/*视音频流*/->codec->codec_type == AVMEDIA_TYPE_VIDEO)//查找音频 { videoIndex = i; break; }
#if FF_API_LAVF_AVCTX /** * @deprecated use the codecpar struct instead */ attribute_deprecated AVCodecContext *codec; #endifAVStream的codec成员再也不推荐使用,反而要求使用codecpar。
从而咱们知道FFmpeg中所谓的“被声明为已否决”就是由于函数或者结构体属性被标示为attribute_deprecated,颇有可能在将来的版本中就删除了。code
因此咱们最好的解决方案就是使用新的被推荐使用的函数、结构体等。orm
修改版(开启SDL检查也没有error与warning):视频
#include <stdio.h> #include <string.h> extern "C" { #include "libavformat/avformat.h" #include "libavutil/dict.h" }; #pragma comment(lib, "avformat.lib") #pragma comment(lib, "avutil.lib") #pragma comment(lib, "avcodec.lib") int main() { AVFormatContext *pFormatCtx = NULL; AVCodecContext *pCodecCtx = NULL; AVCodec *pCodec; AVDictionaryEntry *dict = NULL; int iHour, iMinute, iSecond, iTotalSeconds;//HH:MM:SS int videoIndex, audioIndex; char *fileName = "bad.mp4"; //char *fileName = "Titanic.ts"; av_register_all();//注册全部组件 if (avformat_open_input(&pFormatCtx, fileName, NULL, NULL) != 0)//打开输入视频文件 { printf("Couldn't open input stream.\n"); return -1; } if (avformat_find_stream_info(pFormatCtx, NULL) < 0) { printf("Couldn't find stream information.\n"); return -1; } videoIndex = -1; for (int i = 0; i < pFormatCtx->nb_streams/*视音频流的个数*/; i++) { if (pFormatCtx->streams[i]/*视音频流*/->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)//查找音频 { videoIndex = i; break; } } if (videoIndex == -1) { printf("Couldn't find a video stream.\n"); return -1; } /** * 不同意这样使用 * pCodecCtx = pFormatCtx->streams[videoIndex]->codec; //指向AVCodecContext的指针 */ pCodecCtx = avcodec_alloc_context3(NULL); if (pCodecCtx == NULL) { printf("Could not allocate AVCodecContext\n"); return -1; } avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoIndex]->codecpar); pCodec = avcodec_find_decoder(pCodecCtx->codec_id); //指向AVCodec的指针.查找解码器 if (pCodec == NULL) { printf("Codec not found.\n"); return -1; } //打开解码器 if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { printf("Could not open codec.\n"); return -1; } audioIndex = -1; for (int i = 0; i < pFormatCtx->nb_streams; i++) { if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { audioIndex = i; break; } } if (audioIndex == -1) { printf("Couldn't find a audio stream.\n"); return -1; } //打印结构体信息 puts("AVFormatContext信息:"); puts("---------------------------------------------"); printf("文件名:%s\n", pFormatCtx->filename); iTotalSeconds = (int)pFormatCtx->duration/*微秒*/ / 1000000; iHour = iTotalSeconds / 3600;//小时 iMinute = iTotalSeconds % 3600 / 60;//分钟 iSecond = iTotalSeconds % 60;//秒 printf("持续时间:%02d:%02d:%02d\n", iHour, iMinute, iSecond); printf("平均混合码率:%d kb/s\n", pFormatCtx->bit_rate / 1000); printf("视音频个数:%d\n", pFormatCtx->nb_streams); puts("---------------------------------------------"); puts("AVInputFormat信息:"); puts("---------------------------------------------"); printf("封装格式名称:%s\n", pFormatCtx->iformat->name); printf("封装格式长名称:%s\n", pFormatCtx->iformat->long_name); printf("封装格式扩展名:%s\n", pFormatCtx->iformat->extensions); printf("封装格式ID:%d\n", pFormatCtx->iformat->raw_codec_id); puts("---------------------------------------------"); puts("AVStream信息:"); puts("---------------------------------------------"); printf("视频流标识符:%d\n", pFormatCtx->streams[videoIndex]->index); printf("音频流标识符:%d\n", pFormatCtx->streams[audioIndex]->index); printf("视频流长度:%d微秒\n", pFormatCtx->streams[videoIndex]->duration); printf("音频流长度:%d微秒\n", pFormatCtx->streams[audioIndex]->duration); puts("---------------------------------------------"); puts("AVCodecContext信息:"); puts("---------------------------------------------"); printf("视频码率:%d kb/s\n", pCodecCtx->bit_rate / 1000); printf("视频大小:%d * %d\n", pCodecCtx->width, pCodecCtx->height); puts("---------------------------------------------"); puts("AVCodec信息:"); puts("---------------------------------------------"); printf("视频编码格式:%s\n", pCodec->name); printf("视频编码详细格式:%s\n", pCodec->long_name); puts("---------------------------------------------"); printf("视频时长:%d微秒\n", pFormatCtx->streams[videoIndex]->duration); printf("音频时长:%d微秒\n", pFormatCtx->streams[audioIndex]->duration); printf("音频采样率:%d\n", pFormatCtx->streams[audioIndex]->codecpar->sample_rate); printf("音频信道数目:%d\n", pFormatCtx->streams[audioIndex]->codecpar->channels); puts("AVFormatContext元数据:"); puts("---------------------------------------------"); while (dict = av_dict_get(pFormatCtx->metadata, "", dict, AV_DICT_IGNORE_SUFFIX)) { printf("[%s] = %s\n", dict->key, dict->value); } puts("---------------------------------------------"); puts("AVStream视频元数据:"); puts("---------------------------------------------"); dict = NULL; while (dict = av_dict_get(pFormatCtx->streams[videoIndex]->metadata, "", dict, AV_DICT_IGNORE_SUFFIX)) { printf("[%s] = %s\n", dict->key, dict->value); } puts("---------------------------------------------"); puts("AVStream音频元数据:"); puts("---------------------------------------------"); dict = NULL; while (dict = av_dict_get(pFormatCtx->streams[audioIndex]->metadata, "", dict, AV_DICT_IGNORE_SUFFIX)) { printf("[%s] = %s\n", dict->key, dict->value); } puts("---------------------------------------------"); av_dump_format(pFormatCtx, -1, fileName, 0); printf("\n\n编译信息:\n%s\n\n", avcodec_configuration()); avcodec_free_context(&pCodecCtx); //avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); return 0; }参考自:ffplay.c