sws_scale函数
void FFmpegPLay::playScaleInternal(float scaleW,float scaleH)
{
if (filePath_.isEmpty())
{
QMessageBox::warning(nullptr,"warn","未选择文件",QMessageBox::Ok);
return;
}
std::string input_file=filePath_.toStdString();
av_register_all();
AVFormatContext *pFormatCtx = avformat_alloc_context();
if (avformat_open_input(&pFormatCtx,input_file.c_str(),nullptr,nullptr) < 0)
{
qDebug() << "fail to find the stream\n";
return;
}
if (avformat_find_stream_info(pFormatCtx,NULL) < 0)
{
qDebug() << "fail to find the stream info\n";
return;
}
// av_dump_format(pFormatCtx,0,input_file.c_str(),0);
int video_stream_index = -1;
for (size_t i =0;i < pFormatCtx->nb_streams ;++i )
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
video_stream_index = i;
break;
}
}
if (video_stream_index == -1)
{
qDebug() << "fail to find the video stream";
return;
}
AVCodecContext *pCodecCtx = pFormatCtx->streams[video_stream_index]->codec;
AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL)
{
qDebug() << "fail to find the decoder\n";
return;
}
if (avcodec_open2(pCodecCtx,pCodec,nullptr) < 0 )
{
qDebug() << "fail to open the decodec\n";
return;
}
AVFrame *pFrame = av_frame_alloc();
AVFrame *pframeRGB = av_frame_alloc();
unsigned char *out_buffer = (unsigned char*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB32,pCodecCtx->width*scaleW,pCodecCtx->height*scaleH,1));
av_image_fill_arrays(pframeRGB->data,pframeRGB->linesize,out_buffer,AV_PIX_FMT_RGB32,pCodecCtx->width*scaleW,pCodecCtx->height*scaleH,1);
AVPacket *pkt = av_packet_alloc();
av_init_packet(pkt);
SwsContext *pSwsCtx = sws_alloc_context();
emit calSize(pCodecCtx->width*scaleW,pCodecCtx->height*scaleH);
pSwsCtx = sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,
pCodecCtx->width*scaleW,pCodecCtx->height*scaleH,AV_PIX_FMT_RGB32,
SWS_BICUBIC,nullptr,nullptr,nullptr);
int got_frame = 0;
while(av_read_frame(pFormatCtx,pkt) >= 0)
{
if (pkt->stream_index == video_stream_index){
int ret = avcodec_decode_video2(pCodecCtx,pFrame,&got_frame,pkt);
if (ret < 0)
{
qDebug() << "fail to decode video\n";
return;
}
if (got_frame > 0)
{
sws_scale(pSwsCtx,(const unsigned char* const*)pFrame->data,pFrame->linesize,0,pCodecCtx->height,pframeRGB->data,pframeRGB->linesize);
QImage image = QImage((unsigned char*)pframeRGB->data[0],pCodecCtx->width*scaleW,pCodecCtx->height*scaleH,QImage::Format_RGB32,nullptr,nullptr);
emit genImage(image);
usleep(30000);
}
}
av_packet_unref(pkt);
}
sws_freeContext(pSwsCtx);
av_packet_free(&pkt);
avformat_close_input(&pFormatCtx);
avformat_free_context(pFormatCtx);
emit palyFinished();
}
测试结果
2倍大小
0.5倍大小
1倍大小