完成推流功能
parent
b385c4dd8b
commit
df2d86b055
|
@ -6,7 +6,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>431</width>
|
<width>932</width>
|
||||||
<height>59</height>
|
<height>59</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -15,23 +15,5 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
MainWindow main;
|
MainWindow main;
|
||||||
main.show();
|
main.show();
|
||||||
/*
|
|
||||||
CPlayWidget gPlayer(nullptr);
|
|
||||||
gPlayer.SetDataType(CPlayWidget::IMG_TYPE::TYPE_RGB32);
|
|
||||||
gPlayer.SetImgSize(640,480);
|
|
||||||
gPlayer.show();
|
|
||||||
Camera *gCam;
|
|
||||||
std::vector<std::wstring> names = Camera::EnumAllCamera();
|
|
||||||
for(auto itr = names.begin();itr != names.end();itr++){
|
|
||||||
if(gCam->Open(*names.begin()) ){
|
|
||||||
Camera *gCam = new Camera(*names.begin());
|
|
||||||
gCam->SetObserver(&gPlayer);
|
|
||||||
qDebug("open success");
|
|
||||||
}else{
|
|
||||||
qDebug("open fail");
|
|
||||||
}
|
|
||||||
qDebug()<<QString::fromStdWString(*itr);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,10 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
ui(new Ui::MainWindow),
|
ui(new Ui::MainWindow),
|
||||||
m_bCameraOpen(false),
|
m_bCameraOpen(false),
|
||||||
mCamera(nullptr),
|
mCamera(nullptr),
|
||||||
m_bRtmpPushing(false)
|
m_bRtmpPushing(false),
|
||||||
|
mPlayerWidget(nullptr),
|
||||||
|
mVideoCoder(nullptr),
|
||||||
|
mPusher(nullptr)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
std::vector<std::wstring> cameras = Camera::EnumAllCamera();
|
std::vector<std::wstring> cameras = Camera::EnumAllCamera();
|
||||||
|
@ -14,6 +17,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
ui->comboBox->addItem(QString::fromWCharArray(x.c_str(),x.size()),
|
ui->comboBox->addItem(QString::fromWCharArray(x.c_str(),x.size()),
|
||||||
QString::fromWCharArray(x.c_str(),x.size()));
|
QString::fromWCharArray(x.c_str(),x.size()));
|
||||||
}
|
}
|
||||||
|
mPusher = new H264RtmpPuser();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow(){
|
MainWindow::~MainWindow(){
|
||||||
|
@ -23,7 +27,6 @@ MainWindow::~MainWindow(){
|
||||||
void MainWindow::on_pushButton_clicked(){
|
void MainWindow::on_pushButton_clicked(){
|
||||||
if(nullptr == mPlayerWidget){
|
if(nullptr == mPlayerWidget){
|
||||||
mPlayerWidget = new CPlayWidget(nullptr);
|
mPlayerWidget = new CPlayWidget(nullptr);
|
||||||
//mVideoCoder = new VideoCoder(mCamera->GetWidth(),mCamera->GetHeight(),);
|
|
||||||
}
|
}
|
||||||
if(!m_bCameraOpen){
|
if(!m_bCameraOpen){
|
||||||
mPlayerWidget->SetDataType(CPlayWidget::IMG_TYPE::TYPE_RGB32);
|
mPlayerWidget->SetDataType(CPlayWidget::IMG_TYPE::TYPE_RGB32);
|
||||||
|
@ -36,7 +39,7 @@ void MainWindow::on_pushButton_clicked(){
|
||||||
if(nullptr == mCamera){
|
if(nullptr == mCamera){
|
||||||
this->mCamera = new Camera(ss);
|
this->mCamera = new Camera(ss);
|
||||||
}
|
}
|
||||||
this->mCamera->SetObserver(mPlayerWidget);
|
//this->mCamera->SetObserver(mPlayerWidget);
|
||||||
qDebug()<<ui->comboBox->currentText();
|
qDebug()<<ui->comboBox->currentText();
|
||||||
ui->pushButton->setText("关闭摄像头");
|
ui->pushButton->setText("关闭摄像头");
|
||||||
m_bCameraOpen = true;
|
m_bCameraOpen = true;
|
||||||
|
@ -52,6 +55,33 @@ void MainWindow::on_pushButton_2_clicked()
|
||||||
if(!m_bRtmpPushing){
|
if(!m_bRtmpPushing){
|
||||||
if(!m_bCameraOpen){
|
if(!m_bCameraOpen){
|
||||||
ToastWidget::showTip("请打开摄像头",this);
|
ToastWidget::showTip("请打开摄像头",this);
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
//
|
||||||
|
if(nullptr == mVideoCoder){
|
||||||
|
mVideoCoder = new VideoCoder(mCamera->GetWidth(),
|
||||||
|
mCamera->GetHeight(),
|
||||||
|
GUIDToAvFormat(mCamera->MediaType()));
|
||||||
|
}
|
||||||
|
mCamera->SetObserver(mVideoCoder);
|
||||||
|
|
||||||
|
// todo 根据返回结果判断是否推流
|
||||||
|
if (!mPusher->IfConnect()) {
|
||||||
|
if (0 == mPusher->RTMP264_Connect(ui->lineEdit->text().toStdString().c_str())) {
|
||||||
|
ToastWidget::showTip("已经连接上RTMP服务器",this);
|
||||||
|
mVideoCoder->SetOberver(mPusher);
|
||||||
|
mPusher->StartPush();
|
||||||
|
/*
|
||||||
|
if (nullptr != this->mAudioCoder) {
|
||||||
|
this->mAudioCoder->SetObserver(mPusher);
|
||||||
|
//音频流先不推流
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ToastWidget::showTip("连接RTMP服务器失败,请检查服务器地址",this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
#include "media/CameraCapture.h"
|
#include "media/CameraCapture.h"
|
||||||
#include "cplaywidget.h"
|
#include "cplaywidget.h"
|
||||||
#include "media/VideoCoder.h"
|
#include "media/VideoCoder.h"
|
||||||
#include "media/RtmpPuser.h"
|
#include "media/RtmpPusher.h"
|
||||||
#include "components/toast.h"
|
#include "components/toast.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "media/RtmpPusher.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
|
@ -33,7 +35,7 @@ private:
|
||||||
CPlayWidget *mPlayerWidget;
|
CPlayWidget *mPlayerWidget;
|
||||||
VideoCoder *mVideoCoder;
|
VideoCoder *mVideoCoder;
|
||||||
bool m_bRtmpPushing;
|
bool m_bRtmpPushing;
|
||||||
|
H264RtmpPuser *mPusher;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|
|
@ -94,7 +94,7 @@
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>rtmp://</string>
|
<string>rtmp://192.168.3.21:1935/live</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -28,6 +28,11 @@ Camera::Camera():
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GUID Camera::MediaType()
|
||||||
|
{
|
||||||
|
return mMediaType;
|
||||||
|
}
|
||||||
|
|
||||||
Camera::Camera(wstring camera)
|
Camera::Camera(wstring camera)
|
||||||
{
|
{
|
||||||
mInitOK = false;
|
mInitOK = false;
|
||||||
|
@ -409,15 +414,12 @@ HRESULT STDMETHODCALLTYPE Camera::SampleGrabberCallback::BufferCB(double Time, B
|
||||||
fflush(p);
|
fflush(p);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mNewDataCallBack)
|
|
||||||
{
|
|
||||||
mNewDataCallBack(Time, pBuffer, BufferLen);
|
|
||||||
}
|
|
||||||
if (mObserver.size() > 0) {
|
if (mObserver.size() > 0) {
|
||||||
mMux.lock();
|
mMux.lock();
|
||||||
for (auto itr = this->mObserver.begin(); itr != mObserver.end(); itr++) {
|
for (auto itr = this->mObserver.begin(); itr != mObserver.end(); itr++) {
|
||||||
CameraObserver *p = (CameraObserver *)*itr;
|
CameraObserver *p = (CameraObserver *)*itr;
|
||||||
p->OnCameraData(pBuffer, BufferLen);
|
p->OnCameraData(pBuffer, BufferLen);
|
||||||
}
|
}
|
||||||
mMux.unlock();
|
mMux.unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,5 +83,7 @@ public:
|
||||||
int GetHeight() { return mVideoHeight; }
|
int GetHeight() { return mVideoHeight; }
|
||||||
int GetWidth() { return mVideoWidth; }
|
int GetWidth() { return mVideoWidth; }
|
||||||
int GetBitDepth() { return mBitDepth; }
|
int GetBitDepth() { return mBitDepth; }
|
||||||
|
GUID MediaType();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
#include "VideoCoder.h"
|
||||||
#include "VideoCoder.h"
|
|
||||||
#include "Debuger.h"
|
#include "Debuger.h"
|
||||||
FILE *p = nullptr;
|
FILE *p = nullptr;
|
||||||
int VideoCoder::OnBuffer(double dblSampleTime, BYTE * pBuffer, long lBufferSize)
|
int VideoCoder::OnBuffer(double dblSampleTime, BYTE * pBuffer, long lBufferSize)
|
||||||
|
@ -10,21 +9,26 @@ int VideoCoder::OnBuffer(double dblSampleTime, BYTE * pBuffer, long lBufferSize)
|
||||||
|
|
||||||
int VideoCoder::OnCameraData(uint8_t * dat, uint32_t size)
|
int VideoCoder::OnCameraData(uint8_t * dat, uint32_t size)
|
||||||
{
|
{
|
||||||
this->Encode(dat, size, AV_PIX_FMT_YUV420P);
|
//std::cout<<"captrue data and into coder"<<std::endl;
|
||||||
|
this->Encode(dat, size, AV_PIX_FMT_YUV420P);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VideoCoder::SetDestPix(uint8_t width, uint8_t height)
|
int VideoCoder::SetDestPix(uint8_t width, uint8_t height) {
|
||||||
{
|
|
||||||
this->mDestHeight = height;
|
this->mDestHeight = height;
|
||||||
this->mDestWidth = width;
|
this->mDestWidth = width;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoCoder::VideoCoder(int width, int height, AVPixelFormat formt)
|
VideoCoder::VideoCoder(int width, int height, AVPixelFormat formt):
|
||||||
:mObserver(nullptr),mFrame(nullptr), mPitureBuffer(nullptr), mFormatCtx(nullptr), mOutputFmt(nullptr),
|
mObserver(nullptr),
|
||||||
mVideoStream(nullptr), mCodecCtx(nullptr), mCodec(nullptr)
|
mFrame(nullptr),
|
||||||
{
|
mPitureBuffer(nullptr),
|
||||||
|
mFormatCtx(nullptr),
|
||||||
|
mOutputFmt(nullptr),
|
||||||
|
mVideoStream(nullptr),
|
||||||
|
mCodecCtx(nullptr),
|
||||||
|
mCodec(nullptr) {
|
||||||
AVCodecID codec_id = AV_CODEC_ID_H264;
|
AVCodecID codec_id = AV_CODEC_ID_H264;
|
||||||
mCodec = avcodec_find_encoder(codec_id);
|
mCodec = avcodec_find_encoder(codec_id);
|
||||||
|
|
||||||
|
@ -89,8 +93,7 @@ VideoCoder::~VideoCoder()
|
||||||
fclose(p);
|
fclose(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoCoder::Encode(uint8_t * src, int size, enum AVPixelFormat format)
|
void VideoCoder::Encode(uint8_t * src, int size, enum AVPixelFormat format) {
|
||||||
{
|
|
||||||
uint8_t *pFrame[4];
|
uint8_t *pFrame[4];
|
||||||
int lineSize[4];
|
int lineSize[4];
|
||||||
static int debugs = 1;
|
static int debugs = 1;
|
||||||
|
@ -128,8 +131,8 @@ void VideoCoder::Encode(uint8_t * src, int size, enum AVPixelFormat format)
|
||||||
this->mObserver->OnGetCodeFrame(mAVPack.data, mAVPack.size);
|
this->mObserver->OnGetCodeFrame(mAVPack.data, mAVPack.size);
|
||||||
}
|
}
|
||||||
//Debuger::Debug(L"Succeed to encode frame: %5d\tsize:%5d\n", 1, mAVPack.size);
|
//Debuger::Debug(L"Succeed to encode frame: %5d\tsize:%5d\n", 1, mAVPack.size);
|
||||||
//fwrite(mAVPack.data, 1, mAVPack.size, p);
|
fwrite(mAVPack.data, 1, mAVPack.size, p);
|
||||||
//fflush(p);
|
fflush(p);
|
||||||
// 刷新coder,防止包挤压
|
// 刷新coder,防止包挤压
|
||||||
av_packet_unref(&mAVPack);
|
av_packet_unref(&mAVPack);
|
||||||
av_freep(&pFrame[0]);
|
av_freep(&pFrame[0]);
|
||||||
|
@ -144,8 +147,7 @@ void VideoCoder::SetOutPutPixel(unsigned int width, unsigned int height)
|
||||||
this->mWidth = width;
|
this->mWidth = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VideoCoder::flushCoder(AVFormatContext *fmt_ctx, unsigned int stream_index)
|
int VideoCoder::flushCoder(AVFormatContext *fmt_ctx, unsigned int stream_index) {
|
||||||
{
|
|
||||||
int ret;
|
int ret;
|
||||||
int got_frame;
|
int got_frame;
|
||||||
AVPacket enc_pkt;
|
AVPacket enc_pkt;
|
||||||
|
@ -260,7 +262,7 @@ int VideoCoder::forceYUV420P(uint8_t * src, int size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 转换数据
|
// 转换数据
|
||||||
ret = sws_scale(img_convert_ctx, src_data, src_linesize, 0, mHeight, dst_data, dst_linesize);
|
ret = sws_scale(img_convert_ctx, src_data, src_linesize, 0, mHeight, dst_data, dst_linesize);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ extern "C"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
};
|
};
|
||||||
|
#include <iostream>
|
||||||
#else
|
#else
|
||||||
//Linux...
|
//Linux...
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 4.11.0, 2020-05-31T13:34:59. -->
|
<!-- Written by QtCreator 4.11.0, 2020-06-02T21:30:15. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|
Loading…
Reference in New Issue