fixed bug in creating input image when encoding video

This commit is contained in:
csoler 2015-08-23 21:08:27 -04:00
parent 0bb5a74099
commit 024999ed67

View File

@ -58,14 +58,11 @@ bool VideoProcessor::processImage(const QImage& img,uint32_t size_hint,uint32_t&
{ {
RsVOIPDataChunk chunk ; RsVOIPDataChunk chunk ;
codec->encodeData(img.scaled(_encoded_frame_size,Qt::IgnoreAspectRatio,Qt::SmoothTransformation),size_hint,chunk) ; if(codec->encodeData(img.scaled(_encoded_frame_size,Qt::IgnoreAspectRatio,Qt::SmoothTransformation),size_hint,chunk) && chunk.size > 0)
{
encoded_size = chunk.size ; encoded_size = chunk.size ;
if(chunk.size == 0) // the codec might be buffering the frame for compression reasons
return true ;
_encoded_out_queue.push_back(chunk) ; _encoded_out_queue.push_back(chunk) ;
}
return true ; return true ;
} }
@ -538,6 +535,9 @@ FFmpegVideo::FFmpegVideo()
encoding_frame_buffer = avcodec_alloc_frame() ;//(AVFrame*)malloc(sizeof(AVFrame)) ; encoding_frame_buffer = avcodec_alloc_frame() ;//(AVFrame*)malloc(sizeof(AVFrame)) ;
if(!encoding_frame_buffer)
throw std::runtime_error("AV: could not allocate frame buffer.") ;
encoding_frame_buffer->format = encoding_context->pix_fmt; encoding_frame_buffer->format = encoding_context->pix_fmt;
encoding_frame_buffer->width = encoding_context->width; encoding_frame_buffer->width = encoding_context->width;
encoding_frame_buffer->height = encoding_context->height; encoding_frame_buffer->height = encoding_context->height;
@ -545,7 +545,8 @@ FFmpegVideo::FFmpegVideo()
/* the image can be allocated by any means and av_image_alloc() is /* the image can be allocated by any means and av_image_alloc() is
* just the most convenient way if av_malloc() is to be used */ * just the most convenient way if av_malloc() is to be used */
int ret = av_image_alloc(encoding_frame_buffer->data, encoding_frame_buffer->linesize, encoding_context->width, encoding_context->height, encoding_context->pix_fmt, 32); int ret = av_image_alloc(encoding_frame_buffer->data, encoding_frame_buffer->linesize,
encoding_context->width, encoding_context->height, encoding_context->pix_fmt, 32);
if (ret < 0) if (ret < 0)
throw std::runtime_error("AV: Could not allocate raw picture buffer"); throw std::runtime_error("AV: Could not allocate raw picture buffer");
@ -575,6 +576,7 @@ FFmpegVideo::FFmpegVideo()
throw("AV codec open action failed! ") ; throw("AV codec open action failed! ") ;
decoding_frame_buffer = avcodec_alloc_frame() ;//(AVFrame*)malloc(sizeof(AVFrame)) ; 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); //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) //if (ret < 0)
@ -612,20 +614,36 @@ bool FFmpegVideo::encodeData(const QImage& image,uint32_t size_hint,RsVOIPDataCh
/* prepare a dummy image */ /* prepare a dummy image */
/* Y */ /* Y */
for (int y = 0; y < encoding_context->height; y++) for (int y = 0; y < encoding_context->height/2; y++)
for (int x = 0; x < encoding_context->width; x++) for (int x = 0; x < encoding_context->width/2; x++)
{ {
QRgb pix = input.pixel(QPoint(x,y)) ; QRgb pix00 = input.pixel(QPoint(2*x+0,2*y+0)) ;
QRgb pix01 = input.pixel(QPoint(2*x+0,2*y+1)) ;
QRgb pix10 = input.pixel(QPoint(2*x+1,2*y+0)) ;
QRgb pix11 = input.pixel(QPoint(2*x+1,2*y+1)) ;
register int R = (pix >> 16) & 0xff ; int R00 = (pix00 >> 16) & 0xff ; int G00 = (pix00 >> 8) & 0xff ; int B00 = (pix00 >> 0) & 0xff ;
register int G = (pix >> 8) & 0xff ; int R01 = (pix01 >> 16) & 0xff ; int G01 = (pix01 >> 8) & 0xff ; int B01 = (pix01 >> 0) & 0xff ;
register int B = (pix >> 0) & 0xff ; int R10 = (pix10 >> 16) & 0xff ; int G10 = (pix10 >> 8) & 0xff ; int B10 = (pix10 >> 0) & 0xff ;
int R11 = (pix11 >> 16) & 0xff ; int G11 = (pix11 >> 8) & 0xff ; int B11 = (pix11 >> 0) & 0xff ;
int Y00 = (0.257 * R00) + (0.504 * G00) + (0.098 * B00) + 16 ;
int Y01 = (0.257 * R01) + (0.504 * G01) + (0.098 * B01) + 16 ;
int Y10 = (0.257 * R10) + (0.504 * G10) + (0.098 * B10) + 16 ;
int Y11 = (0.257 * R11) + (0.504 * G11) + (0.098 * B11) + 16 ;
float R = 0.25*(R00+R01+R10+R11) ;
float G = 0.25*(G00+G01+G10+G11) ;
float B = 0.25*(B00+B01+B10+B11) ;
int Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16 ;
int U = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 ; int U = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 ;
int V = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128 ; int V = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128 ;
encoding_frame_buffer->data[0][y * encoding_frame_buffer->linesize[0] + x] = std::min(255,std::max(0,Y)); // Y encoding_frame_buffer->data[0][(2*y+0) * encoding_frame_buffer->linesize[0] + 2*x+0] = std::min(255,std::max(0,Y00)); // Y
encoding_frame_buffer->data[0][(2*y+0) * encoding_frame_buffer->linesize[0] + 2*x+1] = std::min(255,std::max(0,Y01)); // Y
encoding_frame_buffer->data[0][(2*y+1) * encoding_frame_buffer->linesize[0] + 2*x+0] = std::min(255,std::max(0,Y10)); // Y
encoding_frame_buffer->data[0][(2*y+1) * encoding_frame_buffer->linesize[0] + 2*x+1] = std::min(255,std::max(0,Y11)); // Y
encoding_frame_buffer->data[1][y * encoding_frame_buffer->linesize[1] + x] = std::min(255,std::max(0,U));// Cr encoding_frame_buffer->data[1][y * encoding_frame_buffer->linesize[1] + x] = std::min(255,std::max(0,U));// Cr
encoding_frame_buffer->data[2][y * encoding_frame_buffer->linesize[2] + x] = std::min(255,std::max(0,V));// Cb encoding_frame_buffer->data[2][y * encoding_frame_buffer->linesize[2] + x] = std::min(255,std::max(0,V));// Cb
} }
@ -678,6 +696,8 @@ bool FFmpegVideo::encodeData(const QImage& image,uint32_t size_hint,RsVOIPDataCh
fflush(encoding_debug_file) ; fflush(encoding_debug_file) ;
#endif #endif
av_free_packet(&pkt); av_free_packet(&pkt);
return true ;
} }
else else
{ {
@ -686,9 +706,9 @@ bool FFmpegVideo::encodeData(const QImage& image,uint32_t size_hint,RsVOIPDataCh
voip_chunk.type = RsVOIPDataChunk::RS_VOIP_DATA_TYPE_VIDEO ; voip_chunk.type = RsVOIPDataChunk::RS_VOIP_DATA_TYPE_VIDEO ;
std::cerr << "No output produced." << std::endl; std::cerr << "No output produced." << std::endl;
return false ;
} }
return true ;
} }
bool FFmpegVideo::decodeData(const RsVOIPDataChunk& chunk,QImage& image) bool FFmpegVideo::decodeData(const RsVOIPDataChunk& chunk,QImage& image)
{ {
@ -713,6 +733,7 @@ bool FFmpegVideo::decodeData(const RsVOIPDataChunk& chunk,QImage& image)
std::cerr << "Error decodign frame!" << std::endl; std::cerr << "Error decodign frame!" << std::endl;
return false ; return false ;
} }
std::cerr << "Used " << len << " bytes out of " << pkt.size << ". got_frame = " << got_frame << std::endl;
if(!got_frame) if(!got_frame)
return false; return false;