Lines Matching refs:enc
110 static void ResetCounters(WebPAnimEncoder* const enc) { in ResetCounters() argument
111 enc->start_ = 0; in ResetCounters()
112 enc->count_ = 0; in ResetCounters()
113 enc->flush_count_ = 0; in ResetCounters()
114 enc->best_delta_ = DELTA_INFINITY; in ResetCounters()
115 enc->keyframe_ = KEYFRAME_NONE; in ResetCounters()
218 static void MarkNoError(WebPAnimEncoder* const enc) { in MarkNoError() argument
219 enc->error_str_[0] = '\0'; // Empty string. in MarkNoError()
222 static void MarkError(WebPAnimEncoder* const enc, const char* str) { in MarkError() argument
223 if (snprintf(enc->error_str_, ERROR_STR_MAX_LENGTH, "%s.", str) < 0) { in MarkError()
228 static void MarkError2(WebPAnimEncoder* const enc, in MarkError2() argument
230 if (snprintf(enc->error_str_, ERROR_STR_MAX_LENGTH, "%s: %d.", str, in MarkError2()
239 WebPAnimEncoder* enc; in WebPAnimEncoderNewInternal() local
249 enc = (WebPAnimEncoder*)WebPSafeCalloc(1, sizeof(*enc)); in WebPAnimEncoderNewInternal()
250 if (enc == NULL) return NULL; in WebPAnimEncoderNewInternal()
252 enc->encoded_frames_ = NULL; in WebPAnimEncoderNewInternal()
253 enc->mux_ = NULL; in WebPAnimEncoderNewInternal()
254 MarkNoError(enc); in WebPAnimEncoderNewInternal()
257 *(int*)&enc->canvas_width_ = width; in WebPAnimEncoderNewInternal()
258 *(int*)&enc->canvas_height_ = height; in WebPAnimEncoderNewInternal()
260 *(WebPAnimEncoderOptions*)&enc->options_ = *enc_options; in WebPAnimEncoderNewInternal()
261 SanitizeEncoderOptions((WebPAnimEncoderOptions*)&enc->options_); in WebPAnimEncoderNewInternal()
263 DefaultEncoderOptions((WebPAnimEncoderOptions*)&enc->options_); in WebPAnimEncoderNewInternal()
267 if (!WebPPictureInit(&enc->curr_canvas_copy_) || in WebPAnimEncoderNewInternal()
268 !WebPPictureInit(&enc->prev_canvas_) || in WebPAnimEncoderNewInternal()
269 !WebPPictureInit(&enc->prev_canvas_disposed_)) { in WebPAnimEncoderNewInternal()
272 enc->curr_canvas_copy_.width = width; in WebPAnimEncoderNewInternal()
273 enc->curr_canvas_copy_.height = height; in WebPAnimEncoderNewInternal()
274 enc->curr_canvas_copy_.use_argb = 1; in WebPAnimEncoderNewInternal()
275 if (!WebPPictureAlloc(&enc->curr_canvas_copy_) || in WebPAnimEncoderNewInternal()
276 !WebPPictureCopy(&enc->curr_canvas_copy_, &enc->prev_canvas_) || in WebPAnimEncoderNewInternal()
277 !WebPPictureCopy(&enc->curr_canvas_copy_, &enc->prev_canvas_disposed_)) { in WebPAnimEncoderNewInternal()
280 WebPUtilClearPic(&enc->prev_canvas_, NULL); in WebPAnimEncoderNewInternal()
281 enc->curr_canvas_copy_modified_ = 1; in WebPAnimEncoderNewInternal()
284 ResetCounters(enc); in WebPAnimEncoderNewInternal()
286 enc->size_ = enc->options_.kmax - enc->options_.kmin + 1; in WebPAnimEncoderNewInternal()
289 if (enc->size_ < 2) enc->size_ = 2; in WebPAnimEncoderNewInternal()
290 enc->encoded_frames_ = in WebPAnimEncoderNewInternal()
291 (EncodedFrame*)WebPSafeCalloc(enc->size_, sizeof(*enc->encoded_frames_)); in WebPAnimEncoderNewInternal()
292 if (enc->encoded_frames_ == NULL) goto Err; in WebPAnimEncoderNewInternal()
294 enc->mux_ = WebPMuxNew(); in WebPAnimEncoderNewInternal()
295 if (enc->mux_ == NULL) goto Err; in WebPAnimEncoderNewInternal()
297 enc->count_since_key_frame_ = 0; in WebPAnimEncoderNewInternal()
298 enc->first_timestamp_ = 0; in WebPAnimEncoderNewInternal()
299 enc->prev_timestamp_ = 0; in WebPAnimEncoderNewInternal()
300 enc->prev_candidate_undecided_ = 0; in WebPAnimEncoderNewInternal()
301 enc->is_first_frame_ = 1; in WebPAnimEncoderNewInternal()
302 enc->got_null_frame_ = 0; in WebPAnimEncoderNewInternal()
304 return enc; // All OK. in WebPAnimEncoderNewInternal()
307 WebPAnimEncoderDelete(enc); in WebPAnimEncoderNewInternal()
320 void WebPAnimEncoderDelete(WebPAnimEncoder* enc) { in WebPAnimEncoderDelete() argument
321 if (enc != NULL) { in WebPAnimEncoderDelete()
322 WebPPictureFree(&enc->curr_canvas_copy_); in WebPAnimEncoderDelete()
323 WebPPictureFree(&enc->prev_canvas_); in WebPAnimEncoderDelete()
324 WebPPictureFree(&enc->prev_canvas_disposed_); in WebPAnimEncoderDelete()
325 if (enc->encoded_frames_ != NULL) { in WebPAnimEncoderDelete()
327 for (i = 0; i < enc->size_; ++i) { in WebPAnimEncoderDelete()
328 FrameRelease(&enc->encoded_frames_[i]); in WebPAnimEncoderDelete()
330 WebPSafeFree(enc->encoded_frames_); in WebPAnimEncoderDelete()
332 WebPMuxDelete(enc->mux_); in WebPAnimEncoderDelete()
333 WebPSafeFree(enc); in WebPAnimEncoderDelete()
341 static EncodedFrame* GetFrame(const WebPAnimEncoder* const enc, in GetFrame() argument
343 assert(enc->start_ + position < enc->size_); in GetFrame()
344 return &enc->encoded_frames_[enc->start_ + position]; in GetFrame()
829 static void CopyCurrentCanvas(WebPAnimEncoder* const enc) { in CopyCurrentCanvas() argument
830 if (enc->curr_canvas_copy_modified_) { in CopyCurrentCanvas()
831 WebPCopyPixels(enc->curr_canvas_, &enc->curr_canvas_copy_); in CopyCurrentCanvas()
832 enc->curr_canvas_copy_.progress_hook = enc->curr_canvas_->progress_hook; in CopyCurrentCanvas()
833 enc->curr_canvas_copy_.user_data = enc->curr_canvas_->user_data; in CopyCurrentCanvas()
834 enc->curr_canvas_copy_modified_ = 0; in CopyCurrentCanvas()
852 WebPAnimEncoder* const enc, Candidate candidates[CANDIDATE_COUNT], in GenerateCandidates() argument
863 WebPPicture* const curr_canvas = &enc->curr_canvas_copy_; in GenerateCandidates()
865 is_dispose_none ? &enc->prev_canvas_ : &enc->prev_canvas_disposed_; in GenerateCandidates()
869 CopyCurrentCanvas(enc); in GenerateCandidates()
879 if (!enc->options_.allow_mixed) { in GenerateCandidates()
882 } else if (enc->options_.minimize_size) { in GenerateCandidates()
893 CopyCurrentCanvas(enc); in GenerateCandidates()
895 enc->curr_canvas_copy_modified_ = in GenerateCandidates()
903 CopyCurrentCanvas(enc); in GenerateCandidates()
905 enc->curr_canvas_copy_modified_ = in GenerateCandidates()
913 enc->curr_canvas_copy_modified_ = 1; in GenerateCandidates()
928 static void SetPreviousDisposeMethod(WebPAnimEncoder* const enc, in SetPreviousDisposeMethod() argument
930 const size_t position = enc->count_ - 2; in SetPreviousDisposeMethod()
931 EncodedFrame* const prev_enc_frame = GetFrame(enc, position); in SetPreviousDisposeMethod()
932 assert(enc->count_ >= 2); // As current and previous frames are in enc. in SetPreviousDisposeMethod()
934 if (enc->prev_candidate_undecided_) { in SetPreviousDisposeMethod()
946 static int IncreasePreviousDuration(WebPAnimEncoder* const enc, int duration) { in IncreasePreviousDuration() argument
947 const size_t position = enc->count_ - 1; in IncreasePreviousDuration()
948 EncodedFrame* const prev_enc_frame = GetFrame(enc, position); in IncreasePreviousDuration()
951 assert(enc->count_ >= 1); in IncreasePreviousDuration()
981 (enc->last_config_.lossless || enc->options_.allow_mixed); in IncreasePreviousDuration()
982 EncodedFrame* const curr_enc_frame = GetFrame(enc, enc->count_); in IncreasePreviousDuration()
994 ++enc->count_; in IncreasePreviousDuration()
995 ++enc->count_since_key_frame_; in IncreasePreviousDuration()
996 enc->flush_count_ = enc->count_ - 1; in IncreasePreviousDuration()
997 enc->prev_candidate_undecided_ = 0; in IncreasePreviousDuration()
998 enc->prev_rect_ = rect; in IncreasePreviousDuration()
1011 static void PickBestCandidate(WebPAnimEncoder* const enc, in PickBestCandidate() argument
1043 SetPreviousDisposeMethod(enc, prev_dispose_method); in PickBestCandidate()
1045 enc->prev_rect_ = candidates[i].rect_; // save for next frame. in PickBestCandidate()
1058 static WebPEncodingError SetFrame(WebPAnimEncoder* const enc, in SetFrame() argument
1065 const WebPPicture* const curr_canvas = &enc->curr_canvas_copy_; in SetFrame()
1066 const WebPPicture* const prev_canvas = &enc->prev_canvas_; in SetFrame()
1069 const int consider_lossless = is_lossless || enc->options_.allow_mixed; in SetFrame()
1070 const int consider_lossy = !is_lossless || enc->options_.allow_mixed; in SetFrame()
1071 const int is_first_frame = enc->is_first_frame_; in SetFrame()
1090 !is_key_frame && !enc->prev_candidate_undecided_; in SetFrame()
1099 enc->last_config_ = *config; in SetFrame()
1100 enc->last_config_reversed_ = config->lossless ? config_lossy : config_ll; in SetFrame()
1128 WebPPicture* const prev_canvas_disposed = &enc->prev_canvas_disposed_; in SetFrame()
1130 DisposeFrameRectangle(WEBP_MUX_DISPOSE_BACKGROUND, &enc->prev_rect_, in SetFrame()
1142 if (enc->options_.minimize_size) { // Try both dispose methods. in SetFrame()
1158 enc, candidates, WEBP_MUX_DISPOSE_NONE, is_lossless, is_key_frame, in SetFrame()
1164 assert(!enc->is_first_frame_); in SetFrame()
1167 enc, candidates, WEBP_MUX_DISPOSE_BACKGROUND, is_lossless, is_key_frame, in SetFrame()
1172 PickBestCandidate(enc, candidates, is_key_frame, encoded_frame); in SetFrame()
1196 static int CacheFrame(WebPAnimEncoder* const enc, in CacheFrame() argument
1201 const size_t position = enc->count_; in CacheFrame()
1202 EncodedFrame* const encoded_frame = GetFrame(enc, position); in CacheFrame()
1204 ++enc->count_; in CacheFrame()
1206 if (enc->is_first_frame_) { // Add this as a key-frame. in CacheFrame()
1207 error_code = SetFrame(enc, config, 1, encoded_frame, &frame_skipped); in CacheFrame()
1210 assert(position == 0 && enc->count_ == 1); in CacheFrame()
1212 enc->flush_count_ = 0; in CacheFrame()
1213 enc->count_since_key_frame_ = 0; in CacheFrame()
1214 enc->prev_candidate_undecided_ = 0; in CacheFrame()
1216 ++enc->count_since_key_frame_; in CacheFrame()
1217 if (enc->count_since_key_frame_ <= enc->options_.kmin) { in CacheFrame()
1219 error_code = SetFrame(enc, config, 0, encoded_frame, &frame_skipped); in CacheFrame()
1223 enc->flush_count_ = enc->count_ - 1; in CacheFrame()
1224 enc->prev_candidate_undecided_ = 0; in CacheFrame()
1230 error_code = SetFrame(enc, config, 0, encoded_frame, &frame_skipped); in CacheFrame()
1233 prev_rect_sub = enc->prev_rect_; in CacheFrame()
1237 error_code = SetFrame(enc, config, 1, encoded_frame, &frame_skipped); in CacheFrame()
1240 prev_rect_key = enc->prev_rect_; in CacheFrame()
1244 if (curr_delta <= enc->best_delta_) { // Pick this as the key-frame. in CacheFrame()
1245 if (enc->keyframe_ != KEYFRAME_NONE) { in CacheFrame()
1246 EncodedFrame* const old_keyframe = GetFrame(enc, enc->keyframe_); in CacheFrame()
1251 enc->prev_candidate_undecided_ = 1; in CacheFrame()
1252 enc->keyframe_ = (int)position; in CacheFrame()
1253 enc->best_delta_ = curr_delta; in CacheFrame()
1254 enc->flush_count_ = enc->count_ - 1; // We can flush previous frames. in CacheFrame()
1257 enc->prev_candidate_undecided_ = 0; in CacheFrame()
1261 if (enc->count_since_key_frame_ >= enc->options_.kmax) { in CacheFrame()
1262 enc->flush_count_ = enc->count_ - 1; in CacheFrame()
1263 enc->count_since_key_frame_ = 0; in CacheFrame()
1264 enc->keyframe_ = KEYFRAME_NONE; in CacheFrame()
1265 enc->best_delta_ = DELTA_INFINITY; in CacheFrame()
1267 if (!enc->prev_candidate_undecided_) { in CacheFrame()
1268 enc->prev_rect_ = in CacheFrame()
1275 WebPCopyPixels(enc->curr_canvas_, &enc->prev_canvas_); in CacheFrame()
1276 enc->is_first_frame_ = 0; in CacheFrame()
1280 ++enc->in_frame_count_; in CacheFrame()
1286 --enc->count_; in CacheFrame()
1287 if (!enc->is_first_frame_) --enc->count_since_key_frame_; in CacheFrame()
1289 MarkError2(enc, "ERROR adding frame. WebPEncodingError", error_code); in CacheFrame()
1292 enc->curr_canvas_->error_code = error_code; // report error_code in CacheFrame()
1297 static int FlushFrames(WebPAnimEncoder* const enc) { in FlushFrames() argument
1298 while (enc->flush_count_ > 0) { in FlushFrames()
1300 EncodedFrame* const curr = GetFrame(enc, 0); in FlushFrames()
1303 assert(enc->mux_ != NULL); in FlushFrames()
1304 err = WebPMuxPushFrame(enc->mux_, info, 1); in FlushFrames()
1306 MarkError2(enc, "ERROR adding frame. WebPMuxError", err); in FlushFrames()
1309 if (enc->options_.verbose) { in FlushFrames()
1314 ++enc->out_frame_count_; in FlushFrames()
1316 ++enc->start_; in FlushFrames()
1317 --enc->flush_count_; in FlushFrames()
1318 --enc->count_; in FlushFrames()
1319 if (enc->keyframe_ != KEYFRAME_NONE) --enc->keyframe_; in FlushFrames()
1322 if (enc->count_ == 1 && enc->start_ != 0) { in FlushFrames()
1324 const int enc_start_tmp = (int)enc->start_; in FlushFrames()
1325 EncodedFrame temp = enc->encoded_frames_[0]; in FlushFrames()
1326 enc->encoded_frames_[0] = enc->encoded_frames_[enc_start_tmp]; in FlushFrames()
1327 enc->encoded_frames_[enc_start_tmp] = temp; in FlushFrames()
1328 FrameRelease(&enc->encoded_frames_[enc_start_tmp]); in FlushFrames()
1329 enc->start_ = 0; in FlushFrames()
1337 int WebPAnimEncoderAdd(WebPAnimEncoder* enc, WebPPicture* frame, int timestamp, in WebPAnimEncoderAdd() argument
1342 if (enc == NULL) { in WebPAnimEncoderAdd()
1345 MarkNoError(enc); in WebPAnimEncoderAdd()
1347 if (!enc->is_first_frame_) { in WebPAnimEncoderAdd()
1350 (uint32_t)timestamp - enc->prev_timestamp_; in WebPAnimEncoderAdd()
1355 MarkError(enc, "ERROR adding frame: timestamps must be non-decreasing"); in WebPAnimEncoderAdd()
1358 if (!IncreasePreviousDuration(enc, (int)prev_frame_duration)) { in WebPAnimEncoderAdd()
1362 enc->first_timestamp_ = timestamp; in WebPAnimEncoderAdd()
1366 enc->got_null_frame_ = 1; in WebPAnimEncoderAdd()
1367 enc->prev_timestamp_ = timestamp; in WebPAnimEncoderAdd()
1371 if (frame->width != enc->canvas_width_ || in WebPAnimEncoderAdd()
1372 frame->height != enc->canvas_height_) { in WebPAnimEncoderAdd()
1374 MarkError(enc, "ERROR adding frame: Invalid frame dimensions"); in WebPAnimEncoderAdd()
1379 if (enc->options_.verbose) { in WebPAnimEncoderAdd()
1384 MarkError(enc, "ERROR converting frame from YUV(A) to ARGB"); in WebPAnimEncoderAdd()
1391 MarkError(enc, "ERROR adding frame: Invalid WebPConfig"); in WebPAnimEncoderAdd()
1399 assert(enc->curr_canvas_ == NULL); in WebPAnimEncoderAdd()
1400 enc->curr_canvas_ = frame; // Store reference. in WebPAnimEncoderAdd()
1401 assert(enc->curr_canvas_copy_modified_ == 1); in WebPAnimEncoderAdd()
1402 CopyCurrentCanvas(enc); in WebPAnimEncoderAdd()
1404 ok = CacheFrame(enc, &config) && FlushFrames(enc); in WebPAnimEncoderAdd()
1406 enc->curr_canvas_ = NULL; in WebPAnimEncoderAdd()
1407 enc->curr_canvas_copy_modified_ = 1; in WebPAnimEncoderAdd()
1409 enc->prev_timestamp_ = timestamp; in WebPAnimEncoderAdd()
1444 static int FrameToFullCanvas(WebPAnimEncoder* const enc, in FrameToFullCanvas() argument
1447 WebPPicture* const canvas_buf = &enc->curr_canvas_copy_; in FrameToFullCanvas()
1453 if (!EncodeFrame(&enc->last_config_, canvas_buf, &mem1)) goto Err; in FrameToFullCanvas()
1456 if (enc->options_.allow_mixed) { in FrameToFullCanvas()
1457 if (!EncodeFrame(&enc->last_config_reversed_, canvas_buf, &mem2)) goto Err; in FrameToFullCanvas()
1476 static WebPMuxError OptimizeSingleFrame(WebPAnimEncoder* const enc, in OptimizeSingleFrame() argument
1485 assert(enc->out_frame_count_ == 1); in OptimizeSingleFrame()
1495 if (!FrameToFullCanvas(enc, &frame, &full_image)) { in OptimizeSingleFrame()
1518 int WebPAnimEncoderAssemble(WebPAnimEncoder* enc, WebPData* webp_data) { in WebPAnimEncoderAssemble() argument
1522 if (enc == NULL) { in WebPAnimEncoderAssemble()
1525 MarkNoError(enc); in WebPAnimEncoderAssemble()
1528 MarkError(enc, "ERROR assembling: NULL input"); in WebPAnimEncoderAssemble()
1532 if (enc->in_frame_count_ == 0) { in WebPAnimEncoderAssemble()
1533 MarkError(enc, "ERROR: No frames to assemble"); in WebPAnimEncoderAssemble()
1537 if (!enc->got_null_frame_ && enc->in_frame_count_ > 1 && enc->count_ > 0) { in WebPAnimEncoderAssemble()
1540 (uint32_t)enc->prev_timestamp_ - enc->first_timestamp_; in WebPAnimEncoderAssemble()
1541 const int average_duration = (int)(delta_time / (enc->in_frame_count_ - 1)); in WebPAnimEncoderAssemble()
1542 if (!IncreasePreviousDuration(enc, average_duration)) { in WebPAnimEncoderAssemble()
1548 enc->flush_count_ = enc->count_; in WebPAnimEncoderAssemble()
1549 if (!FlushFrames(enc)) { in WebPAnimEncoderAssemble()
1554 mux = enc->mux_; in WebPAnimEncoderAssemble()
1555 err = WebPMuxSetCanvasSize(mux, enc->canvas_width_, enc->canvas_height_); in WebPAnimEncoderAssemble()
1558 err = WebPMuxSetAnimationParams(mux, &enc->options_.anim_params); in WebPAnimEncoderAssemble()
1565 if (enc->out_frame_count_ == 1) { in WebPAnimEncoderAssemble()
1566 err = OptimizeSingleFrame(enc, webp_data); in WebPAnimEncoderAssemble()
1572 MarkError2(enc, "ERROR assembling WebP", err); in WebPAnimEncoderAssemble()
1576 const char* WebPAnimEncoderGetError(WebPAnimEncoder* enc) { in WebPAnimEncoderGetError() argument
1577 if (enc == NULL) return NULL; in WebPAnimEncoderGetError()
1578 return enc->error_str_; in WebPAnimEncoderGetError()