101 lines
2.3 KiB
C++
101 lines
2.3 KiB
C++
|
#include "H264Docoder.h"
|
|||
|
#include "Debuger.h"
|
|||
|
extern "C" {
|
|||
|
#include "libswscale/swscale.h"
|
|||
|
#include "libavformat/avformat.h"
|
|||
|
#include "libavcodec/avcodec.h"
|
|||
|
#include "libswscale/swscale.h"
|
|||
|
#include "libavutil/pixfmt.h"
|
|||
|
}
|
|||
|
|
|||
|
H264decoder::H264decoder()
|
|||
|
:mObserver(nullptr){
|
|||
|
this->mObserverType = Observer_Video;
|
|||
|
avcodec_register_all();
|
|||
|
mCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
|
|||
|
if (!mCodec) {
|
|||
|
cout << "could not found 264 decoder" << endl;
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
mCtx = avcodec_alloc_context3(mCodec);
|
|||
|
picture = av_frame_alloc();
|
|||
|
if ((mCodec->capabilities)&AV_CODEC_CAP_TRUNCATED)
|
|||
|
(mCtx->flags) |= AV_CODEC_FLAG2_CHUNKS;
|
|||
|
mCtx->height = 720;
|
|||
|
mCtx->width = 1280;
|
|||
|
if (avcodec_open2(mCtx, mCodec, NULL) < 0) {
|
|||
|
cout << "could not open codec\n";
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
H264decoder::~H264decoder()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
//
|
|||
|
// Created by 29019 on 2019/5/7.
|
|||
|
//
|
|||
|
const int width = 640;
|
|||
|
const int height = 480;
|
|||
|
const int framesize = width * height * 3 / 2; //һ<><D2BB>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD>
|
|||
|
|
|||
|
VData *H264decoder::Decodes(void *dat,uint32_t size) {
|
|||
|
//FILE *pOut = fopen("pic.yuv","wb+");
|
|||
|
AVPacket pkt;
|
|||
|
int got_picture = 0;
|
|||
|
int len = 0;
|
|||
|
|
|||
|
picture = av_frame_alloc();
|
|||
|
av_init_packet(&pkt);
|
|||
|
|
|||
|
char* data = (char*)dat;
|
|||
|
pkt.data = (uint8_t *)data;
|
|||
|
pkt.size = size;
|
|||
|
|
|||
|
len = avcodec_decode_video2(this->mCtx, picture, &got_picture, &pkt);
|
|||
|
if (len < 0) {
|
|||
|
printf("Error while decoding a frame.\n");
|
|||
|
return nullptr;
|
|||
|
}
|
|||
|
if (got_picture == 0) {
|
|||
|
return nullptr;
|
|||
|
}
|
|||
|
++frame;
|
|||
|
AVPixelFormat pix;
|
|||
|
int pic_size = avpicture_get_size(AV_PIX_FMT_YUVJ420P, picture->width, picture->height);
|
|||
|
/*
|
|||
|
cout << "receive width " << picture->width << " height "
|
|||
|
<< picture->height<<"pic size "
|
|||
|
<< pic_size <<" channel layout "
|
|||
|
<< picture->linesize[0]<< endl;*/
|
|||
|
|
|||
|
uint32_t pitchY = picture->linesize[0];
|
|||
|
uint32_t pitchU = picture->linesize[1];
|
|||
|
uint32_t pitchV = picture->linesize[2];
|
|||
|
|
|||
|
uint8_t *avY = picture->data[0];
|
|||
|
uint8_t *avU = picture->data[1];
|
|||
|
uint8_t *avV = picture->data[2];
|
|||
|
if (nullptr != mObserver) {
|
|||
|
this->mObserver->OnRecieveData(picture);
|
|||
|
}
|
|||
|
av_frame_free(&picture);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void H264decoder::OnRtmpFrame(void * dat, uint32_t size)
|
|||
|
{
|
|||
|
//Debuger::Debug(L"get data\r\n");
|
|||
|
this->Decodes(dat, size);
|
|||
|
}
|
|||
|
|
|||
|
int H264decoder::SetObserver(H264DecodeObserver *p)
|
|||
|
{
|
|||
|
if (nullptr != p)
|
|||
|
this->mObserver = p;
|
|||
|
else
|
|||
|
return -1;
|
|||
|
return 0;
|
|||
|
}
|