|
@@ -0,0 +1,247 @@
|
|
|
+#include <QCoreApplication>
|
|
|
+
|
|
|
+extern "C"
|
|
|
+{
|
|
|
+#include <libavcodec/avcodec.h>
|
|
|
+#include <libavutil/opt.h>
|
|
|
+#include <libavutil/imgutils.h>
|
|
|
+#include <libavutil/common.h>
|
|
|
+}
|
|
|
+
|
|
|
+#include <iostream>
|
|
|
+#include <thread>
|
|
|
+
|
|
|
+#include "modulecomm.h"
|
|
|
+
|
|
|
+#include <opencv2/opencv.hpp>
|
|
|
+#include <opencv2/core.hpp>
|
|
|
+
|
|
|
+#include <opencv2/imgproc.hpp>
|
|
|
+
|
|
|
+//#include "opencv2/imgcodecs/legacy/constants_c.h"
|
|
|
+#include <opencv2/imgproc/types_c.h>
|
|
|
+
|
|
|
+#include "rawpic.pb.h"
|
|
|
+
|
|
|
+bool gbNewData = false;
|
|
|
+#include <QWaitCondition>
|
|
|
+#include <QMutex>
|
|
|
+
|
|
|
+QWaitCondition gwc;
|
|
|
+static QMutex gWaitMutex;
|
|
|
+static int gndatasize = 0;
|
|
|
+
|
|
|
+char * gstrbuffer;
|
|
|
+QMutex gMutexLock;
|
|
|
+
|
|
|
+bool gbNewOut = false;
|
|
|
+QWaitCondition gwcout;
|
|
|
+char * gstrout;
|
|
|
+QMutex gWaitMutexout;
|
|
|
+QMutex gMutexout;
|
|
|
+int gnoutsize = 0;
|
|
|
+
|
|
|
+static char * gstrwidth ="1920";
|
|
|
+static char * gstrheight = "1080";
|
|
|
+int gnwidth,gnheight;
|
|
|
+
|
|
|
+static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
|
|
|
+ FILE *outfile)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ /* send the frame to the encoder */
|
|
|
+ if (frame)
|
|
|
+ printf("Send frame %3"PRId64"\n", frame->pts);
|
|
|
+
|
|
|
+ ret = avcodec_send_frame(enc_ctx, frame);
|
|
|
+ if (ret < 0) {
|
|
|
+ fprintf(stderr, "Error sending a frame for encoding\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ while (ret >= 0) {
|
|
|
+ ret = avcodec_receive_packet(enc_ctx, pkt);
|
|
|
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
|
|
+ return;
|
|
|
+ else if (ret < 0) {
|
|
|
+ fprintf(stderr, "Error during encoding\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
|
|
|
+// fwrite(pkt->data, 1, pkt->size, outfile);
|
|
|
+ av_packet_unref(pkt);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+void ThreadEnc()
|
|
|
+{
|
|
|
+ AVCodec *codec;
|
|
|
+ AVCodecContext *c= NULL;
|
|
|
+ AVFrame * frame;
|
|
|
+ AVPacket * pkt;
|
|
|
+
|
|
|
+ char * strbuf = new char[30000000];
|
|
|
+
|
|
|
+ avcodec_register_all();
|
|
|
+ codec = avcodec_find_encoder(AV_CODEC_ID_H264);// avcodec_find_encoder_by_name("h264");
|
|
|
+
|
|
|
+ if(codec == NULL)
|
|
|
+ {
|
|
|
+ std::cout<<" codec NULL"<<std::endl;
|
|
|
+ int a = 1;
|
|
|
+ a++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout<<"codec ok."<<std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ c = avcodec_alloc_context3(codec);
|
|
|
+
|
|
|
+ if(c == NULL)std::cout<<"c NULL ."<<std::endl;
|
|
|
+ pkt = av_packet_alloc();
|
|
|
+ if (!pkt)
|
|
|
+ exit(1);
|
|
|
+
|
|
|
+ /* put sample parameters */
|
|
|
+ c->bit_rate = 4000000;
|
|
|
+ /* resolution must be a multiple of two */
|
|
|
+ c->width = 1920;
|
|
|
+ c->height = 1080;
|
|
|
+ /* frames per second */
|
|
|
+
|
|
|
+ c->time_base = (AVRational){1, 30};
|
|
|
+ c->framerate = (AVRational){30, 1};
|
|
|
+
|
|
|
+ /* emit one intra frame every ten frames
|
|
|
+ * check frame pict_type before passing frame
|
|
|
+ * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
|
|
|
+ * then gop_size is ignored and the output of encoder
|
|
|
+ * will always be I frame irrespective to gop_size
|
|
|
+ */
|
|
|
+ c->gop_size = 10;
|
|
|
+ c->max_b_frames = 1;
|
|
|
+ c->pix_fmt = AV_PIX_FMT_YUV420P;
|
|
|
+
|
|
|
+ if (codec->id == AV_CODEC_ID_H264)
|
|
|
+ av_opt_set(c->priv_data, "preset", "slow", 0);
|
|
|
+
|
|
|
+ /* open it */
|
|
|
+ int ret = avcodec_open2(c, codec, NULL);
|
|
|
+ if (ret < 0) {
|
|
|
+ std::cout<<"Could not open codec: "<<std::endl;
|
|
|
+ // fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ frame = av_frame_alloc();
|
|
|
+ if (!frame) {
|
|
|
+ fprintf(stderr, "Could not allocate video frame\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ frame->format = c->pix_fmt;
|
|
|
+ frame->width = c->width;
|
|
|
+ frame->height = c->height;
|
|
|
+
|
|
|
+ ret = av_frame_get_buffer(frame, 0);
|
|
|
+ if (ret < 0) {
|
|
|
+ fprintf(stderr, "Could not allocate the video frame data\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ std::cout<<"start enc."<<std::endl;
|
|
|
+
|
|
|
+ int i = 0;
|
|
|
+ while(1)
|
|
|
+ {
|
|
|
+ if(gbNewData == false)
|
|
|
+ {
|
|
|
+ gWaitMutex.lock();
|
|
|
+ gwc.wait(&gWaitMutex,10);
|
|
|
+ gWaitMutex.unlock();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ gMutexLock.lock();
|
|
|
+ memcpy(strbuf,gstrbuffer,gnwidth*gnheight*3/2);
|
|
|
+ gbNewData = false;
|
|
|
+ gMutexLock.unlock();
|
|
|
+ ret = av_frame_make_writable(frame);
|
|
|
+ if (ret < 0)
|
|
|
+ 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);
|
|
|
+
|
|
|
+ frame->pts = i;i++;
|
|
|
+
|
|
|
+ /* encode the image */
|
|
|
+ QTime xTime;
|
|
|
+ xTime.start();
|
|
|
+ encode(c, frame, pkt, NULL);
|
|
|
+ std::cout<<"encode time : "<<xTime.elapsed()<<std::endl;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void Listenpic(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
|
|
|
+{
|
|
|
+ if(nSize<1000)return;
|
|
|
+ iv::vision::rawpic pic;
|
|
|
+ std::cout<<"rec. "<<std::endl;
|
|
|
+ if(false == pic.ParseFromArray(strdata,nSize))
|
|
|
+ {
|
|
|
+ std::cout<<"picview Listenpic fail."<<std::endl;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ cv::Mat mat(pic.height(),pic.width(),pic.mattype());
|
|
|
+
|
|
|
+ if(pic.type() == 1)
|
|
|
+ memcpy(mat.data,pic.picdata().data(),mat.rows*mat.cols*mat.elemSize());
|
|
|
+ else
|
|
|
+ {
|
|
|
+
|
|
|
+ // qDebug("jpg");
|
|
|
+ std::vector<unsigned char> buff(pic.picdata().data(),pic.picdata().data()+pic.picdata().size());
|
|
|
+ mat = cv::imdecode(buff,1);
|
|
|
+ }
|
|
|
+
|
|
|
+ cv::Mat dstYuvImage;
|
|
|
+ QTime xTime;
|
|
|
+ xTime.start();
|
|
|
+ cv::cvtColor(mat, dstYuvImage, CV_BGR2YUV_I420);
|
|
|
+ std::cout<<" cvt time: "<<xTime.elapsed()<<std::endl;
|
|
|
+ gMutexLock.lock();
|
|
|
+ memcpy(gstrbuffer,(char *)dstYuvImage.data,gnwidth*gnheight*3/2);
|
|
|
+ gbNewData = true;
|
|
|
+ gMutexLock.unlock();
|
|
|
+ gwc.wakeAll();
|
|
|
+// xFileYUV.write((char *)dstYuvImage.data,gwidth*gheight*3/2);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int main(int argc, char *argv[])
|
|
|
+{
|
|
|
+ QCoreApplication a(argc, argv);
|
|
|
+
|
|
|
+ gstrbuffer = new char[30000000];
|
|
|
+ gstrout = new char[10000000];
|
|
|
+ gnwidth = atoi(gstrwidth);
|
|
|
+ gnheight = atoi(gstrheight);
|
|
|
+
|
|
|
+ void * pa = iv::modulecomm::RegisterRecv("picfront",Listenpic);
|
|
|
+ std::thread * pthreadenc = new std::thread(ThreadEnc);
|
|
|
+ return a.exec();
|
|
|
+}
|