简介: 【音视频 ffmpeg 】直播推流QT框架搭建
3个线程
一个做视频解码一个做音频解码一个做复用推流
视频解码线程展示
#include "videodecodethread.h"
VideodecodeThread::VideodecodeThread(QObject *parent):QThread(parent)
{avdevice_register_all();avformat_network_init();
}
void VideodecodeThread::run()
{fmt = av_find_input_format("dshow");av_dict_set(&options, "video_size", "640*480", 0);av_dict_set(&options, "framerate", "30", 0);ret = avformat_open_input(&pFormatCtx, "video=ov9734_azurewave_camera", fmt, &options);if (ret < 0){qDebug() << "Couldn't open input stream." << ret;return;}ret = avformat_find_stream_info(pFormatCtx, &options);if(ret < 0){qDebug()<< "Couldn't find stream information.";return;}videoIndex = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &pAvCodec, 0);if(videoIndex < 0){qDebug()<< "Couldn't av_find_best_stream.";return;}pAvCodec = avcodec_find_decoder(pFormatCtx->streams[videoIndex]->codecpar->codec_id);if(!pAvCodec){qDebug()<< "Couldn't avcodec_find_decoder.";return;}qDebug()<<"avcodec_open2 pAVCodec->name:" << QString::fromStdString(pAvCodec->name);if(pFormatCtx->streams[videoIndex]->avg_frame_rate.den != 0){float fps_ = pFormatCtx->streams[videoIndex]->avg_frame_rate.num / pFormatCtx->streams[videoIndex]->avg_frame_rate.den;qDebug() <<"fps:" << fps_;}int64_t video_length_sec_ = pFormatCtx->duration/AV_TIME_BASE;qDebug() <<"video_length_sec_:" << video_length_sec_;pAvCodecCtx = avcodec_alloc_context3(pAvCodec);if(!pAvCodecCtx){qDebug()<< "Couldn't avcodec_alloc_context3.";return;}ret = avcodec_parameters_to_context(pAvCodecCtx, pFormatCtx->streams[videoIndex]->codecpar);if(ret < 0){qDebug()<< "Couldn't avcodec_parameters_to_context.";return;}pAvFrame = av_frame_alloc();pAvFrameYUV = av_frame_alloc();
// pSwsCtx = sws_getContext(pAvCodecCtx->width, pAvCodecCtx->height, pAvCodecCtx->pix_fmt,
// pAvCodecCtx->width, pAvCodecCtx->height, AV_PIX_FMT_YUV420P9,
// SWS_BICUBIC, NULL, NULL, NULL);//m_size = av_image_get_buffer_size(AVPixelFormat(AV_PIX_FMT_YUV420P9), pAvCodecCtx->width, pAvCodecCtx->height, 1);//为已经分配的空间的结构体AVPicture挂上一段用于保存数据的空间//av_image_fill_arrays(pAvFrameYUV->data, pAvFrameYUV->linesize, buffer, AV_PIX_FMT_BGR32, pAvCodecCtx->width, pAvCodecCtx->height, 1);av_new_packet(packet, pAvCodecCtx->width * pAvCodecCtx->height);while(run_flag && !av_read_frame(pFormatCtx, packet)){if (packet->stream_index == videoIndex){//解码一帧视频数据int iGotPic = avcodec_send_packet(pAvCodecCtx, packet);if(iGotPic != 0){qDebug()<<"iVideoIndex avcodec_send_packet error";continue;}iGotPic = avcodec_receive_frame(pAvCodecCtx, pAvFrame);if(iGotPic == 0){//转换像素
// sws_scale(pSwsCtx, (uint8_t const * const *)pAvFrame->data, pAvFrame->linesize, 0,
// pAvFrame->height, pAvFrameYUV->data, pAvFrameYUV->linesize);//buffer = (uint8_t*)av_malloc(pAvFrame->height * pAvFrame->linesize[0]);byte = QByteArray((char*)pAvFrame->data);videoQueue.push(byte);videoCount++;}}av_packet_unref(packet);}
}
ffmpeg 函数解读
后面加上音频以及复用推流过程
粉丝福利, 免费领取C++音视频学习资料包+学习路线大纲、技术视频/代码,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓