fixed some bugs. Still crashing in the decoding phase. Don_t know why.

This commit is contained in:
csoler 2015-08-23 10:27:50 -04:00
parent 4522fe85cc
commit 0bb5a74099

View file

@ -12,6 +12,7 @@
#include <math.h> #include <math.h>
extern "C" { extern "C" {
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
@ -136,14 +137,14 @@ void VideoProcessor::receiveEncodedData(const RsVOIPDataChunk& chunk)
return ; return ;
} }
// if(!codec->decodeData(chunk,img)) if(!codec->decodeData(chunk,img))
// { {
// std::cerr << "No image decoded. Probably in the middle of something..." << std::endl; std::cerr << "No image decoded. Probably in the middle of something..." << std::endl;
// return ; return ;
// } }
//
// if(_decoded_output_device) if(_decoded_output_device)
// _decoded_output_device->showFrame(img) ; _decoded_output_device->showFrame(img) ;
} }
void VideoProcessor::setMaximumFrameRate(uint32_t bytes_per_sec) void VideoProcessor::setMaximumFrameRate(uint32_t bytes_per_sec)
@ -509,7 +510,6 @@ FFmpegVideo::FFmpegVideo()
encoding_context = avcodec_alloc_context3(encoding_codec); encoding_context = avcodec_alloc_context3(encoding_codec);
if (!encoding_context) throw std::runtime_error("AV: Could not allocate video codec encoding context"); if (!encoding_context) throw std::runtime_error("AV: Could not allocate video codec encoding context");
if (!decoding_context) throw std::runtime_error("AV: Could not allocate video codec decoding context");
/* put sample parameters */ /* put sample parameters */
encoding_context->bit_rate = 400000; encoding_context->bit_rate = 400000;
@ -554,23 +554,32 @@ FFmpegVideo::FFmpegVideo()
// Decoding // Decoding
decoding_frame_buffer = avcodec_alloc_frame() ;//(AVFrame*)malloc(sizeof(AVFrame)) ;
decoding_codec = avcodec_find_decoder(codec_id); decoding_codec = avcodec_find_decoder(codec_id);
if (!decoding_codec) if (!decoding_codec)
throw("AV codec not found for codec id ") ; throw("AV codec not found for codec id ") ;
decoding_context = avcodec_alloc_context3(decoding_codec); decoding_context = avcodec_alloc_context3(decoding_codec);
if(!decoding_context)
throw std::runtime_error("AV: Could not allocate video codec decoding context");
decoding_context->width = encoding_context->width; decoding_context->width = encoding_context->width;
decoding_context->height = encoding_context->height; decoding_context->height = encoding_context->height;
decoding_context->pix_fmt = AV_PIX_FMT_YUV420P; decoding_context->pix_fmt = AV_PIX_FMT_YUV420P;
// if (decoding_codec->capabilities & AV_CODEC_CAP_TRUNCATED) if(decoding_codec->capabilities & CODEC_CAP_TRUNCATED)
// decoding_context->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames decoding_context->flags |= CODEC_FLAG_TRUNCATED; // we do not send complete frames
if(avcodec_open2(decoding_context,decoding_codec,NULL) < 0) if(avcodec_open2(decoding_context,decoding_codec,NULL) < 0)
throw("AV codec open action failed! ") ; throw("AV codec open action failed! ") ;
decoding_frame_buffer = avcodec_alloc_frame() ;//(AVFrame*)malloc(sizeof(AVFrame)) ;
//ret = av_image_alloc(decoding_frame_buffer->data, decoding_frame_buffer->linesize, decoding_context->width, decoding_context->height, decoding_context->pix_fmt, 32);
//if (ret < 0)
//throw std::runtime_error("AV: Could not allocate raw picture buffer");
// debug // debug
#ifdef DEBUG_MPEG_VIDEO #ifdef DEBUG_MPEG_VIDEO
std::cerr << "Dumping captured data to file tmpvideo.mpg" << std::endl; std::cerr << "Dumping captured data to file tmpvideo.mpg" << std::endl;
@ -593,11 +602,6 @@ FFmpegVideo::~FFmpegVideo()
bool FFmpegVideo::encodeData(const QImage& image,uint32_t size_hint,RsVOIPDataChunk& voip_chunk) bool FFmpegVideo::encodeData(const QImage& image,uint32_t size_hint,RsVOIPDataChunk& voip_chunk)
{ {
AVPacket pkt ;
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;
std::cerr << "Encoding frame of size " << image.width() << "x" << image.height() << ", resized to " << encoding_frame_buffer->width << "x" << encoding_frame_buffer->height << std::endl; std::cerr << "Encoding frame of size " << image.width() << "x" << image.height() << ", resized to " << encoding_frame_buffer->width << "x" << encoding_frame_buffer->height << std::endl;
QImage input ; QImage input ;
@ -635,6 +639,11 @@ bool FFmpegVideo::encodeData(const QImage& image,uint32_t size_hint,RsVOIPDataCh
AVFrame *frame = encoding_frame_buffer ; AVFrame *frame = encoding_frame_buffer ;
AVPacket pkt ;
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;
// do // do
// { // {
int ret = avcodec_encode_video2(encoding_context, &pkt, frame, &got_output) ; int ret = avcodec_encode_video2(encoding_context, &pkt, frame, &got_output) ;
@ -668,6 +677,7 @@ bool FFmpegVideo::encodeData(const QImage& image,uint32_t size_hint,RsVOIPDataCh
fwrite(pkt.data,1,pkt.size,encoding_debug_file) ; fwrite(pkt.data,1,pkt.size,encoding_debug_file) ;
fflush(encoding_debug_file) ; fflush(encoding_debug_file) ;
#endif #endif
av_free_packet(&pkt);
} }
else else
{ {
@ -678,31 +688,41 @@ bool FFmpegVideo::encodeData(const QImage& image,uint32_t size_hint,RsVOIPDataCh
std::cerr << "No output produced." << std::endl; std::cerr << "No output produced." << std::endl;
} }
av_free_packet(&pkt);
return true ; return true ;
} }
bool FFmpegVideo::decodeData(const RsVOIPDataChunk& chunk,QImage& image) bool FFmpegVideo::decodeData(const RsVOIPDataChunk& chunk,QImage& image)
{ {
AVPacket pkt ; std::cerr << "Decoding data of size " << chunk.size << std::endl;
AVPacket pkt ;
av_init_packet(&pkt); av_init_packet(&pkt);
pkt.data = (unsigned char *)memalign(32,chunk.size + FF_INPUT_BUFFER_PADDING_SIZE) ; pkt.data = (unsigned char *)memalign(16,chunk.size - HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE) ;
memset(pkt.data,0,chunk.size + FF_INPUT_BUFFER_PADDING_SIZE) ; memset(pkt.data,0,chunk.size - HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE) ;
memcpy(pkt.data,&static_cast<unsigned char*>(chunk.data)[HEADER_SIZE],chunk.size - HEADER_SIZE) ; memcpy(pkt.data,&static_cast<unsigned char*>(chunk.data)[HEADER_SIZE],chunk.size - HEADER_SIZE) ;
pkt.size = chunk.size - HEADER_SIZE; pkt.size = chunk.size - HEADER_SIZE;
pkt.pts = AV_NOPTS_VALUE ;
pkt.dts = AV_NOPTS_VALUE ;
int got_frame = 0 ; int got_frame = 0 ;
int len = avcodec_decode_video2(decoding_context,decoding_frame_buffer,&got_frame,&pkt) ; int len = avcodec_decode_video2(decoding_context,decoding_frame_buffer,&got_frame,&pkt) ;
if(len < 0)
{
std::cerr << "Error decodign frame!" << std::endl;
return false ;
}
if(!got_frame) if(!got_frame)
return false; return false;
assert(pkt.size > 0) ;
av_free_packet(&pkt) ;
image = QImage(QSize(decoding_frame_buffer->width,decoding_frame_buffer->height),QImage::Format_ARGB32) ; image = QImage(QSize(decoding_frame_buffer->width,decoding_frame_buffer->height),QImage::Format_ARGB32) ;
std::cerr << "Decoding frame. Size=" << image.width() << "x" << image.height() << std::endl; std::cerr << "Decoded frame. Size=" << image.width() << "x" << image.height() << std::endl;
for (int y = 0; y < decoding_frame_buffer->height; y++) for (int y = 0; y < decoding_frame_buffer->height; y++)
for (int x = 0; x < decoding_frame_buffer->width; x++) for (int x = 0; x < decoding_frame_buffer->width; x++)