|
@@ -0,0 +1,317 @@
|
|
|
+#include <QCoreApplication>
|
|
|
+
|
|
|
+extern "C"
|
|
|
+{
|
|
|
+#include <libavcodec/avcodec.h>
|
|
|
+#include <libavutil/opt.h>
|
|
|
+#include <libavutil/imgutils.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 <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 ;
|
|
|
+#include <QWaitCondition>
|
|
|
+#include <QMutex>
|
|
|
+
|
|
|
+QWaitCondition gwc;
|
|
|
+QMutex gWaitMutex;
|
|
|
+int gndatasize;
|
|
|
+
|
|
|
+char * gstrbuffer;
|
|
|
+QMutex gMutexLock;
|
|
|
+
|
|
|
+bool gbNewOut ;
|
|
|
+QWaitCondition gwcout;
|
|
|
+char * gstrout;
|
|
|
+QMutex gWaitMutexout;
|
|
|
+QMutex gMutexout;
|
|
|
+int gnoutsize ;
|
|
|
+
|
|
|
+bool gbStartRecv = false;
|
|
|
+
|
|
|
+extern void StartDecode();
|
|
|
+
|
|
|
+#include <iostream>
|
|
|
+
|
|
|
+void ListenFrame(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
|
|
|
+{
|
|
|
+ static bool bStart = false;
|
|
|
+ if(nSize < 6)return;
|
|
|
+
|
|
|
+ if(gbStartRecv == false)return;
|
|
|
+
|
|
|
+ if(bStart == false)
|
|
|
+ {
|
|
|
+ if(strdata[4] == 0x27)
|
|
|
+ {
|
|
|
+ std::cout<<" SPS Size "<<nSize<<std::endl;
|
|
|
+ bStart = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(bStart == false)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ std::cout<<" start. "<<std::endl;
|
|
|
+ gMutexLock.lock();
|
|
|
+ memcpy(gstrbuffer,strdata,nSize);
|
|
|
+ gndatasize = nSize;
|
|
|
+ gbNewData = true;
|
|
|
+ gMutexLock.unlock();
|
|
|
+ gwc.wakeAll();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ char strout[1000];
|
|
|
+ memcpy(strout,strdata,100);
|
|
|
+ char strprint[1000];
|
|
|
+ sprintf(strprint,"%02x %02x %02x %02x %02x %02x %02x %02x",strout[0],strout[1],
|
|
|
+ strout[2],strout[3],strout[4],strout[5],strout[6],strout[7]);
|
|
|
+ std::cout<<strprint<<std::endl;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void read_h264_frame(char * strbuf, int & ndatasize)
|
|
|
+{
|
|
|
+ while(gbNewData == false)
|
|
|
+ {
|
|
|
+ gWaitMutex.lock();
|
|
|
+ gwc.wait(&gWaitMutex,10);
|
|
|
+ gWaitMutex.unlock();
|
|
|
+ }
|
|
|
+ std::cout<<"frame data. "<<std::endl;
|
|
|
+ gMutexLock.lock();
|
|
|
+ memcpy(strbuf,gstrbuffer,gndatasize);
|
|
|
+ ndatasize = gndatasize;
|
|
|
+ gbNewData = false;
|
|
|
+ gMutexLock.unlock();
|
|
|
+}
|
|
|
+
|
|
|
+#define INBUF_SIZE 4096
|
|
|
+
|
|
|
+void * gpa;
|
|
|
+
|
|
|
+static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
|
|
|
+ const char *filename)
|
|
|
+{
|
|
|
+ char buf[1024];
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = avcodec_send_packet(dec_ctx, pkt);
|
|
|
+ if (ret < 0) {
|
|
|
+ fprintf(stderr, "Error sending a packet for decoding\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ while (ret >= 0) {
|
|
|
+ ret = avcodec_receive_frame(dec_ctx, frame);
|
|
|
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
|
|
+ return;
|
|
|
+ else if (ret < 0) {
|
|
|
+ fprintf(stderr, "Error during decoding\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ printf("saving frame %3d\n", dec_ctx->frame_number);
|
|
|
+ fflush(stdout);
|
|
|
+
|
|
|
+ /* the picture is allocated by the decoder. no need to
|
|
|
+ free it */
|
|
|
+ snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
|
|
|
+
|
|
|
+ int cy = 720;
|
|
|
+ int cx = 1280;
|
|
|
+ cv::Mat yuvImg;
|
|
|
+ cv::Mat rgbImg(cy, cx,CV_8UC3);
|
|
|
+ yuvImg.create(cy*3/2, cx, CV_8UC1);
|
|
|
+ memcpy(yuvImg.data, frame->data[0], cy*cx);
|
|
|
+ memcpy(yuvImg.data + cy*cx,frame->data[1],cy*cx/4);
|
|
|
+ memcpy(yuvImg.data + cy*cx + cy*cx/4,frame->data[2],cy*cx/4);
|
|
|
+ cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_I420);
|
|
|
+
|
|
|
+ iv::vision::rawpic pic;
|
|
|
+
|
|
|
+ qint64 time = QDateTime::currentMSecsSinceEpoch();
|
|
|
+ QTime xg;
|
|
|
+ xg.start();
|
|
|
+ pic.set_time(time);
|
|
|
+ pic.set_index(0);//gindex++;
|
|
|
+
|
|
|
+
|
|
|
+ pic.set_elemsize(rgbImg.elemSize());
|
|
|
+ pic.set_width(rgbImg.cols);
|
|
|
+ pic.set_height(rgbImg.rows);
|
|
|
+ pic.set_mattype(rgbImg.type());
|
|
|
+
|
|
|
+
|
|
|
+ pic.set_picdata(rgbImg.data,rgbImg.rows*rgbImg.cols*rgbImg.elemSize());
|
|
|
+// pic.set_picdata(matcompress.data,matcompress.rows*matcompress.cols*matcompress.elemSize());
|
|
|
+ pic.set_type(1);
|
|
|
+
|
|
|
+
|
|
|
+// qDebug("buff size is %d",buff.size());
|
|
|
+
|
|
|
+
|
|
|
+ int nSize = pic.ByteSize();
|
|
|
+
|
|
|
+ char * strser = new char[nSize];
|
|
|
+ bool bser = pic.SerializeToArray(strser,nSize);
|
|
|
+ qDebug("time is %ld pac time is %d size is %d",QDateTime::currentMSecsSinceEpoch(),xg.elapsed(),nSize);
|
|
|
+
|
|
|
+// iv::modulecomm::ModuleSendMsg(gpa,str.data(),str.length());
|
|
|
+ if(bser)iv::modulecomm::ModuleSendMsg(gpa,strser,nSize);
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout<<"frame "<< "serialize error. "<<std::endl;
|
|
|
+ }
|
|
|
+ delete strser;
|
|
|
+
|
|
|
+// pgm_save(frame->data[0], frame->linesize[0],
|
|
|
+// frame->width, frame->height, buf);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int ThreadDec()
|
|
|
+{
|
|
|
+ const char *filename, *outfilename;
|
|
|
+ const AVCodec *codec;
|
|
|
+ AVCodecParserContext *parser;
|
|
|
+ AVCodecContext *c= NULL;
|
|
|
+ FILE *f;
|
|
|
+ AVFrame *frame;
|
|
|
+ uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
|
|
+ uint8_t *data;
|
|
|
+ size_t data_size;
|
|
|
+ int ret;
|
|
|
+ AVPacket *pkt;
|
|
|
+
|
|
|
+// if (argc <= 2) {
|
|
|
+// fprintf(stderr, "Usage: %s <input file> <output file>\n"
|
|
|
+// "And check your input file is encoded by mpeg1video please.\n", argv[0]);
|
|
|
+// exit(0);
|
|
|
+// }
|
|
|
+ filename = "/home/yuchuli/testr.mp4";
|
|
|
+ outfilename = "/home/yuchuli/testr.yuv";
|
|
|
+
|
|
|
+ pkt = av_packet_alloc();
|
|
|
+ if (!pkt)
|
|
|
+ exit(1);
|
|
|
+
|
|
|
+ /* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
|
|
|
+ memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
|
|
+
|
|
|
+ /* find the MPEG-1 video decoder */
|
|
|
+ codec = avcodec_find_decoder(AV_CODEC_ID_H264);
|
|
|
+ if (!codec) {
|
|
|
+ fprintf(stderr, "Codec not found\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ parser = av_parser_init(codec->id);
|
|
|
+ if (!parser) {
|
|
|
+ fprintf(stderr, "parser not found\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ c = avcodec_alloc_context3(codec);
|
|
|
+ if (!c) {
|
|
|
+ fprintf(stderr, "Could not allocate video codec context\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* For some codecs, such as msmpeg4 and mpeg4, width and height
|
|
|
+ MUST be initialized there because this information is not
|
|
|
+ available in the bitstream. */
|
|
|
+
|
|
|
+ /* open it */
|
|
|
+ if (avcodec_open2(c, codec, NULL) < 0) {
|
|
|
+ fprintf(stderr, "Could not open codec\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ f = fopen(filename, "rb");
|
|
|
+ if (!f) {
|
|
|
+ fprintf(stderr, "Could not open %s\n", filename);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ frame = av_frame_alloc();
|
|
|
+ if (!frame) {
|
|
|
+ fprintf(stderr, "Could not allocate video frame\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ char * strbuff = new char[10000000];
|
|
|
+ int ndatasize = 0;
|
|
|
+ gbStartRecv = true;
|
|
|
+ while (1) {
|
|
|
+
|
|
|
+ read_h264_frame(strbuff,ndatasize);
|
|
|
+ pkt->data = (uint8_t *)strbuff;
|
|
|
+ pkt->size = ndatasize;
|
|
|
+ if (pkt->size)
|
|
|
+ {
|
|
|
+ std::cout<<"decode ."<<std::endl;
|
|
|
+ decode(c, frame, pkt, outfilename);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /* flush the decoder */
|
|
|
+// decode(c, frame, NULL, outfilename);
|
|
|
+
|
|
|
+ fclose(f);
|
|
|
+
|
|
|
+ av_parser_close(parser);
|
|
|
+ avcodec_free_context(&c);
|
|
|
+ av_frame_free(&frame);
|
|
|
+ av_packet_free(&pkt);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int main(int argc, char *argv[])
|
|
|
+{
|
|
|
+ QCoreApplication a(argc, argv);
|
|
|
+
|
|
|
+ gpa = iv::modulecomm::RegisterSend("h264pic",20000000,1);
|
|
|
+ gstrbuffer = new char[1000000];
|
|
|
+ gstrout = new char[30000000];
|
|
|
+ iv::modulecomm::RegisterRecv("h264frame",ListenFrame);
|
|
|
+
|
|
|
+ std::thread * decthread = new std::thread(ThreadDec);
|
|
|
+
|
|
|
+ return a.exec();
|
|
|
+}
|