//驾驶室摄像头
#include "audio_video_encode_0.h"
class Thread_VideoAudioEncode_0 thread_VideoAudioEncode_0; //编码线程
class VideoAudioEncode videoaudioencode_0;
unsigned char *video_yuv420p_buff=nullptr;//[VIDEO_WIDTH*VIDEO_HEIGHT*3/2];
unsigned char *video_yuv420p_buff_temp=nullptr;//[VIDEO_WIDTH*VIDEO_HEIGHT*3/2];
unsigned char *rgb_buffer=nullptr;
static unsigned char audio_write_buffer[2048];
static qint32 audio_write_cnt=0;
static QByteArray audio_buffer;//存放队列里的一帧音频数据
/*获取一帧音频数据 */
static AVFrame *get_audio_frame(OutputStream *ost)
{
AVFrame *frame = ost->tmp_frame;
int16_t *q = (int16_t*)frame->data[0];
/* 检查我们是否要生成更多帧----用于判断是否结束*/
if(av_compare_ts(ost->next_pts, ost->enc->time_base,
STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
{
// if(videoaudioencode.audio_data_queue.isEmpty())
return nullptr;
}
// qDebug("frame->nb_samples=%d\n",frame->nb_samples); //2048
// qDebug("ost->enc->channels=%d\n",ost->enc->channels); //1
//判断缓冲区的数据是否足够2048字节
if(audio_write_cnt+2048<=audio_buffer.size())
{
memcpy(audio_write_buffer,audio_buffer.data()+audio_write_cnt,2048);
audio_write_cnt+=2048; //每次累加2048
}
else
{
int temp_cnt=0;
if(audio_buffer.size()-audio_write_cnt>0) //上一次缓冲区结尾还有数据,但是不足1024
{
memcpy(audio_write_buffer,audio_buffer.data()+audio_write_cnt,audio_buffer.size()-audio_write_cnt);
temp_cnt=audio_buffer.size()-audio_write_cnt; //拷贝的字节数量
audio_write_cnt=0; //缓冲区的数据已经写完了
// qDebug()<<"temp_cnt="<<temp_cnt;
}
//判断当前缓冲区是否有数据 ,没有数据就从队列里取出一帧
//qDebug()<<"从队列里取出一帧数据.";
//等待队列里有数据才能取出来
while(videoaudioencode_0.audio_data_queue.isEmpty())
{
QThread::msleep(5);
if(videoaudioencode_0.run_flag==0)return nullptr;
}
//消费者 -从队列里取出数据
videoaudioencode_0.audio_encode_mutex.lock();
audio_buffer=videoaudioencode_0.audio_data_queue.dequeue();
#ifdef PCM_DATA_SAVE
pcm_data->write(audio_buffer);
#endif
videoaudioencode_0.audio_encode_mutex.unlock();
// qDebug()<<"out_put="<<videoaudioencode.audio_data_queue.size();
if(temp_cnt==0)
{
memcpy(audio_write_buffer,audio_buffer.data(),2048);
audio_write_cnt=2048;
}
else
{
memcpy(audio_write_buffer+temp_cnt,audio_buffer.data(),2048-temp_cnt);
audio_write_cnt=2048-temp_cnt;
}
}
// qDebug()<<"audio_write_cnt="<<audio_write_cnt; AV_SAMPLE_FMT_FLTP
//nb_samples: 此帧描述的音频样本数(每个通道)
//channels:音频通道数
//音频数据赋值 1024x2
memcpy(q,audio_write_buffer,frame->nb_samples*sizeof(int16_t)*ost->enc->channels);
frame->pts = ost->next_pts;
ost->next_pts += frame->nb_samples;
return frame;
}
/*
准备图像数据
YUV422占用内存空间 = w * h * 2
YUV420占用内存空间 = width*height*3/2
*/
static void fill_yuv_image(AVFrame *pict, int frame_index,int width, int height)
{
unsigned int y_size=width*height;
videoaudioencode_0.video_encode_mutex.lock();
videoaudioencode_0.video_WaitConditon.wait(&videoaudioencode_0.video_encode_mutex);
memcpy(video_yuv420p_buff_temp,video_yuv420p_buff,videoaudioencode_0.image_sizeo);
videoaudioencode_0.video_encode_mutex.unlock();
//将YUV数据拷贝到缓冲区 y_size=wXh
memcpy(pict->data[0],video_yuv420p_buff_temp,y_size);
memcpy(pict->data[1],video_yuv420p_buff_temp+y_size,y_size/4);
memcpy(pict->data[2],video_yuv420p_buff_temp+y_size+y_size/4,y_size/4);
}
static AVFrame *get_video_frame(OutputStream *ost)
{
AVCodecContext *c = ost->enc;
/* 检查我们是否要生成更多帧---判断是否结束录制 */
if(av_compare_ts(ost->next_pts, c->time_base,STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
return nullptr;
/*当我们将帧传递给编码器时,它可能会保留对它的引用
*内部; 确保我们在这里不覆盖它*/
if (av_frame_make_writable(ost->frame) < 0)
exit(1);
//获取图像
//DTS(解码时间戳)和PTS(显示时间戳)
fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);
ost->frame->pts = ost->next_pts++;
//视频帧添加水印
return ost->frame;
}
//析构函数
VideoReadThread_0::~VideoReadThread_0()
{
}
//停止视频采集
void VideoReadThread_0::stop()
{
qDebug()<<"停止视频采集--stop";
if(camera)
{
camera->stop();
delete camera;
camera=nullptr;
}
if(m_pProbe)
{
delete m_pProbe;
m_pProbe=nullptr;
}
if(timer)
{
timer->stop();
delete timer;
}
}
//执行线程
void VideoReadThread_0::run()
{
stop();
if(videoaudioencode_0.desktop_flag)
{
qDebug()<<"桌面开始采集数据";
//Windows系统截图
screen = QGuiApplication::primaryScreen();
timer=new QTimer;
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(70); //采集时间
}
else
{
Camear_Init();
qDebug()<<"摄像头开始采集数据";
}
}
//定时采集桌面的数据
void VideoReadThread_0::update()
{
QPixmap pixmap=screen->grabWindow(0); //获取当前屏幕的图像
QImage image=pixmap.toImage();
image=image.scaled(VIDEO_WIDTH,VIDEO_HEIGHT,Qt::KeepAspectRatio, Qt::SmoothTransformation);
//绘制图片水印
QDateTime dateTime(QDateTime::currentDateTime());
//时间效果: 2020-03-05 16:25::04 周一
QString qStr="";
qStr+=dateTime.toString("yyyy-MM-dd hh:mm:ss ddd");
QPainter pp(&image);
QPen pen = QPen(Qt::white);
pp.setPen(pen);
pp.drawText(QPointF(0,20),qStr);
//提取RGB数据
unsigned char *p=rgb_buffer;
for(int i=0;i<image.height();i++)
{
for(int j=0;j<image.width();j++)
{
QRgb rgb=image.pixel(j,i);
*p++=qRed(rgb);
*p++=qGreen(rgb);
*p++=qBlue(rgb);
}
}
videoaudioencode_0.video_encode_mutex.lock();
RGB24_TO_YUV420(rgb_buffer,image.width(),image.height(),video_yuv420p_buff);
videoaudioencode_0.video_encode_mutex.unlock();
videoaudioencode_0.video_WaitConditon.wakeAll();
emit VideoDataOutput(image.scaled(640,480,Qt::KeepAspectRatio, Qt::SmoothTransformation)); //发送信号
}
void VideoReadThread_0::Camear_Init()
{
/*创建摄像头对象,根据选择的摄像头打开*/
camera = new QCamera(videoaudioencode_0.camera);
m_pProbe = new QVideoProbe;
if(m_pProbe != nullptr)
{
m_pProbe->setSource(camera); // Returns true, hopefully.
connect(m_pProbe, SIGNAL(videoFrameProbed(QVideoFrame)),this, SLOT(slotOnProbeFrame(QVideoFrame)), Qt::QueuedConnection);
}
/*配置摄像头捕 QCamera *camera;
QVideoProbe *m_pProbe;获模式为帧捕获模式*/
//camera->setCaptureMode(QCamera::CaptureStillImage); //如果在Linux系统下运行就这样设置
camera->setCaptureMode(QCamera::CaptureVideo);//如果在android系统下运行就这样设置
/*启动摄像头*/
camera->start();
/*设置摄像头的采集帧率和分辨率*/
QCameraViewfinderSettings settings;
// settings.setPixelFormat(QVideoFrame::Format_YUYV); //设置像素格式 Android上只支持NV21格式
settings.setResolution(QSize(VIDEO_WIDTH,VIDEO_HEIGHT)); //设置摄像头的分辨率
camera->setViewfinderSettings(settings);
//获取摄像头支持的分辨率、帧率等参数
#if 0
int i=0;
QList<QCameraViewfin
没有合适的资源?快使用搜索试试~ 我知道了~
windows下ffmpeg推流桌面与摄像头数据到流媒体服务器源码.7z
共201个文件
h:120个
html:30个
png:19个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
5星 · 超过95%的资源 15 下载量 134 浏览量
2021-06-01
23:13:27
上传
评论 4
收藏 16.55MB 7Z 举报
温馨提示
这是windows下ffmpeg推流桌面与摄像头数据到流媒体服务器源码,该软件里推流和视频保存使用FFMPEG库完成,视频和音频可以同步推流和录制,FFMPEG本身支持跨平台编译开发,QT也支持跨平台,在Android、Linux、windows都运行良好,只需要在不同平台编译对应的ffmpeg库即可,逻辑代码部分通用。
资源推荐
资源详情
资源评论
收起资源包目录
windows下ffmpeg推流桌面与摄像头数据到流媒体服务器源码.7z (201个子文件)
audio_video_encode_0.cpp 20KB
widget.cpp 12KB
ffmpeg_code.cpp 10KB
Color_conversion.cpp 7KB
main.cpp 175B
bootstrap.min.css 107KB
blue.css 9KB
style.min.css 6KB
default.css 2KB
avcodec-58.dll 29.69MB
avfilter-7.dll 6.35MB
avformat-58.dll 5.62MB
avdevice-58.dll 1.25MB
avutil-56.dll 653KB
swscale-5.dll 502KB
swresample-3.dll 316KB
postproc-55.dll 114KB
ffmpeg.exe 293KB
ffprobe.exe 160KB
ffplay.exe 146KB
avcodec.h 209KB
avformat.h 116KB
avfilter.h 41KB
opt.h 35KB
pixfmt.h 33KB
frame.h 32KB
avio.h 31KB
mem.h 23KB
hwcontext.h 22KB
swresample.h 21KB
intreadwrite.h 18KB
avdevice.h 17KB
common.h 16KB
pixdesc.h 16KB
avstring.h 14KB
hdr_dynamic_metadata.h 12KB
swscale.h 12KB
imgutils.h 11KB
log.h 11KB
buffer.h 10KB
samplefmt.h 10KB
channel_layout.h 9KB
avutil.h 9KB
hash.h 8KB
dict.h 8KB
spherical.h 8KB
mathematics.h 8KB
bprint.h 8KB
parseutils.h 7KB
encryption_info.h 7KB
buffersrc.h 6KB
buffersink.h 6KB
hwcontext_d3d11va.h 6KB
xvmc.h 6KB
audio_fifo.h 6KB
fifo.h 6KB
rational.h 6KB
vdpau.h 6KB
cpu.h 6KB
error.h 5KB
tree.h 5KB
timecode.h 5KB
eval.h 5KB
stereo3d.h 5KB
version.h 5KB
attributes.h 5KB
hwcontext_drm.h 5KB
version.h 5KB
version.h 4KB
ffmpeg_code.h 4KB
dirac.h 4KB
videotoolbox.h 4KB
mastering_display_metadata.h 4KB
threadmessage.h 4KB
hwcontext_vaapi.h 4KB
qsv.h 4KB
dv_profile.h 4KB
murmur3.h 4KB
display.h 3KB
mediacodec.h 3KB
downmix_info.h 3KB
crc.h 3KB
avfft.h 3KB
postprocess.h 3KB
hmac.h 3KB
bswap.h 3KB
d3d11va.h 3KB
xtea.h 3KB
tx.h 3KB
file.h 3KB
widget.h 3KB
timestamp.h 3KB
avdct.h 3KB
cast5.h 3KB
sha512.h 3KB
sha.h 2KB
lfg.h 2KB
hwcontext_dxva2.h 2KB
blowfish.h 2KB
dxva2.h 2KB
共 201 条
- 1
- 2
- 3
DS小龙哥
- 粉丝: 4w+
- 资源: 904
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- (源码)基于SimPy和贝叶斯优化的流程仿真系统.zip
- (源码)基于Java Web的个人信息管理系统.zip
- (源码)基于C++和OTL4的PostgreSQL数据库连接系统.zip
- (源码)基于ESP32和AWS IoT Core的室内温湿度监测系统.zip
- (源码)基于Arduino的I2C协议交通灯模拟系统.zip
- coco.names 文件
- (源码)基于Spring Boot和Vue的房屋租赁管理系统.zip
- (源码)基于Android的饭店点菜系统.zip
- (源码)基于Android平台的权限管理系统.zip
- (源码)基于CC++和wxWidgets框架的LEGO模型火车控制系统.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
前往页