|
@@ -6,6 +6,18 @@ extern "C"
|
|
#include <libavutil/opt.h>
|
|
#include <libavutil/opt.h>
|
|
#include <libavutil/imgutils.h>
|
|
#include <libavutil/imgutils.h>
|
|
#include <libavutil/common.h>
|
|
#include <libavutil/common.h>
|
|
|
|
+#include "libavutil/error.h"
|
|
|
|
+#include "libavutil/hwcontext.h"
|
|
|
|
+#include "libavformat/avformat.h"
|
|
|
|
+#include "libavformat/avio.h"
|
|
|
|
+
|
|
|
|
+#ifdef USE_QSV
|
|
|
|
+#include "libavutil/hwcontext_qsv.h"
|
|
|
|
+
|
|
|
|
+#include "libavutil/hwcontext_vaapi.h"
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
#include <iostream>
|
|
#include <iostream>
|
|
@@ -42,12 +54,28 @@ QMutex gWaitMutexout;
|
|
QMutex gMutexout;
|
|
QMutex gMutexout;
|
|
int gnoutsize = 0;
|
|
int gnoutsize = 0;
|
|
|
|
|
|
-static char * gstrwidth ="1920";
|
|
|
|
-static char * gstrheight = "1080";
|
|
|
|
|
|
+static char * gstrwidth ="1280";
|
|
|
|
+static char * gstrheight = "720";
|
|
int gnwidth,gnheight;
|
|
int gnwidth,gnheight;
|
|
|
|
|
|
void * gpaout;
|
|
void * gpaout;
|
|
|
|
|
|
|
|
+#include <QFile>
|
|
|
|
+QFile gFile;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+int W = 1280;
|
|
|
|
+int H = 720;
|
|
|
|
+void yuvI420ToNV12(char *I420,int w,int h,char *NV12)
|
|
|
|
+{
|
|
|
|
+ memcpy(NV12,I420,w*h);//y分量
|
|
|
|
+ for(int i = 0,j = 0;i<w*h/4;i++,j+=2)
|
|
|
|
+ {
|
|
|
|
+ memcpy(NV12+w*h+j,I420+w*h+i,1);//u分量
|
|
|
|
+ memcpy(NV12+w*h+j+1,I420+w*h+i+w*h/4,1);//v分量
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
|
|
static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
|
|
FILE *outfile)
|
|
FILE *outfile)
|
|
{
|
|
{
|
|
@@ -75,27 +103,61 @@ static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
|
|
std::cout<<"time: "<<std::chrono::system_clock::now().time_since_epoch().count()/1000000<<std::endl;
|
|
std::cout<<"time: "<<std::chrono::system_clock::now().time_since_epoch().count()/1000000<<std::endl;
|
|
printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
|
|
printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
|
|
iv::modulecomm::ModuleSendMsg(gpaout,(char *)pkt->data,pkt->size);
|
|
iv::modulecomm::ModuleSendMsg(gpaout,(char *)pkt->data,pkt->size);
|
|
|
|
+ gFile.write((char *)pkt->data,pkt->size);
|
|
|
|
+ gFile.flush();
|
|
// fwrite(pkt->data, 1, pkt->size, outfile);
|
|
// fwrite(pkt->data, 1, pkt->size, outfile);
|
|
av_packet_unref(pkt);
|
|
av_packet_unref(pkt);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ThreadEnc()
|
|
void ThreadEnc()
|
|
{
|
|
{
|
|
- AVCodec *codec;
|
|
|
|
|
|
+ const AVCodec *codec;
|
|
AVCodecContext *c= NULL;
|
|
AVCodecContext *c= NULL;
|
|
AVFrame * frame;
|
|
AVFrame * frame;
|
|
AVPacket * pkt;
|
|
AVPacket * pkt;
|
|
|
|
|
|
char * strbuf = new char[30000000];
|
|
char * strbuf = new char[30000000];
|
|
|
|
+ char * strbufnv12 = new char[30000000];
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+#ifndef USE_QSV
|
|
|
|
+ av_register_all();
|
|
|
|
+
|
|
|
|
+ codec = avcodec_find_encoder(AV_CODEC_ID_H264);// avcodec_find_encoder_by_name("h264");
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
+#ifdef USE_QSV
|
|
|
|
+ AVBufferRef *device_ref = NULL;
|
|
|
|
+
|
|
|
|
+// av_hwdevice_ctx_init();
|
|
|
|
+ ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_QSV,"auto", NULL, 0);
|
|
|
|
+ codec = avcodec_find_encoder_by_name("h264_qsv");
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// AVCodecContext *decoder_ctx = NULL;
|
|
|
|
+// AVBufferRef *device_ref = NULL;
|
|
|
|
+
|
|
|
|
+ // av_hwdevice_ctx_init();
|
|
|
|
+// ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_QSV,"auto", NULL, 0);
|
|
|
|
+// codec = avcodec_find_encoder_by_name("libx264");
|
|
|
|
+// /* 检查下是否打开成功,失败则直接跳出去 */
|
|
|
|
+// if (ret < 0) {
|
|
|
|
+// fprintf(stderr, "Cannot open the hardware device\n");
|
|
|
|
+// return ;
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// codec = avcodec_find_encoder_by_name("h264");
|
|
|
|
|
|
- avcodec_register_all();
|
|
|
|
|
|
|
|
- codec = avcodec_find_encoder(AV_CODEC_ID_H264);// avcodec_find_encoder_by_name("h264");
|
|
|
|
|
|
|
|
if(codec == NULL)
|
|
if(codec == NULL)
|
|
{
|
|
{
|
|
@@ -115,11 +177,12 @@ void ThreadEnc()
|
|
if (!pkt)
|
|
if (!pkt)
|
|
exit(1);
|
|
exit(1);
|
|
|
|
|
|
|
|
+
|
|
/* put sample parameters */
|
|
/* put sample parameters */
|
|
c->bit_rate = 4000000;
|
|
c->bit_rate = 4000000;
|
|
/* resolution must be a multiple of two */
|
|
/* resolution must be a multiple of two */
|
|
- c->width = 1920;
|
|
|
|
- c->height = 1080;
|
|
|
|
|
|
+ c->width = 1280;
|
|
|
|
+ c->height = 720;
|
|
/* frames per second */
|
|
/* frames per second */
|
|
|
|
|
|
c->time_base = (AVRational){1, 30};
|
|
c->time_base = (AVRational){1, 30};
|
|
@@ -133,16 +196,31 @@ void ThreadEnc()
|
|
*/
|
|
*/
|
|
c->gop_size = 10;
|
|
c->gop_size = 10;
|
|
c->max_b_frames = 1;
|
|
c->max_b_frames = 1;
|
|
- c->pix_fmt = AV_PIX_FMT_YUV420P;
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // c->pix_fmt = AV_PIX_FMT_YUV420P;//
|
|
|
|
+ c->pix_fmt = AV_PIX_FMT_NV12;// AV_PIX_FMT_YUV420P;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
|
|
if (codec->id == AV_CODEC_ID_H264)
|
|
if (codec->id == AV_CODEC_ID_H264)
|
|
{
|
|
{
|
|
- av_opt_set(c->priv_data, "preset", "fast", 0);
|
|
|
|
- av_opt_set(c->priv_data, "tune", "zerolatency", 0);
|
|
|
|
|
|
+ av_opt_set(c->priv_data, "profile", "baseline", 0);
|
|
|
|
+
|
|
|
|
+#ifndef USE_QSV
|
|
|
|
+ av_opt_set(c->priv_data, "preset", "ultrafast", 0);
|
|
|
|
+#endif
|
|
|
|
+// av_opt_set(c->priv_data, "preset", "fast", 0);
|
|
|
|
+ av_opt_set(c->priv_data, "tune", "zerolatency", 0);
|
|
|
|
+// av_opt_set_int(c->priv_data, "tune", 0, 0);
|
|
|
|
+// av_opt_set_double(c->priv_data,"look_ahead",0.03,0);
|
|
|
|
+// av_opt_set(c->priv_data,"qp","qp_constant",0);
|
|
|
|
+// av_opt_set_int(c->priv_data,"rc_method",9,0);
|
|
|
|
+// av_opt_set(c->priv_data,"look_ahead_downsampling","off",0);
|
|
}
|
|
}
|
|
|
|
|
|
/* open it */
|
|
/* open it */
|
|
- int ret = avcodec_open2(c, codec, NULL);
|
|
|
|
|
|
+ ret = avcodec_open2(c, codec, NULL);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
std::cout<<"Could not open codec: "<<std::endl;
|
|
std::cout<<"Could not open codec: "<<std::endl;
|
|
// fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
|
|
// fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
|
|
@@ -185,9 +263,14 @@ void ThreadEnc()
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
exit(1);
|
|
exit(1);
|
|
|
|
|
|
- memcpy(frame->data[0],strbuf,gnwidth*gnheight);
|
|
|
|
- memcpy(frame->data[1],strbuf + gnwidth*gnheight,gnwidth*gnheight/4);
|
|
|
|
- memcpy(frame->data[2],strbuf+gnwidth*gnheight+gnwidth*gnheight/4,gnwidth*gnheight/4);
|
|
|
|
|
|
+ yuvI420ToNV12(strbuf,1280,720,strbufnv12);
|
|
|
|
+ memcpy(frame->data[0],strbufnv12,gnwidth*gnheight);
|
|
|
|
+ memcpy(frame->data[1],strbufnv12 + gnwidth*gnheight,gnwidth*gnheight*1/2);
|
|
|
|
+// memcpy(frame->data[2],strbuf+gnwidth*gnheight+gnwidth*gnheight/4,gnwidth*gnheight/4);
|
|
|
|
+
|
|
|
|
+ // memcpy(frame->data[0],strbuf,gnwidth*gnheight);
|
|
|
|
+ // memcpy(frame->data[1],strbuf + gnwidth*gnheight,gnwidth*gnheight/4);
|
|
|
|
+ // memcpy(frame->data[2],strbuf+gnwidth*gnheight+gnwidth*gnheight/4,gnwidth*gnheight/4);
|
|
|
|
|
|
frame->pts = i;i++;
|
|
frame->pts = i;i++;
|
|
|
|
|
|
@@ -225,13 +308,16 @@ void Listenpic(const char * strdata,const unsigned int nSize,const unsigned int
|
|
|
|
|
|
// qDebug("jpg");
|
|
// qDebug("jpg");
|
|
std::vector<unsigned char> buff(pic.picdata().data(),pic.picdata().data()+pic.picdata().size());
|
|
std::vector<unsigned char> buff(pic.picdata().data(),pic.picdata().data()+pic.picdata().size());
|
|
|
|
+ QTime xTime;
|
|
|
|
+ xTime.start();
|
|
mat = cv::imdecode(buff,1);
|
|
mat = cv::imdecode(buff,1);
|
|
|
|
+// std::cout<<" jpg decode time: "<<xTime.elapsed()<<std::endl;
|
|
}
|
|
}
|
|
|
|
|
|
cv::Mat dstYuvImage;
|
|
cv::Mat dstYuvImage;
|
|
QTime xTime;
|
|
QTime xTime;
|
|
xTime.start();
|
|
xTime.start();
|
|
- cv::cvtColor(mat, dstYuvImage, CV_BGR2YUV_I420);
|
|
|
|
|
|
+ cv::cvtColor(mat, dstYuvImage, CV_BGR2YUV_I420);
|
|
// std::cout<<" cvt time: "<<xTime.elapsed()<<std::endl;
|
|
// std::cout<<" cvt time: "<<xTime.elapsed()<<std::endl;
|
|
gMutexLock.lock();
|
|
gMutexLock.lock();
|
|
memcpy(gstrbuffer,(char *)dstYuvImage.data,gnwidth*gnheight*3/2);
|
|
memcpy(gstrbuffer,(char *)dstYuvImage.data,gnwidth*gnheight*3/2);
|
|
@@ -249,6 +335,9 @@ int main(int argc, char *argv[])
|
|
{
|
|
{
|
|
QCoreApplication a(argc, argv);
|
|
QCoreApplication a(argc, argv);
|
|
|
|
|
|
|
|
+ gFile.setFileName("/home/yuchuli/test1.mp4");
|
|
|
|
+ gFile.open(QIODevice::ReadWrite);
|
|
|
|
+
|
|
gstrbuffer = new char[30000000];
|
|
gstrbuffer = new char[30000000];
|
|
gstrout = new char[10000000];
|
|
gstrout = new char[10000000];
|
|
gnwidth = atoi(gstrwidth);
|
|
gnwidth = atoi(gstrwidth);
|