#include "ivh264framedecode.h" ivh264framedecode::ivh264framedecode(int framewidth,int frameheight) { mframeheight = frameheight; mframewidth = framewidth; int i; for(i=0;i lk(mmutex_cvread); if(mcvread.wait_for(lk, std::chrono::milliseconds(nwaitms)) == std::cv_status::timeout) { lk.unlock(); return -1; } lk.unlock(); if(mvectorupdateindex.size()>0)return mvectorupdateindex[0]; return -1; } iv::framedecodebuf * ivh264framedecode::LockReadBuff(int nbufindex) { if(nbufindex < 0)return NULL; if(nbufindex >= FRAMEDECBUFSIZE)return NULL; mdecbuf[nbufindex].mMutex.lock(); return &mdecbuf[nbufindex].mbuf; } void ivh264framedecode::UnlockReadBuff(int nbufindex) { mdecbuf[nbufindex].mMutex.unlock(); mmutexstate.lock(); mvectorupdateindex.erase(mvectorupdateindex.begin()); mmutexstate.unlock(); } int ivh264framedecode::GetEmptyIndex() { int i; int nindex = -1; mmutexstate.lock(); for(i=0;i= FRAMEDECBUFSIZE)return NULL; mdecbuf[nbufindex].mMutex.lock(); return &mdecbuf[nbufindex].mbuf; } void ivh264framedecode::UnlockWriteBuff(int nbufindex) { mdecbuf[nbufindex].mMutex.unlock(); mmutexstate.lock(); mvectorupdateindex.push_back(nbufindex); mmutexstate.unlock(); } void ivh264framedecode::decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt) { // char buf[1024]; int ret; ret = avcodec_send_packet(dec_ctx, pkt); if (ret < 0) { fprintf(stderr, "Error sending a packet for decoding\n"); return; } 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"); return; } 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); // cv::Mat yuvImg; // cv::Mat rgbImg(cy, cx,CV_8UC3); int index = GetEmptyIndex(); if(index < 0) { std::cout<<" no empty buffer used. "<height)||(mframewidth != frame->width)) { mframeheight = frame->height; mframewidth = frame->width; pbuf->myuvImg.create(mframeheight*3/2, mframewidth, CV_8UC1); pbuf->frameheight = mframeheight; pbuf->framewidth = mframewidth; std::cout<<"change width to : "<myuvImg.data, frame->data[0], cy*cx); memcpy(pbuf->myuvImg.data + cy*cx,frame->data[1],cy*cx/4); memcpy(pbuf->myuvImg.data + cy*cx + cy*cx/4,frame->data[2],cy*cx/4); UnlockWriteBuff(index); mcvread.notify_all(); // 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); } } #define INBUF_SIZE 4096 void ivh264framedecode::threaddecode() { const AVCodec *codec; AVCodecParserContext *parser; AVCodecContext *c= NULL; AVFrame *frame; uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; int ret; AVPacket *pkt; av_register_all(); 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); } frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "Could not allocate video frame\n"); exit(1); } // char * strbuff = new char[10000000]; // int ndatasize = 0; while (mbthreadrun) { iv::rawframedata xraw; if(mvectorrawframe.size()>0) { mmutexframe.lock(); xraw = mvectorrawframe[0]; mvectorrawframe.erase(mvectorrawframe.begin()); mmutexframe.unlock(); } else { std::unique_lock lk(mmutex_cv); if(mcv.wait_for(lk, std::chrono::milliseconds(10)) == std::cv_status::timeout) { lk.unlock(); continue; } lk.unlock(); continue; } // read_h264_frame(strbuff,ndatasize); pkt->data = (uint8_t *)xraw.mpstr_ptr.get(); pkt->size = xraw.ndatasize; if (pkt->size) { std::cout<<"decode ."<