• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_IMAGE_ANIMATED_IMAGE_PLAYER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_IMAGE_ANIMATED_IMAGE_PLAYER_H
18 
19 #include <unordered_map>
20 
21 #include "flutter/fml/memory/ref_counted.h"
22 #include "include/codec/SkCodec.h"
23 
24 #include "base/memory/ace_type.h"
25 #include "core/animation/animator.h"
26 #include "core/animation/picture_animation.h"
27 #include "core/image/image_provider.h"
28 #include "core/image/image_source_info.h"
29 #include "core/pipeline/pipeline_base.h"
30 
31 namespace OHOS::Ace {
32 
33 class AnimatedImagePlayer : public virtual AceType {
34     DECLARE_ACE_TYPE(AnimatedImagePlayer, AceType);
35 
36 public:
37     AnimatedImagePlayer(ImageSourceInfo source, UploadSuccessCallback successCallback,
38         const WeakPtr<PipelineBase>& weakContext, std::unique_ptr<SkCodec> codec, int32_t dstWidth = -1,
39         int32_t dstHeight = -1)
imageSource_(source)40         : imageSource_(source), successCallback_(successCallback), context_(weakContext), codec_(std::move(codec)),
41           frameCount_(codec_->getFrameCount()), repetitionCount_(codec_->getRepetitionCount()),
42           frameInfos_(codec_->getFrameInfo()), dstWidth_(dstWidth), dstHeight_(dstHeight)
43     {
44         LOGD("animated image frameCount_ : %{public}d, repetitionCount_ : %{public}d", frameCount_, repetitionCount_);
45         auto context = context_.Upgrade();
46         if (context) {
47             animator_ = CREATE_ANIMATOR(context);
48             auto pictureAnimation = AceType::MakeRefPtr<PictureAnimation<int32_t>>();
49             float totalFrameDuration = 0.0f;
50             int32_t lastRequiredIndex = -1;
51             for (int32_t index = 0; index < frameCount_; index++) {
52                 LOGD("frame[%{public}d] duration is %{public}d", index, frameInfos_[index].fDuration);
53                 // if frame duration is 0, set this frame duration as 100ms
54                 if (frameInfos_[index].fDuration <= 0) {
55                     frameInfos_[index].fDuration = 100;
56                 }
57                 totalFrameDuration += frameInfos_[index].fDuration;
58 
59                 // process required frame index.
60                 int32_t requiredIndex = frameInfos_[index].fRequiredFrame;
61                 // if requiredIndex is valid
62                 if (requiredIndex >= 0 && requiredIndex < frameCount_) {
63                     LOGD("now index: %{private}d require prior frame: %{private}d", index, requiredIndex);
64                     // if require prior frame before last frame, cache it after first loop.
65                     if (requiredIndex < lastRequiredIndex) {
66                         LOGD("requiredIndex < lastRequiredIndex, lastRequiredIndex: %{private}d ", lastRequiredIndex);
67                         cachedFrame_.emplace(requiredIndex, nullptr);
68                     }
69                     lastRequiredIndex = requiredIndex;
70                 }
71             }
72             LOGD("frame cached size: %{private}d", static_cast<int32_t>(cachedFrame_.size()));
73             LOGD("animated image total duration: %{public}f", totalFrameDuration);
74             for (int32_t index = 0; index < frameCount_; index++) {
75                 pictureAnimation->AddPicture(
76                     static_cast<float>(frameInfos_[index].fDuration) / totalFrameDuration, index);
77             }
78             pictureAnimation->AddListener([weak = WeakClaim(this)](const int32_t& index) {
79                 auto player = weak.Upgrade();
80                 if (player) {
81                     player->RenderFrame(index);
82                 }
83             });
84             animator_->AddInterpolator(pictureAnimation);
85             animator_->SetDuration(totalFrameDuration);
86             auto repetitionCount = context->IsJsCard() ? 1 : repetitionCount_;
87             animator_->SetIteration(repetitionCount > 0 ? repetitionCount : ANIMATION_REPEAT_INFINITE);
88             animator_->Play();
89         }
90     }
91 
92     ~AnimatedImagePlayer() override = default;
93 
94     void Pause();
95     void Resume();
96     void RenderFrame(const int32_t& index);
97 
SetTargetSize(int32_t width,int32_t height)98     void SetTargetSize(int32_t width, int32_t height)
99     {
100         dstWidth_ = width;
101         dstHeight_ = height;
102     }
103 
104 private:
105 #ifndef USE_ROSEN_DRAWING
106     sk_sp<SkImage> DecodeFrameImage(const int32_t& index);
107 #else
108     std::shared_ptr<RSImage> DecodeFrameImage(const int32_t& index);
109 #endif
110     static bool CopyTo(SkBitmap* dst, SkColorType dstColorType, const SkBitmap& src);
111 
112     ImageSourceInfo imageSource_;
113     UploadSuccessCallback successCallback_;
114     WeakPtr<PipelineBase> context_;
115 
116     const std::unique_ptr<SkCodec> codec_;
117     const int32_t frameCount_;
118     const int32_t repetitionCount_;
119     std::vector<SkCodec::FrameInfo> frameInfos_;
120 
121     RefPtr<Animator> animator_;
122     int32_t dstWidth_ = -1;
123     int32_t dstHeight_ = -1;
124 
125     // used to cache required frame.
126     std::unordered_map<int32_t, std::unique_ptr<SkBitmap>> cachedFrame_;
127 
128     // used to cache last required frame. this will be reset during looping.
129     std::unique_ptr<SkBitmap> lastRequiredBitmap_;
130 #ifndef USE_ROSEN_DRAWING
131     int32_t lastRequiredFrameIndex_ = -1;
132 #endif
133 };
134 
135 } // namespace OHOS::Ace
136 
137 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_IMAGE_ANIMATED_IMAGE_PLAYER_H
138