本文共 2700 字,大约阅读时间需要 9 分钟。
main.cpp文件代码如下:
#include "myplayer.h"#include运行结果如图:#pragma comment(lib,"avformat.lib")#pragma comment(lib,"avutil.lib")#pragma comment(lib,"avcodec.lib")#pragma comment(lib,"swscale.lib")extern "C"{ #include #include }static double r2d(AVRational r){ return r.num == 0 || r.den == 0 ? 0. : (double)r.num / (double)r.den;}int main(int argc, char *argv[]){ av_register_all(); char *path = "test.mp4"; AVFormatContext *ac = NULL; int re = avformat_open_input(&ac, path, 0, 0); if (re != 0){//打开文件失败 char buf[1024] = { 0 }; av_strerror(re, buf, sizeof(buf)); printf("file %s open failed because of : %s", path, buf); getchar(); return -1; } int totalSec = ac->duration / AV_TIME_BASE; printf("指定的视频文件有 %d分%d秒\n", totalSec / 60, totalSec % 60); int videoStream = 0; AVCodecContext *videoCtx = NULL; SwsContext *cCtx = NULL; int outWidth = 640; int outHeight = 480; char *rgb = new char[outWidth * outHeight * 4]; for (int i = 0; i < ac->nb_streams; i++) { AVCodecContext *enc = ac->streams[i]->codec; if (enc->codec_type == AVMEDIA_TYPE_VIDEO){ videoStream = i; videoCtx = enc; AVCodec *codec = avcodec_find_decoder(enc->codec_id); if (!codec){ printf("无法解码此视频文件\n"); return -1; } int err = avcodec_open2(enc, codec, NULL); if (err != 0){ char buf[1024] = { 0 }; av_strerror(err, buf, sizeof(buf)); printf(buf); return -2; } printf("\n"); printf("成功打开视频编码流\n"); } } AVFrame *yuv = av_frame_alloc(); for (;;){ AVPacket pkt; re = av_read_frame(ac, &pkt); if (re != 0){ break; } if (pkt.stream_index != videoStream) { av_packet_unref(&pkt); continue; } int pts = pkt.pts * r2d(ac->streams[pkt.stream_index]->time_base) * 1000;//得到帧的毫秒值 int re = avcodec_send_packet(videoCtx,&pkt); if (re != 0){ av_packet_unref(&pkt); continue; } re = avcodec_receive_frame(videoCtx,yuv); if (re != 0){ av_packet_unref(&pkt); continue; } printf("[D]___"); //打开ffmpeg格式转换和缩放器 cCtx = sws_getCachedContext(cCtx, videoCtx->width, videoCtx->height, videoCtx->pix_fmt, outWidth, outHeight, AV_PIX_FMT_BGRA, SWS_BICUBIC, NULL, NULL, NULL); if (!cCtx){ printf("sws_getCachedContext failed!\n"); break; } uint8_t *data[AV_NUM_DATA_POINTERS] = {0}; data[0] = (uint8_t *)rgb; int linesize[AV_NUM_DATA_POINTERS] = { 0 }; linesize[0] = outWidth * 4; int h = sws_scale(cCtx, yuv->data, yuv->linesize, 0, videoCtx->height, data, linesize); if (h > 0){ printf("(%d)", h); } printf("pts = %d 毫秒\n", pts); av_packet_unref(&pkt); } if (cCtx){ sws_freeContext(cCtx); cCtx = NULL; } avformat_close_input(&ac); ac = NULL; QApplication a(argc, argv); MyPlayer w; w.show(); return a.exec();}