c++ - Decoding by libjpeg -> Encoding by x264, strange artefacts on frames -


i have collection of jpeg, must decoded lib jpeg, , after it, encoded x264 (after encoded packets streamed via rtmp). code used decoding:

struct my_error_mgr  {        struct jpeg_error_mgr pub;     jmp_buf setjmp_buffer; }; typedef my_error_mgr *my_error_ptr;  methoddef(void) my_error_exit (j_common_ptr cinfo) {     my_error_ptr myerr = (my_error_ptr) cinfo->err;     (*cinfo->err->output_message) (cinfo);     longjmp(myerr->setjmp_buffer, 1);    }  void init_source(j_decompress_ptr ptr) {     q_unused(ptr) }  boolean fill_input_buffer(j_decompress_ptr ptr)  {      q_unused(ptr)     return true; }  void term_source(j_decompress_ptr ptr) {     q_unused(ptr) }  void skip_input_data(j_decompress_ptr ptr, long num_bytes) {     if(num_bytes>0)      {         ptr->src->next_input_byte+=(size_t)num_bytes;         ptr->src->bytes_in_buffer-=(size_t)num_bytes;        } }  etherdecoder::etherdecoder(qobject *parent): qobject(parent) { }  void etherdecoder::datablockready(qbytearray data) {     jpeg_decompress_struct decompressinfo;     jpeg_create_decompress(&decompressinfo);     my_error_mgr err;     decompressinfo.do_fancy_upsampling = false;     decompressinfo.src = (jpeg_source_mgr *) (*decompressinfo.mem->alloc_small)       ((j_common_ptr) &decompressinfo, jpool_permanent, sizeof(jpeg_source_mgr));     decompressinfo.err = jpeg_std_error(&err.pub);     err.pub.error_exit = my_error_exit;     if (setjmp(err.setjmp_buffer))       {         jpeg_destroy_decompress(&decompressinfo);         return;      }     decompressinfo.src->init_source = init_source;     decompressinfo.src->resync_to_restart = jpeg_resync_to_restart;     decompressinfo.src->fill_input_buffer = fill_input_buffer;     decompressinfo.src->skip_input_data = skip_input_data;     decompressinfo.src->term_source = term_source;     decompressinfo.src->next_input_byte = reinterpret_cast<const joctet*>(data.data());     decompressinfo.src->bytes_in_buffer = data.size();     jpeg_read_header(&decompressinfo, true);     jpeg_start_decompress(&decompressinfo);     int size = 0;     int n_samples = 0;     char *samples = new char[5242880];     char *reserv = samples;     while (decompressinfo.output_scanline < decompressinfo.output_height)        {         n_samples = jpeg_read_scanlines(&decompressinfo, (jsamparray) &samples, 1);         samples += n_samples * decompressinfo.image_width * decompressinfo.num_components;         size += n_samples * decompressinfo.image_width * decompressinfo.num_components;      }     jpeg_finish_decompress(&decompressinfo);     qbytearray output(reserv, size);     emit frameready(output, decompressinfo.output_width, decompressinfo.output_height);     jpeg_destroy_decompress(&decompressinfo);     delete[] reserv; } 

when emit frameready signal, send data encoder, method, init encedor looks like:

bool etherencoder::initencoder(unsigned int width, unsigned int height) {     x264_param_t param;     x264_param_default_preset(&param, "veryfast", "zerolatency");     param.i_width=width;     param.i_height=height;     param.i_frame_total=0;     param.i_csp=x264_csp_i420;     param.i_timebase_num=1;     param.i_timebase_den=96000;     param.b_annexb=true;     param.b_repeat_headers=false;     x264_param_apply_fastfirstpass(&param);     x264_param_apply_profile(&param, "baseline");     _context=x264_encoder_open(&param);     if(!_context)         return false;     int nal_count;     x264_nal_t *nals;     if(x264_encoder_headers(_context, &nals, &nal_count)<0)      {         x264_encoder_close(_context);         _context=0;         return false;        }     _extradata=qbytearray();     _width=width;     _height=height;     if(nal_count>0)      {         _extradata=qbytearray(             (const char *)nals[0].p_payload,             nals[nal_count-1].p_payload+nals[nal_count-1].i_payload-nals[0].p_payload);      }     return true; } 

and encoding method:

void etherencoder::onframeready(qbytearray data, int width, int height) {     while(data.size()>0)         {         if(!_context && initencoder(width, height))         {             _timestampdelta=realtimestamp();         }         if(_context)         {             x264_picture_t pic;             x264_picture_init(&pic);             pic.i_type=x264_type_auto;             pic.i_pts=_timestampdelta*96000;             pic.img.i_csp=x264_csp_i420;             pic.img.i_plane=3;             int planesize = width*height;             uint8_t *p = (uint8_t*)data.data();             pic.img.plane[0]=p;             p+=planesize;             pic.img.plane[1]=p;             p+=planesize/4;             pic.img.plane[2]=p;             pic.img.i_stride[0]=width;             pic.img.i_stride[1]=width/2;             pic.img.i_stride[2]=width/2;             if(_forcekeyframe)             {                 pic.i_type=x264_type_i;                 _forcekeyframe=false;             }             int nal_count;             x264_nal_t *nals;             int rc=x264_encoder_encode(_context, &nals, &nal_count, &pic, &pic);             if(rc>0)             {                 _mutex.lock();                 _packets.push_back(                     packet(                         qbytearray(                             (const char *)nals[0].p_payload,         nals[nal_count-    1].p_payload+nals[nal_count-1].i_payload-nals[0].p_payload),                         _timestampdelta/96.0,                         _timestampdelta/96.0,                         pic.b_keyframe));                 _timestampdelta+=40;                 data.clear();                 _mutex.unlock();                 emit onpacketready();             }         }        } } 

decoding , encoding proceeds without errors, @ end valid video stream, but, seems in 1 of steps set invalid data decoder/encoder. 1/4 part of image (top-left, understood) , has invalid color , come color stripes. maybe set invalid strides , planes when encode frame, or maybe setting data libjpeg decoder incorrect.. please ask questions code, i'll try make explanations you. explodes brain.. thank you.


Comments

Popular posts from this blog

Change php variable from jquery value using ajax (same page) -

Pull out data related to my apps from Android Play Store and iOS App Store -

How can I fetch data from a web server in an android application? -