multimedia/client/qt_gl_render/yuvgl/media/H264Docoder.cpp

101 lines
2.3 KiB
C++
Raw Normal View History

2020-05-11 15:35:53 +00:00
#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;
}