int VP8EncAnalyze(VP8Encoder* const enc) { int ok = 1; const int do_segments = enc->config_->emulate_jpeg_size || // We need the complexity evaluation. (enc->segment_hdr_.num_segments_ > 1) || (enc->method_ == 0); // for method 0, we need preds_[] to be filled. enc->alpha_ = 0; enc->uv_alpha_ = 0; if (do_segments) { int alphas[MAX_ALPHA + 1] = { 0 }; VP8EncIterator it; VP8IteratorInit(enc, &it); do { VP8IteratorImport(&it); MBAnalyze(&it, alphas, &enc->alpha_, &enc->uv_alpha_); ok = VP8IteratorProgress(&it, 20); // Let's pretend we have perfect lossless reconstruction. } while (ok && VP8IteratorNext(&it, it.yuv_in_)); enc->alpha_ /= enc->mb_w_ * enc->mb_h_; enc->uv_alpha_ /= enc->mb_w_ * enc->mb_h_; if (ok) AssignSegments(enc, alphas); } else { // Use only one default segment. ResetAllMBInfo(enc); } return ok; }
int VP8EncAnalyze(VP8Encoder* const enc) { int ok = 1; const int do_segments = enc->config_->emulate_jpeg_size || (enc->segment_hdr_.num_segments_ > 1) || (enc->method_ == 0); enc->alpha_ = 0; enc->uv_alpha_ = 0; if (do_segments) { int alphas[MAX_ALPHA + 1] = { 0 }; VP8EncIterator it; VP8IteratorInit(enc, &it); do { VP8IteratorImport(&it); MBAnalyze(&it, alphas, &enc->alpha_, &enc->uv_alpha_); ok = VP8IteratorProgress(&it, 20); } while (ok && VP8IteratorNext(&it, it.yuv_in_)); enc->alpha_ /= enc->mb_w_ * enc->mb_h_; enc->uv_alpha_ /= enc->mb_w_ * enc->mb_h_; if (ok) AssignSegments(enc, alphas); } else { ResetAllMBInfo(enc); } return ok; }
int VP8EncAnalyze(VP8Encoder* const enc) { int ok = 1; const int do_segments = (enc->segment_hdr_.num_segments_ > 1) || (enc->method_ <= 2); // for methods 0,1,2, we need preds_[] to be filled. if (do_segments) { int alphas[MAX_ALPHA + 1] = { 0 }; VP8EncIterator it; VP8IteratorInit(enc, &it); enc->uv_alpha_ = 0; do { VP8IteratorImport(&it); MBAnalyze(&it, alphas, &enc->uv_alpha_); ok = VP8IteratorProgress(&it, 20); // Let's pretend we have perfect lossless reconstruction. } while (ok && VP8IteratorNext(&it, it.yuv_in_)); enc->uv_alpha_ /= enc->mb_w_ * enc->mb_h_; if (ok) AssignSegments(enc, alphas); } else { // Use only one default segment. int n; for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { DefaultMBInfo(&enc->mb_info_[n]); } // Default susceptibilities. enc->dqm_[0].alpha_ = 0; enc->dqm_[0].beta_ = 0; enc->uv_alpha_ = 0; // we can't compute this one. WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_); } return ok; }
// main entry point int VP8EncAnalyze(VP8Encoder* const enc) { int ok = 1; const int do_segments = enc->config_->emulate_jpeg_size || // We need the complexity evaluation. (enc->segment_hdr_.num_segments_ > 1) || (enc->method_ == 0); // for method 0, we need preds_[] to be filled. if (do_segments) { const int last_row = enc->mb_h_; // We give a little more than a half work to the main thread. const int split_row = (9 * last_row + 15) >> 4; const int total_mb = last_row * enc->mb_w_; #ifdef WEBP_USE_THREAD const int kMinSplitRow = 2; // minimal rows needed for mt to be worth it const int do_mt = (enc->thread_level_ > 0) && (split_row >= kMinSplitRow); #else const int do_mt = 0; #endif const WebPWorkerInterface* const worker_interface = WebPGetWorkerInterface(); SegmentJob main_job; if (do_mt) { SegmentJob side_job; // Note the use of '&' instead of '&&' because we must call the functions // no matter what. InitSegmentJob(enc, &main_job, 0, split_row); InitSegmentJob(enc, &side_job, split_row, last_row); // we don't need to call Reset() on main_job.worker, since we're calling // WebPWorkerExecute() on it ok &= worker_interface->Reset(&side_job.worker); // launch the two jobs in parallel if (ok) { worker_interface->Launch(&side_job.worker); worker_interface->Execute(&main_job.worker); ok &= worker_interface->Sync(&side_job.worker); ok &= worker_interface->Sync(&main_job.worker); } worker_interface->End(&side_job.worker); if (ok) MergeJobs(&side_job, &main_job); // merge results together } else { // Even for single-thread case, we use the generic Worker tools. InitSegmentJob(enc, &main_job, 0, last_row); worker_interface->Execute(&main_job.worker); ok &= worker_interface->Sync(&main_job.worker); } worker_interface->End(&main_job.worker); if (ok) { enc->alpha_ = main_job.alpha / total_mb; enc->uv_alpha_ = main_job.uv_alpha / total_mb; AssignSegments(enc, main_job.alphas); } } else { // Use only one default segment.
int VP8EncAnalyze(VP8Encoder* const enc) { int ok = 1; int alphas[256] = { 0 }; VP8EncIterator it; VP8IteratorInit(enc, &it); enc->uv_alpha_ = 0; do { VP8IteratorImport(&it); MBAnalyze(&it, alphas, &enc->uv_alpha_); ok = VP8IteratorProgress(&it, 20); // Let's pretend we have perfect lossless reconstruction. } while (ok && VP8IteratorNext(&it, it.yuv_in_)); enc->uv_alpha_ /= enc->mb_w_ * enc->mb_h_; if (ok) AssignSegments(enc, alphas); return ok; }